workarea-zipco 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintrc.json +35 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  4. data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  6. data/.github/workflows/ci.yml +64 -0
  7. data/.gitignore +23 -0
  8. data/.rubocop.yml +2 -0
  9. data/.stylelintrc.json +8 -0
  10. data/CHANGELOG.md +17 -0
  11. data/Gemfile +17 -0
  12. data/README.md +51 -0
  13. data/Rakefile +59 -0
  14. data/app/assets/images/zipco/.keep +0 -0
  15. data/app/assets/stylesheets/workarea/storefront/zipco/components/_zipco_icon.scss +7 -0
  16. data/app/controllers/storefront/checkout/place_order_controller.decorator +11 -0
  17. data/app/controllers/storefront/zipco_controller.rb +96 -0
  18. data/app/controllers/storefront/zipco_landing_controller.rb +6 -0
  19. data/app/helpers/.keep +0 -0
  20. data/app/mailers/.keep +0 -0
  21. data/app/models/checkout.decorator +33 -0
  22. data/app/models/workarea/order.decorator +52 -0
  23. data/app/models/workarea/order/status/zip_referred.rb +13 -0
  24. data/app/models/workarea/payment.decorator +30 -0
  25. data/app/models/workarea/payment/authorize/zipco.rb +66 -0
  26. data/app/models/workarea/payment/capture/zipco.rb +58 -0
  27. data/app/models/workarea/payment/purchase/zipco.rb +66 -0
  28. data/app/models/workarea/payment/refund/zipco.rb +59 -0
  29. data/app/models/workarea/payment/tender/zipco.rb +13 -0
  30. data/app/models/workarea/search/admin/admin.decorator +7 -0
  31. data/app/services/workarea/zipco/checkout.rb +48 -0
  32. data/app/services/workarea/zipco/order.rb +188 -0
  33. data/app/services/workarea/zipco/setup.rb +37 -0
  34. data/app/view_models/workarea/storefront/checkout/payment_view_model.decorator +17 -0
  35. data/app/view_models/workarea/storefront/order_view_model.decorator +11 -0
  36. data/app/view_models/workarea/storefront/zipco_view_model.rb +18 -0
  37. data/app/views/workarea/admin/orders/tenders/_zipco.html.haml +4 -0
  38. data/app/views/workarea/storefront/checkouts/_zipco_payment.html.haml +10 -0
  39. data/app/views/workarea/storefront/order_mailer/tenders/_zipco.html.haml +4 -0
  40. data/app/views/workarea/storefront/order_mailer/tenders/_zipco.text.erb +1 -0
  41. data/app/views/workarea/storefront/orders/_zipco_order_message.html.haml +2 -0
  42. data/app/views/workarea/storefront/orders/tenders/_zipco.html.haml +6 -0
  43. data/app/views/workarea/storefront/zipco/_zipco_tagline.html.haml +4 -0
  44. data/app/views/workarea/storefront/zipco_landing/show.html.haml +4 -0
  45. data/bin/rails +25 -0
  46. data/config/initializers/appends.rb +24 -0
  47. data/config/initializers/workarea.rb +15 -0
  48. data/config/locales/en.yml +38 -0
  49. data/config/routes.rb +5 -0
  50. data/lib/workarea/zipco.rb +48 -0
  51. data/lib/workarea/zipco/bogus_gateway.rb +160 -0
  52. data/lib/workarea/zipco/engine.rb +10 -0
  53. data/lib/workarea/zipco/gateway.rb +113 -0
  54. data/lib/workarea/zipco/response.rb +29 -0
  55. data/lib/workarea/zipco/version.rb +5 -0
  56. data/test/dummy/.ruby-version +1 -0
  57. data/test/dummy/Rakefile +6 -0
  58. data/test/dummy/app/assets/config/manifest.js +3 -0
  59. data/test/dummy/app/assets/images/.keep +0 -0
  60. data/test/dummy/app/assets/javascripts/application.js +14 -0
  61. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  62. data/test/dummy/app/controllers/application_controller.rb +2 -0
  63. data/test/dummy/app/controllers/concerns/.keep +0 -0
  64. data/test/dummy/app/helpers/application_helper.rb +2 -0
  65. data/test/dummy/app/jobs/application_job.rb +2 -0
  66. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  67. data/test/dummy/app/models/concerns/.keep +0 -0
  68. data/test/dummy/app/views/layouts/application.html.erb +15 -0
  69. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  70. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  71. data/test/dummy/bin/bundle +3 -0
  72. data/test/dummy/bin/rails +4 -0
  73. data/test/dummy/bin/rake +4 -0
  74. data/test/dummy/bin/setup +28 -0
  75. data/test/dummy/bin/update +28 -0
  76. data/test/dummy/bin/yarn +11 -0
  77. data/test/dummy/config.ru +5 -0
  78. data/test/dummy/config/application.rb +34 -0
  79. data/test/dummy/config/boot.rb +5 -0
  80. data/test/dummy/config/environment.rb +5 -0
  81. data/test/dummy/config/environments/development.rb +52 -0
  82. data/test/dummy/config/environments/production.rb +83 -0
  83. data/test/dummy/config/environments/test.rb +45 -0
  84. data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
  85. data/test/dummy/config/initializers/assets.rb +14 -0
  86. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  87. data/test/dummy/config/initializers/content_security_policy.rb +25 -0
  88. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  89. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  90. data/test/dummy/config/initializers/inflections.rb +16 -0
  91. data/test/dummy/config/initializers/mime_types.rb +4 -0
  92. data/test/dummy/config/initializers/workarea.rb +5 -0
  93. data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
  94. data/test/dummy/config/locales/en.yml +33 -0
  95. data/test/dummy/config/puma.rb +34 -0
  96. data/test/dummy/config/routes.rb +5 -0
  97. data/test/dummy/config/spring.rb +6 -0
  98. data/test/dummy/db/seeds.rb +2 -0
  99. data/test/dummy/lib/assets/.keep +0 -0
  100. data/test/dummy/log/.keep +0 -0
  101. data/test/integration/workarea/storefront/zipco_integration_test.rb +250 -0
  102. data/test/models/workarea/order/zipco_queries_test.rb +35 -0
  103. data/test/models/workarea/payment/zipco_payment_integration_test.rb +89 -0
  104. data/test/services/workarea/zipco/checkout_test.rb +43 -0
  105. data/test/services/workarea/zipco/order_test.rb +102 -0
  106. data/test/services/workarea/zipco/setup_test.rb +65 -0
  107. data/test/teaspoon_env.rb +6 -0
  108. data/test/test_helper.rb +10 -0
  109. data/test/view_models/workarea/storefront/zipco_view_model_test.rb +55 -0
  110. data/workarea-zipco.gemspec +19 -0
  111. metadata +167 -0
