workarea-gift_cards 3.4.6
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 +7 -0
- data/.editorconfig +20 -0
- data/.eslintignore +2 -0
- data/.eslintrc +24 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +15 -0
- data/.scss-lint.yml +188 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +485 -0
- data/CODE_OF_CONDUCT.md +3 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +7 -0
- data/LICENSE +52 -0
- data/README.md +119 -0
- data/Rakefile +53 -0
- data/app/assets/images/workarea/admin/payment_icons/gift_card.svg +1 -0
- data/app/assets/images/workarea/storefront/payment_icons/gift_card.svg +1 -0
- data/app/controllers/workarea/admin/data_file_exports_controller.decorator +28 -0
- data/app/controllers/workarea/admin/payment_gift_cards_controller.rb +78 -0
- data/app/controllers/workarea/api/admin/payment_gift_cards_controller.rb +49 -0
- data/app/controllers/workarea/api/storefront/checkouts_controller.decorator +10 -0
- data/app/controllers/workarea/api/storefront/gift_cards_controller.rb +26 -0
- data/app/controllers/workarea/storefront/checkouts_controller.decorator +24 -0
- data/app/controllers/workarea/storefront/gift_cards_controller.rb +24 -0
- data/app/mailers/workarea/storefront/gift_card_mailer.rb +28 -0
- data/app/models/workarea/catalog/customizations/gift_card.rb +9 -0
- data/app/models/workarea/catalog/product.decorator +11 -0
- data/app/models/workarea/order/item.decorator +7 -0
- data/app/models/workarea/payment/authorize/gift_card.rb +43 -0
- data/app/models/workarea/payment/capture/gift_card.rb +25 -0
- data/app/models/workarea/payment/gift_card/redemption.rb +23 -0
- data/app/models/workarea/payment/gift_card.rb +186 -0
- data/app/models/workarea/payment/purchase/gift_card.rb +7 -0
- data/app/models/workarea/payment/refund/gift_card.rb +35 -0
- data/app/models/workarea/payment/tender/gift_card.rb +30 -0
- data/app/models/workarea/payment.decorator +19 -0
- data/app/models/workarea/search/admin/order.decorator +9 -0
- data/app/models/workarea/search/admin/payment_gift_card.rb +46 -0
- data/app/queries/workarea/admin_redemptions_export.rb +84 -0
- data/app/queries/workarea/order_item_details.decorator +11 -0
- data/app/queries/workarea/search/admin_gift_cards.rb +20 -0
- data/app/seeds/workarea/gift_card_seeds.rb +44 -0
- data/app/services/workarea/checkout/steps/gift_card.rb +49 -0
- data/app/view_models/workarea/admin/payment_gift_card_view_model.rb +11 -0
- data/app/view_models/workarea/storefront/checkout/payment_view_model.decorator +32 -0
- data/app/view_models/workarea/storefront/checkout/summary_view_model.decorator +11 -0
- data/app/view_models/workarea/storefront/gift_card_order_pricing.rb +36 -0
- data/app/view_models/workarea/storefront/order_view_model.decorator +27 -0
- data/app/view_models/workarea/storefront/product_templates/gift_card_view_model.rb +4 -0
- data/app/views/workarea/admin/activities/_payment_gift_card_create.html.haml +12 -0
- data/app/views/workarea/admin/activities/_payment_gift_card_destroy.html.haml +10 -0
- data/app/views/workarea/admin/activities/_payment_gift_card_update.html.haml +14 -0
- data/app/views/workarea/admin/orders/tenders/_gift_card.html.haml +5 -0
- data/app/views/workarea/admin/payment_gift_cards/_aux_navigation.html.haml +4 -0
- data/app/views/workarea/admin/payment_gift_cards/_cards.html.haml +74 -0
- data/app/views/workarea/admin/payment_gift_cards/_menu.html.haml +1 -0
- data/app/views/workarea/admin/payment_gift_cards/_summary.html.haml +11 -0
- data/app/views/workarea/admin/payment_gift_cards/edit.html.haml +37 -0
- data/app/views/workarea/admin/payment_gift_cards/index.html.haml +95 -0
- data/app/views/workarea/admin/payment_gift_cards/new.html.haml +43 -0
- data/app/views/workarea/admin/payment_gift_cards/redemptions.html.haml +29 -0
- data/app/views/workarea/admin/payment_gift_cards/show.html.haml +19 -0
- data/app/views/workarea/api/storefront/checkouts/steps/_gift_card.json.jbuilder +6 -0
- data/app/views/workarea/api/storefront/gift_cards/balance.json.jbuilder +3 -0
- data/app/views/workarea/api/storefront/orders/tenders/_gift_card.json.jbuilder +3 -0
- data/app/views/workarea/storefront/checkouts/_gift_card_error.html.haml +6 -0
- data/app/views/workarea/storefront/checkouts/_gift_card_payment.html.haml +28 -0
- data/app/views/workarea/storefront/checkouts/_gift_card_summary.html.haml +6 -0
- data/app/views/workarea/storefront/gift_card_mailer/created.html.haml +15 -0
- data/app/views/workarea/storefront/gift_cards/index.html.haml +17 -0
- data/app/views/workarea/storefront/order_mailer/_gift_card_summary.html.haml +5 -0
- data/app/views/workarea/storefront/order_mailer/tenders/_gift_card.html.haml +5 -0
- data/app/views/workarea/storefront/orders/_gift_card_summary.html.haml +6 -0
- data/app/views/workarea/storefront/orders/tenders/_gift_card.html.haml +9 -0
- data/app/views/workarea/storefront/products/templates/_gift_card.html.haml +77 -0
- data/app/workers/workarea/create_ordered_gift_cards.rb +47 -0
- data/app/workers/workarea/log_gift_card_redemption.rb +32 -0
- data/app/workers/workarea/send_gift_card_notifications.rb +20 -0
- data/bin/rails +18 -0
- data/config/initializers/append_points.rb +37 -0
- data/config/initializers/configuration.rb +8 -0
- data/config/initializers/jump_to_navigation.rb +3 -0
- data/config/locales/en.yml +82 -0
- data/config/routes.rb +31 -0
- data/lib/workarea/gift_cards/engine.rb +19 -0
- data/lib/workarea/gift_cards/version.rb +5 -0
- data/lib/workarea/gift_cards.rb +11 -0
- data/lib/workarea/mailer_previews/storefront/gift_card_mailer_preview.rb +18 -0
- data/test/documentation/workarea/api/admin/gift_cards_documentation_test.rb +82 -0
- data/test/documentation/workarea/api/storefront/gift_cards_documentation_test.rb +107 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +4 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +2 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +34 -0
- data/test/dummy/bin/update +29 -0
- data/test/dummy/config/application.rb +24 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cable.yml +9 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +54 -0
- data/test/dummy/config/environments/production.rb +86 -0
- data/test/dummy/config/environments/test.rb +43 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/new_framework_defaults.rb +21 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/puma.rb +47 -0
- data/test/dummy/config/routes.rb +6 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/test/dummy/public/apple-touch-icon.png +0 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/factories/gift_cards.rb +27 -0
- data/test/integration/workarea/admin/gift_card_integration_test.rb +53 -0
- data/test/integration/workarea/admin/gift_card_redemptions_export_integration_test.rb +104 -0
- data/test/integration/workarea/api/admin/gift_card_integration_test.rb +57 -0
- data/test/integration/workarea/api/storefront/balance_integration_test.rb +40 -0
- data/test/integration/workarea/api/storefront/checkout_integration_test.rb +161 -0
- data/test/integration/workarea/storefront/gift_card_integration_test.rb +222 -0
- data/test/models/workarea/catalog/gift_card_product_test.rb +15 -0
- data/test/models/workarea/gift_card_payment_test.rb +12 -0
- data/test/models/workarea/payment/gift_card_test.rb +127 -0
- data/test/models/workarea/payment/purchase/gift_card_test.rb +52 -0
- data/test/models/workarea/payment/refund/gift_card_test.rb +19 -0
- data/test/queries/workarea/admin_redemptions_export_test.rb +52 -0
- data/test/queries/workarea/gift_card_order_item_details_test.rb +11 -0
- data/test/services/workarea/checkout/steps/gift_card_test.rb +87 -0
- data/test/system/workarea/admin/gift_cards_system_test.rb +89 -0
- data/test/system/workarea/storefront/gift_cards_system_test.rb +400 -0
- data/test/test_helper.rb +10 -0
- data/test/view_models/workarea/storefront/checkout/gift_card_payment_view_model_test.rb +65 -0
- data/test/workers/workarea/create_ordered_gift_cards_test.rb +39 -0
- data/test/workers/workarea/log_gift_card_redemption_test.rb +19 -0
- data/workarea-gift_cards.gemspec +21 -0
- metadata +227 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
class Payment::Tender::GiftCard < Payment::Tender
|
|
3
|
+
field :number, type: String
|
|
4
|
+
validates :number, presence: true
|
|
5
|
+
|
|
6
|
+
def display_number
|
|
7
|
+
"XXXX#{number.last(4)}"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def slug
|
|
11
|
+
:gift_card
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def amount=(amount)
|
|
15
|
+
if amount.blank?
|
|
16
|
+
super(amount)
|
|
17
|
+
elsif balance >= amount
|
|
18
|
+
super(amount)
|
|
19
|
+
else
|
|
20
|
+
super(balance)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def balance
|
|
27
|
+
@balance ||= Payment::GiftCard.find_balance(number)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
decorate Payment, with: 'gift_cards' do
|
|
3
|
+
decorated do
|
|
4
|
+
embeds_one :gift_card, class_name: 'Workarea::Payment::Tender::GiftCard'
|
|
5
|
+
delegate :number, to: :gift_card, allow_nil: true, prefix: true
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def set_gift_card(attrs)
|
|
9
|
+
build_gift_card unless gift_card
|
|
10
|
+
gift_card.number = attrs[:number]
|
|
11
|
+
save
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def reset!
|
|
15
|
+
self.gift_card = nil
|
|
16
|
+
super
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
module Search
|
|
3
|
+
class Admin
|
|
4
|
+
class PaymentGiftCard < Search::Admin
|
|
5
|
+
def type
|
|
6
|
+
'gift_card'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def search_text
|
|
10
|
+
[
|
|
11
|
+
model.token,
|
|
12
|
+
model.to,
|
|
13
|
+
model.from,
|
|
14
|
+
model.message
|
|
15
|
+
].join ' '
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def jump_to_text
|
|
19
|
+
"#{model.token} - balance: #{model.balance}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def status
|
|
23
|
+
if model.balance.zero?
|
|
24
|
+
'redeemed'
|
|
25
|
+
elsif model.used > 0
|
|
26
|
+
'partially_redeemed'
|
|
27
|
+
else
|
|
28
|
+
'unredeemed'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def created_by
|
|
33
|
+
if model.order_id.present?
|
|
34
|
+
'order'
|
|
35
|
+
else
|
|
36
|
+
'admin'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def facets
|
|
41
|
+
super.merge(created_by: created_by)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Query class for models to match the API of {Search::Query}.
|
|
2
|
+
#
|
|
3
|
+
# HOLY SHIT THIS HOT MESS SHOULD BE SOLVED DIFFERENTLY AT SOME POINT
|
|
4
|
+
#
|
|
5
|
+
module Workarea
|
|
6
|
+
class AdminRedemptionsExport
|
|
7
|
+
include Search::Pagination
|
|
8
|
+
include GlobalID::Identification
|
|
9
|
+
|
|
10
|
+
attr_reader :params, :gift_cards_query_id
|
|
11
|
+
alias_method :id, :gift_cards_query_id
|
|
12
|
+
|
|
13
|
+
def self.find(id)
|
|
14
|
+
new(gift_cards_query_id: id)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize(params = {})
|
|
18
|
+
@params = params.with_indifferent_access
|
|
19
|
+
@gift_cards_query_id = params[:gift_cards_query_id]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def results
|
|
23
|
+
@results ||= PagedArray.new(
|
|
24
|
+
redemptions_for(gift_card_ids).to_a,
|
|
25
|
+
page,
|
|
26
|
+
per_page,
|
|
27
|
+
gift_cards_query.total # ensure correct paginating
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def scroll(options = {}, &block) # to match Search::Query method arguments
|
|
32
|
+
results.total_pages.times do |page|
|
|
33
|
+
query = self.class.new(params.merge(page: page + 1))
|
|
34
|
+
yield query.results
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def total
|
|
39
|
+
@total ||= begin
|
|
40
|
+
result = 0
|
|
41
|
+
|
|
42
|
+
gift_cards_query.results.total_pages.times do |page|
|
|
43
|
+
page_params = gift_cards_query.params.merge(page: page + 1)
|
|
44
|
+
page_query = gift_cards_query.class.new(page_params)
|
|
45
|
+
page_query.define_singleton_method(:per_page) { Workarea.config.bulk_action_per_page }
|
|
46
|
+
result += redemptions_for(page_query.results.map(&:id)).count
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
result
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def per_page
|
|
56
|
+
Workarea.config.bulk_action_per_page
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def redemptions_for(ids)
|
|
60
|
+
Payment::GiftCard::Redemption.in(gift_card_id: ids)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def gift_cards_page
|
|
64
|
+
params[:page].present? ? params[:page].to_i : 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def gift_cards_query
|
|
68
|
+
@gift_cards_query ||= begin
|
|
69
|
+
result = GlobalID.find(gift_cards_query_id)
|
|
70
|
+
page_for_query = gift_cards_page
|
|
71
|
+
result.define_singleton_method(:page) { page_for_query }
|
|
72
|
+
result
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def gift_card_ids
|
|
77
|
+
gift_cards_query.results.map(&:id) - exclude_gift_card_ids
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def exclude_gift_card_ids
|
|
81
|
+
GlobalID::Locator.locate_many(Array.wrap(params[:exclude_ids])).map(&:id)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
module Search
|
|
3
|
+
class AdminGiftCards
|
|
4
|
+
include Query
|
|
5
|
+
include AdminIndexSearch
|
|
6
|
+
include AdminSorting
|
|
7
|
+
include Pagination
|
|
8
|
+
|
|
9
|
+
document Search::Admin
|
|
10
|
+
|
|
11
|
+
def initialize(params = {})
|
|
12
|
+
super(params.merge(type: 'gift_card'))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def facets
|
|
16
|
+
super + [TermsFacet.new(self, 'created_by')]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
class GiftCardSeeds
|
|
3
|
+
def perform
|
|
4
|
+
puts 'Adding gift cards...'
|
|
5
|
+
add_gift_card_product
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def add_gift_card_product
|
|
11
|
+
product = Workarea::Catalog::Product.new(
|
|
12
|
+
id: 'GIFT_CARD',
|
|
13
|
+
name: 'Gift Card',
|
|
14
|
+
gift_card: true,
|
|
15
|
+
digital: true,
|
|
16
|
+
template: 'gift_card',
|
|
17
|
+
customizations: 'gift_card',
|
|
18
|
+
description: Faker::Lorem.paragraph,
|
|
19
|
+
variants: [
|
|
20
|
+
{ sku: 'GIFT_CARD_10' },
|
|
21
|
+
{ sku: 'GIFT_CARD_25' },
|
|
22
|
+
{ sku: 'GIFT_CARD_50' }
|
|
23
|
+
]
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
product.save!
|
|
27
|
+
|
|
28
|
+
Workarea::Pricing::Sku.find_or_create_by(
|
|
29
|
+
id: 'GIFT_CARD_10',
|
|
30
|
+
prices: [{ regular: 10 }]
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
Workarea::Pricing::Sku.find_or_create_by(
|
|
34
|
+
id: 'GIFT_CARD_25',
|
|
35
|
+
prices: [{ regular: 25 }]
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
Workarea::Pricing::Sku.find_or_create_by(
|
|
39
|
+
id: 'GIFT_CARD_50',
|
|
40
|
+
prices: [{ regular: 50 }]
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
class Checkout
|
|
3
|
+
module Steps
|
|
4
|
+
class GiftCard < Base
|
|
5
|
+
# Updates the checkout to use a gift card as one of
|
|
6
|
+
# its tenders.
|
|
7
|
+
#
|
|
8
|
+
# Sets pricing and reconciles tenders so the checkout
|
|
9
|
+
# can know whether we need more payment.
|
|
10
|
+
#
|
|
11
|
+
# @param [Hash] params
|
|
12
|
+
# @option params [String] :gift_card_number The gift card number to apply
|
|
13
|
+
#
|
|
14
|
+
# @return [Boolean] whether the update succeeded (payment were saved)
|
|
15
|
+
#
|
|
16
|
+
def update(params = {})
|
|
17
|
+
return false unless params[:gift_card_number].present?
|
|
18
|
+
gift_card_number = params[:gift_card_number].to_s.gsub(/\s+/, '')
|
|
19
|
+
|
|
20
|
+
return false unless valid_number?(gift_card_number)
|
|
21
|
+
payment.set_gift_card(number: gift_card_number)
|
|
22
|
+
|
|
23
|
+
Pricing.perform(order, shippings)
|
|
24
|
+
payment.adjust_tender_amounts(order.total_price)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Whether this update to use a gift card succeeded.
|
|
28
|
+
# If true, this was no gift card or a valid gift card applied,
|
|
29
|
+
# false means the gift card number was invalid or expired.
|
|
30
|
+
#
|
|
31
|
+
# @return [Boolean]
|
|
32
|
+
#
|
|
33
|
+
def complete?
|
|
34
|
+
!payment.gift_card? || (
|
|
35
|
+
payment.gift_card.valid? &&
|
|
36
|
+
valid_number?(payment.gift_card.number)
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def valid_number?(number)
|
|
43
|
+
return false unless number.present?
|
|
44
|
+
Workarea::Payment::GiftCard.find_balance(number) > 0
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
decorate Storefront::Checkout::PaymentViewModel, with: 'gift_cards' do
|
|
3
|
+
# Whether or not to show current gift card information.
|
|
4
|
+
# True if the current payment is a valid gift card.
|
|
5
|
+
#
|
|
6
|
+
# @return [Boolean]
|
|
7
|
+
#
|
|
8
|
+
def show_gift_card?
|
|
9
|
+
payment.gift_card?
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Can the current gift card cover the entire order
|
|
13
|
+
# total? Used for rendering gift card messaging.
|
|
14
|
+
#
|
|
15
|
+
# @return [Boolean]
|
|
16
|
+
#
|
|
17
|
+
def order_covered_by_gift_card?
|
|
18
|
+
gift_card_balance >= total_after_store_credit
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Can store credit or gift card cover the entire
|
|
22
|
+
# order total? Override this method in order to prevent
|
|
23
|
+
# a default credit card from being selected if
|
|
24
|
+
# not necessary to complete the order.
|
|
25
|
+
#
|
|
26
|
+
# @return [Boolean]
|
|
27
|
+
#
|
|
28
|
+
def order_covered_by_advance_payments?
|
|
29
|
+
super || order_covered_by_gift_card?
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
module Storefront
|
|
3
|
+
module GiftCardOrderPricing
|
|
4
|
+
def gift_card
|
|
5
|
+
return unless payment.gift_card.present?
|
|
6
|
+
@gift_card ||= Workarea::Payment::GiftCard.find_by_token(
|
|
7
|
+
payment.gift_card.number
|
|
8
|
+
)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def gift_card_balance
|
|
12
|
+
if gift_card.present?
|
|
13
|
+
gift_card.balance
|
|
14
|
+
else
|
|
15
|
+
0.to_m
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def gift_card_amount
|
|
20
|
+
if gift_card_balance > total_after_store_credit
|
|
21
|
+
total_after_store_credit
|
|
22
|
+
else
|
|
23
|
+
gift_card_balance
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def total_after_store_credit
|
|
28
|
+
order.total_price - store_credit_amount
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def order_balance
|
|
32
|
+
super - gift_card_amount
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
decorate Storefront::OrderViewModel, with: 'gift_card_display' do
|
|
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
|
+
|
|
23
|
+
def paid_amount
|
|
24
|
+
super - gift_card_tender_amount
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
.activity
|
|
2
|
+
.activity__header
|
|
3
|
+
.activity__avatar
|
|
4
|
+
= link_to_modifier(entry) do
|
|
5
|
+
= avatar_for entry.modifier
|
|
6
|
+
%h3.activity__name= link_to_modifier(entry)
|
|
7
|
+
%p.activity__time= activity_time(entry.created_at)
|
|
8
|
+
.activity__message
|
|
9
|
+
- if entry.audited.present?
|
|
10
|
+
= t('workarea.admin.activities.payment_gift_card_create_html', name: link_to(entry.audited.name, payment_gift_card_path(entry.audited)))
|
|
11
|
+
- else
|
|
12
|
+
= t('workarea.admin.activities.payment_gift_card_create_html', name: t('workarea.payment_gift_card.name', token: entry.token))
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
.activity
|
|
2
|
+
.activity__header
|
|
3
|
+
.activity__avatar
|
|
4
|
+
= link_to_modifier(entry) do
|
|
5
|
+
= avatar_for entry.modifier
|
|
6
|
+
%h3.activity__name= link_to_modifier(entry)
|
|
7
|
+
%p.activity__time= activity_time(entry.created_at)
|
|
8
|
+
.activity__message
|
|
9
|
+
= t('workarea.admin.activities.payment_gift_card_destroy_html')
|
|
10
|
+
= link_to_restore_for(entry)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.activity
|
|
2
|
+
.activity__header
|
|
3
|
+
.activity__avatar
|
|
4
|
+
= link_to_modifier(entry) do
|
|
5
|
+
= avatar_for entry.modifier
|
|
6
|
+
%h3.activity__name= link_to_modifier(entry)
|
|
7
|
+
%p.activity__time= activity_time(entry.created_at)
|
|
8
|
+
.activity__message
|
|
9
|
+
- if entry.audited.blank?
|
|
10
|
+
- name = t('workarea.payment_gift_card.name', token: entry.token)
|
|
11
|
+
- else
|
|
12
|
+
- name = link_to(entry.audited.name, payment_gift_card_path(entry.audited))
|
|
13
|
+
|
|
14
|
+
= t('workarea.admin.activities.payment_gift_card_update_html', fields: fields_clause_for(entry.tracked_changes), name: name)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
.grid.grid--auto.grid--flush.grid--center
|
|
2
|
+
.grid__cell
|
|
3
|
+
.card{ class: card_classes(:attributes, local_assigns[:active]) }
|
|
4
|
+
= link_to edit_payment_gift_card_path(model), class: 'card__header' do
|
|
5
|
+
%span.card__header-text= t('workarea.admin.cards.attributes.title')
|
|
6
|
+
= inline_svg 'workarea/admin/icons/attributes.svg', class: 'card__icon'
|
|
7
|
+
|
|
8
|
+
- if local_assigns[:active].blank?
|
|
9
|
+
.card__body
|
|
10
|
+
%ul.list-reset
|
|
11
|
+
%li
|
|
12
|
+
%strong #{t('workarea.admin.fields.token')}:
|
|
13
|
+
= model.token
|
|
14
|
+
%li
|
|
15
|
+
%strong #{t('workarea.admin.fields.amount')}:
|
|
16
|
+
= number_to_currency model.amount
|
|
17
|
+
%li
|
|
18
|
+
%strong #{t('workarea.admin.fields.order_id')}:
|
|
19
|
+
= model.order_id.presence || t('workarea.admin.cards.attributes.no_value')
|
|
20
|
+
%li
|
|
21
|
+
%strong #{t('workarea.admin.fields.recipient')}:
|
|
22
|
+
= model.to
|
|
23
|
+
%li
|
|
24
|
+
%strong #{t('workarea.admin.fields.from')}:
|
|
25
|
+
= model.from.presence || t('workarea.admin.cards.attributes.no_value')
|
|
26
|
+
%li
|
|
27
|
+
%strong #{t('workarea.admin.fields.message')}:
|
|
28
|
+
= model.message.presence || t('workarea.admin.cards.attributes.no_value')
|
|
29
|
+
%li
|
|
30
|
+
%strong #{t('workarea.admin.fields.notify')}:
|
|
31
|
+
= model.notify ? t('workarea.admin.true') : t('workarea.admin.false')
|
|
32
|
+
%li
|
|
33
|
+
%strong #{t('workarea.admin.fields.expires_at')}:
|
|
34
|
+
- if model.expires_at.present?
|
|
35
|
+
= local_time_ago(model.expires_at)
|
|
36
|
+
- else
|
|
37
|
+
= t('workarea.admin.cards.attributes.no_value')
|
|
38
|
+
%li
|
|
39
|
+
%strong= t('workarea.admin.fields.updated_at')
|
|
40
|
+
#{local_time_ago(model.updated_at)}
|
|
41
|
+
%li
|
|
42
|
+
%strong= t('workarea.admin.fields.created_at')
|
|
43
|
+
#{local_time_ago(model.created_at)}
|
|
44
|
+
|
|
45
|
+
= link_to edit_payment_gift_card_path(model), class: 'card__button' do
|
|
46
|
+
%span.button.button--small= t('workarea.admin.cards.attributes.button')
|
|
47
|
+
|
|
48
|
+
.grid__cell
|
|
49
|
+
.card{ class: card_classes(:redemptions, local_assigns[:active]) }
|
|
50
|
+
= link_to payment_gift_card_redemptions_path(model), class: 'card__header' do
|
|
51
|
+
%span.card__header-text= t('workarea.admin.payment_gift_cards.cards.redemptions.title')
|
|
52
|
+
= inline_svg 'workarea/admin/icons/prices.svg', class: 'card__icon'
|
|
53
|
+
|
|
54
|
+
- if local_assigns[:active].blank?
|
|
55
|
+
.card__body
|
|
56
|
+
- if model.redemptions.empty?
|
|
57
|
+
%p= t('workarea.admin.payment_gift_cards.cards.redemptions.empty')
|
|
58
|
+
- else
|
|
59
|
+
%ul.list-reset
|
|
60
|
+
- model.redemptions.take(10).each do |redemption|
|
|
61
|
+
%li
|
|
62
|
+
%strong= redemption.order_id
|
|
63
|
+
= number_to_currency redemption.amount
|
|
64
|
+
#{local_time_ago(redemption.redeemed_at)}
|
|
65
|
+
- if model.redemptions.size > 10
|
|
66
|
+
%li= t('workarea.admin.cards.more', amount: model.redemptions.size - 10)
|
|
67
|
+
= link_to payment_gift_card_redemptions_path(model), class: 'card__button' do
|
|
68
|
+
%span.button.button--small= t('workarea.admin.payment_gift_cards.cards.redemptions.button')
|
|
69
|
+
|
|
70
|
+
.grid__cell
|
|
71
|
+
= render 'workarea/admin/timeline/card', timeline: model.timeline, active: local_assigns[:active]
|
|
72
|
+
|
|
73
|
+
.grid__cell
|
|
74
|
+
= render 'workarea/admin/comments/card', commentable: model, active: local_assigns[:active]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
%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)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
.summary{ data: { global_id: model.to_global_id.to_param } }
|
|
2
|
+
= link_to payment_gift_card_path(model, return_to: params[:return_to]) do
|
|
3
|
+
%span.summary__name= model.name
|
|
4
|
+
.summary__info-container
|
|
5
|
+
%span.summary__info= local_time_ago(model.updated_at)
|
|
6
|
+
%span.summary__info= number_to_currency model.amount
|
|
7
|
+
%span.summary__type= t('workarea.admin.payment_gift_cards.gift_card')
|
|
8
|
+
|
|
9
|
+
.summary__checkbox.hidden
|
|
10
|
+
= check_box_tag 'product_id', model.to_global_id.to_param, false, class: 'summary__checkbox-input', id: dom_id(model)
|
|
11
|
+
= label_tag dom_id(model), t('workarea.admin.bulk_actions.add_summary_button'), class: 'summary__checkbox-label'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
- @page_title = t('workarea.admin.payment_gift_cards.edit.title', name: @gift_card.name)
|
|
2
|
+
|
|
3
|
+
.view
|
|
4
|
+
.view__header
|
|
5
|
+
.grid.grid--middle
|
|
6
|
+
.grid__cell.grid__cell--25
|
|
7
|
+
= render 'workarea/admin/releases/select'
|
|
8
|
+
.grid__cell.grid__cell--50
|
|
9
|
+
.view__heading
|
|
10
|
+
= link_to_index_for(@gift_card)
|
|
11
|
+
%h1= link_to @gift_card.name, url_for(@gift_card)
|
|
12
|
+
.grid__cell.grid__cell--25
|
|
13
|
+
= render_aux_navigation_for(@gift_card)
|
|
14
|
+
|
|
15
|
+
.view__container
|
|
16
|
+
= render_cards_for(@gift_card, :attributes)
|
|
17
|
+
|
|
18
|
+
.view__container.view__container--narrow
|
|
19
|
+
- if @gift_card.errors.present?
|
|
20
|
+
- @gift_card.errors.full_messages.each do |message|
|
|
21
|
+
= render_message 'error', message
|
|
22
|
+
|
|
23
|
+
= form_tag payment_gift_card_path(@gift_card), method: 'patch', id: 'payment_gift_card_form' do
|
|
24
|
+
= hidden_field_tag 'return_to', request.referrer
|
|
25
|
+
|
|
26
|
+
.section
|
|
27
|
+
.property
|
|
28
|
+
= label_tag 'gift_card[to]', t('workarea.admin.fields.recipient'), class: 'property__name'
|
|
29
|
+
= email_field_tag 'gift_card[to]', @gift_card.to, class: 'text-box'
|
|
30
|
+
|
|
31
|
+
.property
|
|
32
|
+
= label_tag 'gift_card[expires_at]', t('workarea.admin.fields.expires_on'), class: 'property__name'
|
|
33
|
+
= datetime_picker_tag 'gift_card[expires_at]', @gift_card.expires_at, class: 'text-box', data: { datepicker_field: { inline: false } }
|
|
34
|
+
|
|
35
|
+
.workflow-bar
|
|
36
|
+
.grid.grid--auto.grid--right.grid--middle
|
|
37
|
+
.grid__cell= button_tag t('workarea.admin.payment_gift_cards.edit.button'), value: 'save_gift_card', class: 'workflow-bar__button workflow-bar__button--create'
|