workarea-gift_cards 3.4.6
Sign up to get free protection for your applications and to get access to all the features.
- 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,95 @@
|
|
1
|
+
- @page_title = t('workarea.admin.payment_gift_cards.index.title')
|
2
|
+
|
3
|
+
.view
|
4
|
+
.view__header
|
5
|
+
.grid.grid--middle.grid--center
|
6
|
+
.grid__cell.grid__cell--50
|
7
|
+
.view__heading
|
8
|
+
= link_to "↑ #{t('workarea.admin.orders.index.dashboard_link')}", orders_dashboards_path, class: 'view__dashboard-button'
|
9
|
+
%h1= t('workarea.admin.payment_gift_cards.index.title')
|
10
|
+
|
11
|
+
.view__container
|
12
|
+
.browsing-controls.browsing-controls--with-divider.browsing-controls--center{ class: ('browsing-controls--filters-displayed' unless @search.toggle_facets?) }
|
13
|
+
= form_tag payment_gift_cards_path, method: 'get', id: 'gift_cards_form' do
|
14
|
+
= facet_hidden_inputs(@search.facets)
|
15
|
+
.browsing-controls__sort
|
16
|
+
.property.property--inline
|
17
|
+
= label_tag 'sort', t('workarea.admin.search.sort_by'), class: 'property__name'
|
18
|
+
= select_tag :sort, options_for_select(@search.sorts, selected: @search.sort), data: { form_submitting_control: '' }
|
19
|
+
|
20
|
+
.browsing-controls__search
|
21
|
+
.search-form
|
22
|
+
= text_field_tag :q, params[:q], class: 'search-form__input', id: 'search_products', title: t('workarea.admin.search.keywords'), placeholder: t('workarea.admin.search.keywords')
|
23
|
+
= submit_tag 'search_gift_cards', class: 'search-form__button'
|
24
|
+
|
25
|
+
= render 'workarea/admin/shared/creation_date', search: @search, form_path: payment_gift_cards_path
|
26
|
+
|
27
|
+
- if @search.facets.present?
|
28
|
+
- @search.facets.each do |facet|
|
29
|
+
= render "workarea/admin/facets/#{facet.type}", facet: facet
|
30
|
+
|
31
|
+
- if @search.toggle_facets?
|
32
|
+
.browsing-controls__toggle-filters
|
33
|
+
%button.text-button{ type: 'button', data: { toggle_filters: '' } }= t('workarea.admin.search.show_filters')
|
34
|
+
|
35
|
+
= render 'workarea/admin/facets/applied', search: @search, reset_path: payment_gift_cards_path
|
36
|
+
|
37
|
+
%p.browsing-controls__count{ data: { browsing_controls_count: @search.total } }
|
38
|
+
= pluralize(@search.total, t('workarea.admin.payment_gift_cards.gift_card'))
|
39
|
+
|
40
|
+
- if @search.results.any?
|
41
|
+
%table.index-table
|
42
|
+
%thead
|
43
|
+
%tr
|
44
|
+
%th.index-table__control-cell
|
45
|
+
.checkbox
|
46
|
+
= check_box_tag 'select_all', nil, false, id: 'select_all', class: 'checkbox__input', data: { bulk_action_select_all: '' }
|
47
|
+
= label_tag 'select_all', t('workarea.admin.bulk_actions.select_all'), class: 'checkbox__label'
|
48
|
+
%th= t('workarea.admin.fields.token')
|
49
|
+
%th= t('workarea.admin.fields.from')
|
50
|
+
%th= t('workarea.admin.fields.recipient')
|
51
|
+
%th.align-right= t('workarea.admin.fields.amount')
|
52
|
+
%th.align-right= t('workarea.admin.fields.balance')
|
53
|
+
%th.align-center= t('workarea.admin.fields.order_id')
|
54
|
+
%th.align-right= t('workarea.admin.fields.expires_on')
|
55
|
+
%th= t('workarea.admin.fields.created_at')
|
56
|
+
|
57
|
+
%tbody
|
58
|
+
- @search.results.each do |result|
|
59
|
+
%tr.index-table__row
|
60
|
+
%td.index-table__control-cell
|
61
|
+
.checkbox
|
62
|
+
= check_box_tag 'global_id', result.to_global_id.to_param, false, class: 'checkbox__input', id: dom_id(result), data: { bulk_action_item: '' }
|
63
|
+
= label_tag dom_id(result), '', class: 'checkbox__label', title: t('workarea.admin.bulk_actions.add_summary_button')
|
64
|
+
%td
|
65
|
+
= link_to result.token, payment_gift_card_path(result)
|
66
|
+
= upcoming_changesets_icon_for(result)
|
67
|
+
= comments_icon_for(result)
|
68
|
+
%td= result.from.presence || t('workarea.admin.cards.attributes.no_value')
|
69
|
+
%td= result.to
|
70
|
+
%td.align-right= number_to_currency result.amount
|
71
|
+
%td.align-right= number_to_currency result.balance
|
72
|
+
%td.align-center= result.order_id.presence || t('workarea.admin.cards.attributes.no_value')
|
73
|
+
%td.align-right
|
74
|
+
- if result.expires_at.present?
|
75
|
+
= local_time_ago(result.expires_at)
|
76
|
+
- else
|
77
|
+
= t('workarea.admin.cards.attributes.no_value')
|
78
|
+
%td= local_time_ago(result.created_at)
|
79
|
+
|
80
|
+
- if @search.results.total_pages > 1
|
81
|
+
= render 'workarea/admin/shared/pagination', collection: @search.results
|
82
|
+
|
83
|
+
.workflow-bar
|
84
|
+
.grid
|
85
|
+
.grid__cell.grid__cell--50
|
86
|
+
= render 'workarea/admin/shared/bulk_actions', klass: Workarea::Payment::GiftCard, search: @search do
|
87
|
+
.grid__cell
|
88
|
+
= form_tag new_data_file_export_path, method: 'get', data: { bulk_action_form: '' } do
|
89
|
+
= hidden_field_tag 'model_type', 'Workarea::Payment::GiftCard::Redemption', id: nil
|
90
|
+
= hidden_field_tag 'query_id', @search.to_gid_param, id: nil
|
91
|
+
= hidden_field_tag 'return_to', request.path, id: nil
|
92
|
+
%button.workflow-bar__button{ type: :submit }= t('workarea.admin.payment_gift_cards.index.export_redemptions')
|
93
|
+
|
94
|
+
.grid__cell.grid__cell--50.align-right
|
95
|
+
= link_to t('workarea.admin.payment_gift_cards.index.button'), new_payment_gift_card_path, id: 'add_payment_gift_card', class: 'workflow-bar__button workflow-bar__button--create'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
- @page_title = t('workarea.admin.payment_gift_cards.new.title')
|
2
|
+
|
3
|
+
.view
|
4
|
+
.view__header
|
5
|
+
.grid.grid--middle.grid--center
|
6
|
+
.grid__cell.grid__cell--50
|
7
|
+
.view__heading
|
8
|
+
= link_to_index_for(@gift_card)
|
9
|
+
%h1= t('workarea.admin.payment_gift_cards.new.title')
|
10
|
+
|
11
|
+
.view__container
|
12
|
+
- if @gift_card.errors.present?
|
13
|
+
- @gift_card.errors.full_messages.each do |message|
|
14
|
+
= render_message 'error', message
|
15
|
+
|
16
|
+
= form_tag payment_gift_cards_path, method: 'post', id: 'payment_gift_card_form' do
|
17
|
+
= hidden_field_tag 'return_to', request.referrer
|
18
|
+
|
19
|
+
.section
|
20
|
+
.property
|
21
|
+
= label_tag 'gift_card[token]', t('workarea.admin.fields.token'), class: 'property__name'
|
22
|
+
= text_field_tag 'gift_card[token]', @gift_card.token, class: 'text-box'
|
23
|
+
|
24
|
+
.property
|
25
|
+
= label_tag 'gift_card[to]', t('workarea.admin.fields.recipient'), class: 'property__name'
|
26
|
+
= email_field_tag 'gift_card[to]', @gift_card.to, class: 'text-box'
|
27
|
+
|
28
|
+
.property
|
29
|
+
= label_tag 'gift_card[notify]', t('workarea.admin.fields.notify'), class: 'property__name'
|
30
|
+
= check_box_tag 'gift_card[notify]', 1, false
|
31
|
+
|
32
|
+
.property
|
33
|
+
= label_tag 'gift_card[amount]', t('workarea.admin.fields.amount'), class: 'property__name'
|
34
|
+
%span $
|
35
|
+
= text_field_tag 'gift_card[amount]', @gift_card.amount, class: 'text-box text-box--small'
|
36
|
+
|
37
|
+
.property
|
38
|
+
= label_tag 'gift_card[expires_at]', t('workarea.admin.fields.expires_on'), class: 'property__name'
|
39
|
+
= datetime_picker_tag 'gift_card[expires_at]', @gift_card.expires_at, class: 'text-box', data: { datepicker_field: { inline: false } }
|
40
|
+
|
41
|
+
.workflow-bar
|
42
|
+
.grid.grid--auto.grid--right.grid--middle
|
43
|
+
.grid__cell= button_tag t('workarea.admin.payment_gift_cards.new.button'), value: 'create_gift_card', class: 'workflow-bar__button workflow-bar__button--create'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
- @page_title = t('workarea.admin.payment_gift_cards.redemptions.title', name: @gift_card.name)
|
2
|
+
|
3
|
+
.view
|
4
|
+
.view__header
|
5
|
+
.grid.grid--middle.grid--center
|
6
|
+
.grid__cell.grid__cell--50
|
7
|
+
.view__heading
|
8
|
+
= link_to_index_for(@gift_card)
|
9
|
+
%h1= link_to @gift_card.name, url_for(@gift_card)
|
10
|
+
|
11
|
+
.view__container
|
12
|
+
= render_cards_for(@gift_card, :redemptions)
|
13
|
+
|
14
|
+
.view__container
|
15
|
+
%p.align-center= pluralize(@gift_card.redemptions.count, t('workarea.admin.payment_gift_cards.redemptions.redemption'))
|
16
|
+
|
17
|
+
- if @gift_card.redemptions.any?
|
18
|
+
%table
|
19
|
+
%thead
|
20
|
+
%tr
|
21
|
+
%th= t('workarea.admin.fields.order_id')
|
22
|
+
%th= t('workarea.admin.fields.amount')
|
23
|
+
%th= t('workarea.admin.fields.redeemed_at')
|
24
|
+
%tbody
|
25
|
+
- @gift_card.redemptions.each do |redemption|
|
26
|
+
%tr
|
27
|
+
%td= link_to redemption.order_id, order_path(redemption.order_id)
|
28
|
+
%td= number_to_currency redemption.amount
|
29
|
+
%td= local_time(redemption.redeemed_at, :long)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
- @page_title = @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= @gift_card.name
|
12
|
+
.grid__cell.grid__cell--25
|
13
|
+
= render_aux_navigation_for(@gift_card)
|
14
|
+
|
15
|
+
.view__container
|
16
|
+
= render_cards_for(@gift_card)
|
17
|
+
|
18
|
+
.workflow-bar
|
19
|
+
= link_to t('workarea.admin.actions.delete'), payment_gift_card_path(@gift_card), class: 'workflow-bar__button workflow-bar__button--delete', data: { method: 'delete', confirm: t('workarea.admin.actions.delete_confirmation') }
|
@@ -0,0 +1,28 @@
|
|
1
|
+
.checkout-payment__secondary-method{ class: step.show_gift_card? ? 'checkout-payment__secondary-method--visible' : nil }
|
2
|
+
|
3
|
+
- if step.show_gift_card?
|
4
|
+
.message.message--info
|
5
|
+
%p.message__type
|
6
|
+
%span.message__icon= t('workarea.storefront.messages.info')
|
7
|
+
%p.message__text
|
8
|
+
#{t('workarea.storefront.gift_cards.balance', amount: number_to_currency(step.gift_card_balance))}
|
9
|
+
#{t('workarea.storefront.gift_cards.applied_to_order', amount: number_to_currency(step.gift_card_amount))}
|
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
|
+
- if step.tender_required?
|
14
|
+
#{t('workarea.storefront.gift_cards.tender_required', amount: number_to_currency(step.order_balance))}
|
15
|
+
|
16
|
+
= optional_field(t('workarea.storefront.gift_cards.enter_gift_card_prompt'), step.gift_card.try(:number)) do
|
17
|
+
|
18
|
+
%h2= t('workarea.storefront.gift_cards.gift_card')
|
19
|
+
|
20
|
+
= form_tag checkout_add_gift_card_path, method: 'patch', id: 'gift_card_form', class: 'inline-form' do
|
21
|
+
|
22
|
+
.inline-form__cell
|
23
|
+
.value
|
24
|
+
= text_field_tag 'gift_card_number', step.gift_card.try(: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.gift_card && step.gift_card.errors[:number].present?
|
26
|
+
%span.value__error= step.gift_card.errors[:number].first
|
27
|
+
.inline-form__cell
|
28
|
+
%p= button_tag t('workarea.storefront.gift_cards.apply_gift_card'), value: 'apply_gift_card', class: 'button'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
%tr
|
2
|
+
%td
|
3
|
+
%h1= t('workarea.storefront.email.gift_card_created.heading')
|
4
|
+
%p
|
5
|
+
%strong= @from
|
6
|
+
%br
|
7
|
+
= t('workarea.storefront.email.gift_card_created.message_html', link: link_to(Workarea.config.host, Workarea.config.host, style: "color: #{@config.link_color}"), amount: number_to_currency(@card.amount))
|
8
|
+
|
9
|
+
- if @card.message.present?
|
10
|
+
%p
|
11
|
+
%strong= @from
|
12
|
+
%br
|
13
|
+
= @card.message
|
14
|
+
|
15
|
+
%p= t('workarea.storefront.email.gift_card_created.how_to_redeem', token: @card.token)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
.view
|
2
|
+
|
3
|
+
%h1= t('workarea.storefront.gift_cards.check_balance')
|
4
|
+
|
5
|
+
= form_tag gift_cards_lookup_path, method: 'get' do
|
6
|
+
|
7
|
+
.property.property--responsive
|
8
|
+
= label_tag 'gift_card_email', class: 'property__name' do
|
9
|
+
%span.property__text= t('workarea.storefront.users.email')
|
10
|
+
.value= email_field_tag :email, nil, id: 'gift_card_email', class: 'text-box', required: true
|
11
|
+
|
12
|
+
.property.property--responsive
|
13
|
+
= label_tag 'gift_card_number', class: 'property__name' do
|
14
|
+
%span.property__text= t('workarea.storefront.gift_cards.gift_card_number')
|
15
|
+
.value= text_field_tag :token, nil, id: 'gift_card_number', class: 'text-box', required: true
|
16
|
+
|
17
|
+
%p= button_tag t('workarea.storefront.forms.go'), value: 'submit', class: 'button'
|
@@ -0,0 +1,9 @@
|
|
1
|
+
.data-card
|
2
|
+
.data-card__cell
|
3
|
+
%p.data-card__line.data-card__credit-card
|
4
|
+
= inline_svg('workarea/storefront/payment_icons/gift_card.svg', title: t('workarea.storefront.orders.tenders.gift_card.title'), class: 'payment-icon')
|
5
|
+
%span.data-card__credit-card-number
|
6
|
+
= t('workarea.storefront.credit_cards.summary', issuer: t('workarea.storefront.orders.tenders.gift_card.title'), number: tender.display_number)
|
7
|
+
%p.data-card__line
|
8
|
+
%strong
|
9
|
+
#{t('workarea.storefront.orders.amount')}: #{number_to_currency tender.amount}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
.grid.grid--rev
|
2
|
+
.grid__cell.grid__cell--60-at-medium
|
3
|
+
|
4
|
+
.product-details__name
|
5
|
+
%h1.product-details__heading{ itemprop: 'name' }= product.name
|
6
|
+
|
7
|
+
%p.product-details__id
|
8
|
+
%span{ itemprop: 'productID' }= product.id
|
9
|
+
|
10
|
+
.product-prices.product-prices--details{ itemprop: 'offers', itemscope: true, itemtype: 'http://schema.org/Offer' }
|
11
|
+
= render 'workarea/storefront/products/pricing', product: product
|
12
|
+
|
13
|
+
- if product.description.present?
|
14
|
+
.product-details__description
|
15
|
+
%p= truncated_product_description(product, t('workarea.storefront.products.read_more'))
|
16
|
+
|
17
|
+
= form_tag cart_items_path, method: 'post', class: 'product-details__add-to-cart-form', data: { dialog_form: { dialogOptions: { closeAll: true, initModules: true } }, analytics: add_to_cart_analytics_data(product).to_json } do
|
18
|
+
= hidden_field_tag :product_id, product.id, id: dom_id(product, 'product_id')
|
19
|
+
|
20
|
+
- if product.sku_options.one?
|
21
|
+
= hidden_field_tag :sku, product.sku_options.first.second
|
22
|
+
|
23
|
+
- else
|
24
|
+
.property
|
25
|
+
= label_tag :sku, nil, class: 'property__name', for: "sku_#{dom_id(product)}" do
|
26
|
+
%span.property__text= t('workarea.storefront.products.select_options')
|
27
|
+
.value
|
28
|
+
= select_tag :sku, options_for_select(product.sku_options, params[:sku]), required: true, id: "sku_#{dom_id(product)}", data: { product_details_sku_select: product.slug }
|
29
|
+
- if params[:sku].present?
|
30
|
+
.value__note= product.inventory_status
|
31
|
+
|
32
|
+
= hidden_field_tag :quantity, 1, id: "quantity#{dom_id(product)}"
|
33
|
+
|
34
|
+
.message.message--info
|
35
|
+
%p.message__type
|
36
|
+
%span.message__icon= t('workarea.storefront.messages.info')
|
37
|
+
%p.message__text= t('workarea.storefront.gift_cards.email_to_recipient')
|
38
|
+
|
39
|
+
.property
|
40
|
+
= label_tag :email, nil, class: "property__name", for: "email_#{dom_id(product)}" do
|
41
|
+
%span.property__text= t('workarea.storefront.gift_cards.recipients_email')
|
42
|
+
.value= email_field_tag :email, params[:email], class: 'text-box', required: true, id: "email_#{dom_id(product)}"
|
43
|
+
.property
|
44
|
+
= label_tag :from, nil, class: "property__name", for: "from_#{dom_id(product)}" do
|
45
|
+
%span.property__text= t('workarea.storefront.gift_cards.senders_email')
|
46
|
+
%span.property__requirement.property__requirement--optional= t('workarea.storefront.forms.optional')
|
47
|
+
.value= text_field_tag :from, params[:from], class: 'text-box', id: "from_#{dom_id(product)}", maxlength: 100
|
48
|
+
.property
|
49
|
+
= label_tag :message, nil, class: "property__name", for: "message_#{dom_id(product)}" do
|
50
|
+
%span.property__text= t('workarea.storefront.gift_cards.message_to_recipient')
|
51
|
+
%span.property__requirement.property__requirement--optional= t('workarea.storefront.forms.optional')
|
52
|
+
.value= text_area_tag :message, params[:message], class: 'text-box text-box--multi-line', id: "message_#{dom_id(product)}", maxlength: 500
|
53
|
+
|
54
|
+
- if product.purchasable?
|
55
|
+
%p.product-details__add-to-cart-action= button_tag t('workarea.storefront.products.add_to_cart'), value: 'add_to_cart', class: 'button button--large'
|
56
|
+
|
57
|
+
- else
|
58
|
+
%p.product-details__unavailable= t('workarea.storefront.products.unavailable')
|
59
|
+
|
60
|
+
= append_partials('storefront.product_details', product: product)
|
61
|
+
|
62
|
+
%p.product-details__full-details=link_to t('workarea.storefront.products.view_full_details'), product_path(product, color: params[:color]), class: 'text-button', itemprop: 'url'
|
63
|
+
|
64
|
+
.grid__cell.grid__cell--40-at-medium
|
65
|
+
|
66
|
+
.product-details__primary-image
|
67
|
+
= link_to(product_image_url(product.primary_image, :zoom), target: '_blank', class: 'product-details__primary-image-link', data: { dialog_button: '' }) do
|
68
|
+
= image_tag product_image_url(product.primary_image, :detail), alt: 'View Larger Image', itemprop: 'image', class: 'product-details__primary-image-link-image'
|
69
|
+
|
70
|
+
- if product.images.length > 1
|
71
|
+
.product-details__alt-images
|
72
|
+
.grid.grid--auto
|
73
|
+
- product.images.each_with_index do |image, index|
|
74
|
+
.grid__cell
|
75
|
+
.product-details__alt-image
|
76
|
+
- button_class = index == 0 ? 'product-details__alt-image-link product-details__alt-image-link--selected' : 'product-details__alt-image-link'
|
77
|
+
= link_to(image_tag(product_image_url(image, :small_thumb), alt: t('workarea.storefront.products.zoom')), product_image_url(image, :zoom), class: button_class, target: '_blank', data: { alternate_image_button: { src: product_image_url(image, :detail) }.to_json })
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Workarea
|
2
|
+
class CreateOrderedGiftCards
|
3
|
+
include Sidekiq::Worker
|
4
|
+
include Sidekiq::CallbacksWorker
|
5
|
+
|
6
|
+
sidekiq_options enqueue_on: { Fulfillment => :create }
|
7
|
+
|
8
|
+
def perform(order_id)
|
9
|
+
order = Order.find(order_id)
|
10
|
+
fulfillment = Fulfillment.find(order.id)
|
11
|
+
|
12
|
+
gift_cards = order.items.select do |item|
|
13
|
+
item.digital? && item.gift_card?
|
14
|
+
end
|
15
|
+
|
16
|
+
gift_cards.each do |item|
|
17
|
+
unit_adjustment = item.price_adjustments.first
|
18
|
+
unit_amount = unit_adjustment.amount / item.quantity
|
19
|
+
|
20
|
+
item.quantity.times do
|
21
|
+
Payment::GiftCard.create!(
|
22
|
+
amount: unit_amount,
|
23
|
+
order_id: order.id,
|
24
|
+
to: item.customizations['email'],
|
25
|
+
from: item.customizations['from'],
|
26
|
+
message: item.customizations['message'],
|
27
|
+
notify: true,
|
28
|
+
purchased: true
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
update_fulfillment(fulfillment, item)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def update_fulfillment(fulfillment, item)
|
39
|
+
# Ensure item is there to ship
|
40
|
+
fulfillment.items.detect { |i| i.order_item_id == item.id.to_s } ||
|
41
|
+
fulfillment.items.build(order_item_id: item.id, quantity: item.quantity)
|
42
|
+
|
43
|
+
fulfillment.mark_item_shipped(id: item.id.to_s, quantity: item.quantity)
|
44
|
+
fulfillment.save!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Workarea
|
2
|
+
class LogGiftCardRedemption
|
3
|
+
include Sidekiq::Worker
|
4
|
+
include Sidekiq::CallbacksWorker
|
5
|
+
|
6
|
+
sidekiq_options enqueue_on: { Order => :place }
|
7
|
+
|
8
|
+
def perform(order_id)
|
9
|
+
order = Order.find(order_id)
|
10
|
+
|
11
|
+
payment = Payment.find_or_initialize_by(id: order.id)
|
12
|
+
return unless payment.gift_card?
|
13
|
+
|
14
|
+
gift_card = Payment::GiftCard.find_by_token(payment.gift_card.number)
|
15
|
+
return if redemption_already_exists?(gift_card, order.id)
|
16
|
+
|
17
|
+
gift_card.redemptions.create!(
|
18
|
+
redeemed_at: order.placed_at,
|
19
|
+
amount: payment.gift_card.amount,
|
20
|
+
order_id: order.id
|
21
|
+
)
|
22
|
+
|
23
|
+
gift_card.touch
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def redemption_already_exists?(card, order_id)
|
29
|
+
card.redemptions.pluck(:order_id).include?(order_id)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Workarea
|
2
|
+
class SendGiftCardNotifications
|
3
|
+
include Sidekiq::Worker
|
4
|
+
include Sidekiq::CallbacksWorker
|
5
|
+
|
6
|
+
sidekiq_options enqueue_on: { Payment::GiftCard => :create }, queue: 'low'
|
7
|
+
|
8
|
+
def perform(gift_card_id)
|
9
|
+
card = Payment::GiftCard.find(gift_card_id)
|
10
|
+
return unless send_notification?(card)
|
11
|
+
Storefront::GiftCardMailer.created(card.id.to_s).deliver_now
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def send_notification?(card)
|
17
|
+
card.order_id.present? || (card.to.present? && card.notify?)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/bin/rails
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
3
|
+
# installed from the root of your application.
|
4
|
+
|
5
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
6
|
+
ENGINE_PATH = File.expand_path('../../lib/workarea/gift_cards/engine', __FILE__)
|
7
|
+
|
8
|
+
# Set up gems listed in the Gemfile.
|
9
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
10
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
11
|
+
|
12
|
+
require 'action_controller/railtie'
|
13
|
+
require 'action_view/railtie'
|
14
|
+
require 'action_mailer/railtie'
|
15
|
+
require 'rails/test_unit/railtie'
|
16
|
+
require 'sprockets/railtie'
|
17
|
+
|
18
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#
|
2
|
+
# Store Front
|
3
|
+
#
|
4
|
+
#
|
5
|
+
Workarea.append_partials(
|
6
|
+
'storefront.checkout_summary_payment',
|
7
|
+
'workarea/storefront/checkouts/gift_card_summary'
|
8
|
+
)
|
9
|
+
|
10
|
+
Workarea.append_partials(
|
11
|
+
'storefront.payment_error',
|
12
|
+
'workarea/storefront/checkouts/gift_card_error'
|
13
|
+
)
|
14
|
+
|
15
|
+
Workarea.append_partials(
|
16
|
+
'storefront.secondary_payment',
|
17
|
+
'workarea/storefront/checkouts/gift_card_payment'
|
18
|
+
)
|
19
|
+
|
20
|
+
Workarea.append_partials(
|
21
|
+
'storefront.order_summary_payment',
|
22
|
+
'workarea/storefront/orders/gift_card_summary'
|
23
|
+
)
|
24
|
+
|
25
|
+
Workarea.append_partials(
|
26
|
+
'storefront.order_mailer_summary_payment',
|
27
|
+
'workarea/storefront/order_mailer/gift_card_summary'
|
28
|
+
)
|
29
|
+
|
30
|
+
#
|
31
|
+
# Admin
|
32
|
+
#
|
33
|
+
#
|
34
|
+
Workarea.append_partials(
|
35
|
+
'admin.orders_menu',
|
36
|
+
'workarea/admin/payment_gift_cards/menu'
|
37
|
+
)
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Workarea.configure do |config|
|
2
|
+
config.checkout_steps << 'Workarea::Checkout::Steps::GiftCard'
|
3
|
+
config.customization_types << Workarea::Catalog::Customizations::GiftCard
|
4
|
+
config.product_templates << :gift_card
|
5
|
+
config.tender_types.prepend(:gift_card)
|
6
|
+
config.seeds << 'Workarea::GiftCardSeeds'
|
7
|
+
config.gift_card_token_length = 8
|
8
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
en:
|
2
|
+
workarea:
|
3
|
+
admin:
|
4
|
+
activities:
|
5
|
+
payment_gift_card_create_html: created %{name}
|
6
|
+
payment_gift_card_destroy_html: deleted a payment gift card
|
7
|
+
payment_gift_card_update_html: updated %{name}
|
8
|
+
fields:
|
9
|
+
amount: Amount
|
10
|
+
balance: Balance
|
11
|
+
expires_on: Expires on
|
12
|
+
from: From
|
13
|
+
message: Message
|
14
|
+
notify: Notify Recipient
|
15
|
+
number: Number
|
16
|
+
order_id: Order ID
|
17
|
+
redeemed_at: Redeemed At
|
18
|
+
recipient: Recipient
|
19
|
+
token: Token
|
20
|
+
used: Used
|
21
|
+
orders:
|
22
|
+
tenders:
|
23
|
+
gift_card:
|
24
|
+
title: Gift Card
|
25
|
+
payment_gift_cards:
|
26
|
+
cards:
|
27
|
+
redemptions:
|
28
|
+
button: View All Redemptions
|
29
|
+
empty: There are no redemptions for this gift card yet.
|
30
|
+
title: Redemptions
|
31
|
+
edit:
|
32
|
+
button: Save Gift Card
|
33
|
+
title: Editing %{name}
|
34
|
+
gift_card: Gift Card
|
35
|
+
index:
|
36
|
+
button: Add Gift Card
|
37
|
+
title: Gift Cards
|
38
|
+
export_redemptions: Export Redemptions
|
39
|
+
new:
|
40
|
+
button: Create Gift Card
|
41
|
+
title: New Gift Card
|
42
|
+
redemptions:
|
43
|
+
export_button: Create Export
|
44
|
+
redemption: Redemption
|
45
|
+
title: Gift Card Redemptions
|
46
|
+
view_order: View Order
|
47
|
+
shared:
|
48
|
+
primary_nav:
|
49
|
+
gift_cards: Gift Cards
|
50
|
+
gift_cards:
|
51
|
+
capture: Gift cards are captured on authorization.
|
52
|
+
credit: "%{amount} added to gift card %{number}"
|
53
|
+
debit: "%{amount} deducted from gift card %{number}"
|
54
|
+
insufficient_funds: This gift card doesn't not enough balance.
|
55
|
+
payment_gift_card:
|
56
|
+
name: Gift Card %{token}
|
57
|
+
storefront:
|
58
|
+
email:
|
59
|
+
gift_card_created:
|
60
|
+
heading: You've Got a Gift Certificate!
|
61
|
+
how_to_redeem: To redeem your gift certificate, enter code %{token} at checkout. Enjoy!
|
62
|
+
message_html: has purchased a gift certificate for you to use at %{link} in the amount of %{amount}.
|
63
|
+
says: 'says:'
|
64
|
+
subject: You've Got a Gift Certificate!
|
65
|
+
gift_cards:
|
66
|
+
applied_to_order: "%{amount} will be applied to your order."
|
67
|
+
apply_gift_card: Apply
|
68
|
+
balance: Your gift card balance is %{amount}.
|
69
|
+
check_balance: Check Your Gift Card Balance
|
70
|
+
email_to_recipient: We will email the digital gift card to the recipient.
|
71
|
+
enter_gift_card_prompt: Enter a gift card number
|
72
|
+
gift_card: Gift Card
|
73
|
+
gift_card_number: Gift Card Number
|
74
|
+
message_to_recipient: Message to Recipient
|
75
|
+
place_order: Click the Place Order button below to complete your order.
|
76
|
+
recipients_email: Recipient's Email
|
77
|
+
senders_email: Your Name
|
78
|
+
tender_required: You must submit another payment method for %{amount}.
|
79
|
+
orders:
|
80
|
+
tenders:
|
81
|
+
gift_card:
|
82
|
+
title: Gift Card
|