@@ -0,0 +1,6 @@
1
+ module Workarea
2
+ class Storefront::ZipcoLandingController < Storefront::ApplicationController
3
+ def show
4
+ end
5
+ end
6
+ end
File without changes
File without changes
@@ -0,0 +1,33 @@
1
+ module Workarea
2
+ decorate Checkout, with: :zipco do
3
+ # handles checking out a zipco refered order
4
+ # inventory is captured but no funds are captured.
5
+ #
6
+ # @return [Boolean]
7
+ #
8
+ def handle_zipco_referred
9
+ return false unless complete?
10
+ return false unless shippable?
11
+ return false unless payable?
12
+
13
+ inventory.purchase
14
+ return false unless inventory.captured?
15
+
16
+ true
17
+ end
18
+
19
+ # handles checking out a zipco order that was referred but
20
+ # is now approved. Funds are captured and checkout side
21
+ # effects are ran.
22
+ #
23
+ # @return [Boolean]
24
+ #
25
+ def handle_zipco_approved_referred
26
+ payment_collection.purchase
27
+ result = order.place
28
+ place_order_side_effects if result
29
+
30
+ result
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ module Workarea
2
+ decorate Order, with: :zipco do
3
+ decorated do
4
+ field :zipco_order_id, type: String
5
+ field :zipco_referred_at, type: Time
6
+ scope :not_referred, -> { where(:zipco_referred_at => nil) }
7
+
8
+
9
+ index({ zipco_order_id: 1}, { background: true })
10
+ index({ zipco_referred_at: 1}, { background: true })
11
+ end
12
+
13
+ class_methods do
14
+ # Overriding method from core/models/order/queries.rb module
15
+ def need_reminding
16
+ super.where(zipco_referred_at: nil)
17
+ end
18
+
19
+ def find_current(params = {})
20
+ if params[:id].present?
21
+ Order.not_placed.not_referred.find(params[:id].to_s)
22
+ elsif params[:user_id].present?
23
+ Order.recently_updated.not_placed.not_referred.find_by(params.slice(:user_id))
24
+ else
25
+ Order.new(user_id: params[:user_id])
26
+ end
27
+ rescue Mongoid::Errors::DocumentNotFound
28
+ Order.new(user_id: params[:user_id])
29
+ end
30
+ end
31
+
32
+ def clear_zipco!
33
+ self.zipco_order_id = nil
34
+ self.zipco_referred_at = nil
35
+ save!
36
+ end
37
+
38
+ def zipco_referred?
39
+ !!zipco_referred_at
40
+ end
41
+
42
+ def set_zipco_referred_at!
43
+ update!(
44
+ zipco_referred_at: Time.current
45
+ )
46
+ end
47
+
48
+ def abandoned?
49
+ super && !zipco_referred?
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,13 @@
1
+ module Workarea
2
+ class Order
3
+ module Status
4
+ class ZipReferred
5
+ include StatusCalculator::Status
6
+
7
+ def in_status?
8
+ !order.placed? && order.zipco_referred? && !order.canceled?
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ module Workarea
2
+ decorate Payment, with: :zipco do
3
+ decorated do
4
+ embeds_one :zipco, class_name: 'Workarea::Payment::Tender::Zipco'
5
+ end
6
+
7
+ def zipco?
8
+ zipco.present?
9
+ end
10
+
11
+ def set_zipco(attrs)
12
+ build_zipco unless zipco?
13
+ zipco.attributes = attrs.slice(
14
+ :token
15
+ )
16
+
17
+ save
18
+ end
19
+
20
+ def clear_zipco!
21
+ self.zipco = nil
22
+ save!
23
+ end
24
+
25
+ def set_credit_card(*)
26
+ self.zipco = nil
27
+ super
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,66 @@
1
+ module Workarea
2
+ class Payment
3
+ module Authorize
4
+ class Zipco
5
+ include OperationImplementation
6
+ include CreditCardOperation
7
+
8
+ def complete!
9
+ response = authorize
10
+ if response.success?
11
+ transaction.response = ActiveMerchant::Billing::Response.new(
12
+ true,
13
+ I18n.t(
14
+ 'workarea.zipco.authorize',
15
+ amount: transaction.amount
16
+ ),
17
+ response.body
18
+ )
19
+ else
20
+ transaction.response = ActiveMerchant::Billing::Response.new(
21
+ false,
22
+ I18n.t('workarea.zipco.authorize_failure'),
23
+ response.body.present? ? response.body : {}
24
+ )
25
+ end
26
+ end
27
+
28
+ def cancel!
29
+ # No op - no cancel functionality available.
30
+ end
31
+
32
+ private
33
+
34
+ def gateway
35
+ Workarea::Zipco.gateway
36
+ end
37
+
38
+ def transaction_attrs
39
+ {
40
+ authority: {
41
+ type: "checkout_id",
42
+ value: tender.token
43
+ },
44
+ amount: transaction.amount.to_s,
45
+ currency: transaction.amount.currency.iso_code,
46
+ capture: false
47
+ }
48
+ end
49
+
50
+ def authorize
51
+ request_id = SecureRandom.uuid
52
+ auth_response = response(request_id)
53
+ if Workarea::Zipco::RETRY_ERROR_STATUSES.include? auth_response.status
54
+ return response(request_id)
55
+ end
56
+
57
+ auth_response
58
+ end
59
+
60
+ def response(request_id)
61
+ gateway.authorize(transaction_attrs, request_id)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,58 @@
1
+ module Workarea
2
+ class Payment
3
+ class Capture
4
+ class Zipco
5
+ include OperationImplementation
6
+ include CreditCardOperation
7
+
8
+ def complete!
9
+ response = capture
10
+ if response.success?
11
+ transaction.response = ActiveMerchant::Billing::Response.new(
12
+ true,
13
+ I18n.t(
14
+ 'workarea.zipco.capture',
15
+ amount: transaction.amount
16
+ ),
17
+ response.body
18
+ )
19
+ else
20
+ transaction.response = ActiveMerchant::Billing::Response.new(
21
+ false,
22
+ I18n.t('workarea.zipco.capture_failure'),
23
+ response.body.present? ? response.body : {}
24
+ )
25
+ end
26
+ end
27
+
28
+ def cancel!
29
+ # No op - no cancel functionality available.
30
+ end
31
+
32
+ private
33
+
34
+ def charge_id
35
+ transaction.reference.response.params["id"]
36
+ end
37
+
38
+ def gateway
39
+ Workarea::Zipco.gateway
40
+ end
41
+
42
+ def refund
43
+ request_id = SecureRandom.uuid
44
+ capture_response = response(request_id)
45
+ if Workarea::Zipco::RETRY_ERROR_STATUSES.include? capture_response.status
46
+ return response(request_id)
47
+ end
48
+
49
+ capture_response
50
+ end
51
+
52
+ def response(request_id)
53
+ gateway.capture(charge_id, transaction.amount, request_id)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,66 @@
1
+ module Workarea
2
+ class Payment
3
+ module Purchase
4
+ class Zipco
5
+ include OperationImplementation
6
+ include CreditCardOperation
7
+
8
+ def complete!
9
+ response = purchase
10
+ if response.success?
11
+ transaction.response = ActiveMerchant::Billing::Response.new(
12
+ true,
13
+ I18n.t(
14
+ 'workarea.zipco.purchase',
15
+ amount: transaction.amount
16
+ ),
17
+ response.body
18
+ )
19
+ else
20
+ transaction.response = ActiveMerchant::Billing::Response.new(
21
+ false,
22
+ I18n.t('workarea.zipco.purchase_failure'),
23
+ response.body.present? ? response.body : {}
24
+ )
25
+ end
26
+ end
27
+
28
+ def cancel!
29
+ # No op - no cancel functionality available.
30
+ end
31
+
32
+ private
33
+
34
+ def gateway
35
+ Workarea::Zipco.gateway
36
+ end
37
+
38
+ def transaction_attrs
39
+ {
40
+ authority: {
41
+ type: "checkout_id",
42
+ value: tender.token
43
+ },
44
+ amount: transaction.amount.to_s,
45
+ currency: transaction.amount.currency.iso_code,
46
+ capture: true
47
+ }
48
+ end
49
+
50
+ def purchase
51
+ request_id = SecureRandom.uuid
52
+ purchase_response = response(request_id)
53
+ if Workarea::Zipco::RETRY_ERROR_STATUSES.include? purchase_response.status
54
+ return response(request_id)
55
+ end
56
+
57
+ purchase_response
58
+ end
59
+
60
+ def response(request_id)
61
+ gateway.purchase(transaction_attrs, request_id)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,59 @@
1
+ module Workarea
2
+ class Payment
3
+ class Refund
4
+ class Zipco
5
+ include OperationImplementation
6
+ include CreditCardOperation
7
+
8
+ def complete!
9
+ response = refund
10
+
11
+ if response.success?
12
+ transaction.response = ActiveMerchant::Billing::Response.new(
13
+ true,
14
+ I18n.t(
15
+ 'workarea.zipco.refund',
16
+ amount: transaction.amount
17
+ ),
18
+ response.body
19
+ )
20
+ else
21
+ transaction.response = ActiveMerchant::Billing::Response.new(
22
+ false,
23
+ I18n.t('workarea.zipco.refund_failure'),
24
+ response.body.presence
25
+ )
26
+ end
27
+ end
28
+
29
+ def cancel!
30
+ # No op - no cancel functionality available.
31
+ end
32
+
33
+ private
34
+
35
+ def charge_id
36
+ transaction.reference.response.params["id"]
37
+ end
38
+
39
+ def gateway
40
+ Workarea::Zipco.gateway
41
+ end
42
+
43
+ def refund
44
+ request_id = SecureRandom.uuid
45
+ refund_response = response(request_id)
46
+ if Workarea::Zipco::RETRY_ERROR_STATUSES.include? refund_response.status
47
+ return response(request_id)
48
+ end
49
+
50
+ refund_response
51
+ end
52
+
53
+ def response(request_id)
54
+ gateway.refund(charge_id, transaction.amount, request_id)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,13 @@
1
+ module Workarea
2
+ class Payment
3
+ class Tender
4
+ class Zipco < Tender
5
+ field :token, type: String
6
+
7
+ def slug
8
+ :zipco
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ module Workarea
2
+ decorate Search::Admin::Order, with: :zipco do
3
+ def should_be_indexed?
4
+ model.placed? || model.zipco_referred?
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,48 @@
1
+ module Workarea
2
+ module Zipco
3
+ class Checkout
4
+ attr_reader :checkout, :order, :options, :user
5
+
6
+ # @param ::Workarea::Order
7
+ def initialize(checkout, user, options = {})
8
+ @checkout = checkout
9
+ @user = user
10
+ @options = options
11
+ @order = Workarea::Order.where(zipco_order_id: zipco_order_id).first
12
+ end
13
+
14
+ def complete
15
+ approved_referred_order = result == "approved" && order.zipco_referred?
16
+
17
+ if result == "referred"
18
+ order.set_zipco_referred_at!
19
+ else
20
+ order.update_attributes(zipco_referred_at: nil)
21
+ end
22
+
23
+ order.user_id = user.try(:id)
24
+
25
+ Workarea::Pricing.perform(order, checkout.shipping)
26
+ checkout.payment.adjust_tender_amounts(order.total_price)
27
+
28
+ if order.zipco_referred?
29
+ checkout.handle_zipco_referred
30
+ elsif approved_referred_order
31
+ checkout.handle_zipco_approved_referred
32
+ else
33
+ checkout.place_order
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def result
40
+ options[:result]
41
+ end
42
+
43
+ def zipco_order_id
44
+ options[:checkoutId]
45
+ end
46
+ end
47
+ end
48
+ end