workarea-zipco 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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