solidus-returnly 0.12.0 → 0.13.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c65b26145ed509d151c337ef349bb1573cba5703e80b646dfa874ac6566c66a2
4
- data.tar.gz: ea4067aaaf9ebd7b97927c2e9c586f4398654e4388009f2c5f226ceaa9b70979
3
+ metadata.gz: 49a3132d794c84523c95f735e48248ec39f4df2ed08650dfdc4770897b7478e4
4
+ data.tar.gz: ed416b5e72b84d710baffc1bba8103282ed3637040ceb093622414f855c50fdc
5
5
  SHA512:
6
- metadata.gz: 8be45554263a53fd0e88c8a9255d437861815e01cc174bc3f0d0b8476d71e4cca99068a493257b7e6297c60cd9319bc3488b1457d2d41d24cf2f57ec12940de8
7
- data.tar.gz: b9322a7879716d05367cce5609737af8f628a43bb34412d0b9691ca3487ce2862a8aa95531b345d1db470616f6d262d627d6f5cd11a9323f6d68891f47bf34a5
6
+ metadata.gz: f73a7bcf01193de619aac70ded0b6d7b5ac85968d7e75de241d0e8d243922e1dddea96bc240207bfdee8a39ebd867291f8af176a191220348bc4deaa2e0990aa
7
+ data.tar.gz: 00fe2aac2e84fcd8f278547aadf930f112f1dc58ac20ee979c54dbe257553e58c12aa2d3602448054bfcc0af7ecdfa0fecb62630aab4a781faf7cafcfb72b2aa
data/README.md CHANGED
@@ -101,11 +101,24 @@ Response:
101
101
  "refundable_shipping_amount": "{money}",
102
102
  "refundable_shipping_tax_amount": "{money}",
103
103
  "max_refundable_amount": "{money}",
104
- "refunds_by_payment_method": [
104
+ "transactions": [
105
105
  {
106
- "code": "Credit Card",
106
+ "id": "{refund tx id}",
107
107
  "amount": "{money}",
108
- "original_transaction_id": 1
108
+ "status": "PENDING",
109
+ "type": "REFUND",
110
+ "gateway": "{gateway}",
111
+ "is_online": true,
112
+ "is_test": true,
113
+ "payment_details": {
114
+ "avs_result_code": "{code}",
115
+ "cvv_result_code": "{code}",
116
+ "credit_card_number": "{number}",
117
+ "credit_card_company": "visa",
118
+ "gift_card_id": "{voucher_id}",
119
+ "gift_card_code": "{voucher_code}"
120
+ },
121
+ "created_at": "{date}"
109
122
  }
110
123
  ]
111
124
  }
@@ -148,12 +161,27 @@ Response:
148
161
  "units": 2
149
162
  },
150
163
  ],
151
- "transactions": [
164
+ "transactions": [
152
165
  {
153
166
  "id": "{refund tx id}",
154
- "amount": "{money}"
167
+ "amount": "{money}",
168
+ "status": "PENDING",
169
+ "type": "REFUND",
170
+ "gateway": "{gateway}",
171
+ "is_online": true,
172
+ "is_test": true,
173
+ "payment_details": {
174
+ "avs_result_code": "{code}",
175
+ "cvv_result_code": "{code}",
176
+ "credit_card_number": "{number}",
177
+ "credit_card_company": "visa",
178
+ "gift_card_id": "{voucher_id}",
179
+ "gift_card_code": "{voucher_code}"
180
+ }
155
181
  }
156
182
  ],
183
+ "created_at": "{date}",
184
+ "updated_at": "{date}",
157
185
  "refund_note": "comment text",
158
186
  }
159
187
  ```
@@ -3,8 +3,9 @@ class RefundPayments
3
3
 
4
4
  include RefundMethods
5
5
 
6
- def initialize(order)
6
+ def initialize(order, gift_card)
7
7
  @order = order
8
+ @gift_card = gift_card
8
9
  end
9
10
 
10
11
  def perform!(payment_amount)
@@ -17,9 +18,15 @@ class RefundPayments
17
18
  payment_amount -= allowed_amount
18
19
 
19
20
  payments << {
20
- code: payment.source_type.constantize.model_name.human,
21
- amount: allowed_amount.to_f,
22
- original_transaction_id: ''
21
+ id: payment.id.to_s,
22
+ amount: allowed_amount.to_s,
23
+ status: 'PENDING',
24
+ type: 'REFUND',
25
+ gateway: payment.payment_method.type.demodulize,
26
+ is_online: true,
27
+ is_test: !Rails.env.match?(/production/),
28
+ payment_details: transaction_payment_details(payment),
29
+ created_at: Time.zone.now.iso8601(3)
23
30
  }
24
31
  end
25
32
  end
@@ -30,4 +37,23 @@ class RefundPayments
30
37
  payments = payments.select { |p| eligible_refund_methods.include? p.payment_method.class }
31
38
  payments.sort_by { |p| eligible_refund_methods.index(p.payment_method.class) }
32
39
  end
40
+
41
+ def transaction_payment_details(payment)
42
+ details = {}
43
+
44
+ details[:avs_result_code] = payment.avs_response if payment.avs_response.present?
45
+ details[:cvv_result_code] = payment.cvv_response_code if payment.cvv_response_code.present?
46
+
47
+ source = payment.source
48
+
49
+ if source.respond_to?(:number) || source.respond_to?(:last_digits)
50
+ details[:credit_card_number] = source.number || source.last_digits if source.number.present? || source.last_digits.present?
51
+ details[:credit_card_company] = source.brand if source.brand.present?
52
+ end
53
+
54
+ details[:gift_card_id] = @gift_card.id if @gift_card.id.present?
55
+ details[:gift_card_code] = @gift_card.code if @gift_card.code.present?
56
+
57
+ details
58
+ end
33
59
  end
data/lib/returnly.rb CHANGED
@@ -9,6 +9,7 @@ require 'returnly/builders/return_item'
9
9
  require 'returnly/refund_calculator'
10
10
 
11
11
  require 'returnly/version'
12
+ require 'returnly/gift_card'
12
13
  require 'returnly/refund/amount_calculator'
13
14
  require 'returnly/refund/return_item_restock_policy'
14
15
  require 'returnly/services/create_reimbursement'
@@ -5,7 +5,9 @@ module Returnly
5
5
  :return_item_restock_policy,
6
6
  :refunder,
7
7
  :refund_calculator,
8
- :refund_presenter
8
+ :refund_presenter,
9
+ :gift_card,
10
+ :git_card_estimate
9
11
  end
10
12
 
11
13
  def self.configure(&block)
@@ -0,0 +1,21 @@
1
+ module Returnly
2
+ NilGiftCard = Struct.new(:refund) do
3
+ def code
4
+ nil
5
+ end
6
+
7
+ def id
8
+ nil
9
+ end
10
+ end
11
+
12
+ NilGiftCardEstimate = Struct.new(:order) do
13
+ def code
14
+ nil
15
+ end
16
+
17
+ def id
18
+ nil
19
+ end
20
+ end
21
+ end
@@ -33,6 +33,10 @@ module Returnly
33
33
  order.all_adjustments.where(source_type: 'Spree::TaxRate', adjustable_type: 'Spree::Shipment').sum(&:amount).to_d.round(2, :down)
34
34
  end
35
35
 
36
+ def gift_card
37
+ @gift_card ||= self.class.gift_card_estimate_class.new(order)
38
+ end
39
+
36
40
  protected
37
41
 
38
42
  def available_return_items
@@ -1,71 +1,115 @@
1
1
  module Returnly
2
2
  class RefundPresenter
3
+ class << self
4
+ def present_refund(refunder)
5
+ customer_return = refunder.customer_return
6
+ refund = refunder.order.reload.refunds.last
3
7
 
4
- def self.present_estimate(calculator)
5
- sub_total = Money.new 0
6
- tax = Money.new 0
8
+ {
9
+ refund_id: refund.try(:id).try(:to_s),
10
+ user_id: refunder.order.user_id,
11
+ line_items: customer_return.return_items.group_by { |ri| ri.inventory_unit.line_item.id }.map do |_, return_items|
12
+ first_return_item = return_items.first
13
+ {
14
+ refund_line_item_id: first_return_item.id.to_s,
15
+ order_line_item_id: first_return_item.inventory_unit.line_item.id.to_s,
16
+ units: return_items.size,
17
+ restock: first_return_item.resellable
18
+ }
19
+ end,
20
+ transactions: refunder.reimbursement.refunds.map do |refund|
21
+ {
22
+ id: refund.transaction_id,
23
+ amount: refund.amount.to_s,
24
+ status: transaction_status(refund.payment),
25
+ type: 'REFUND',
26
+ gateway: refund.payment.payment_method.type.demodulize,
27
+ is_online: true,
28
+ is_test: !Rails.env.match?(/production/),
29
+ payment_details: transaction_payment_details(refund.payment, refunder.gift_card_class.new(refund)),
30
+ created_at: refund.created_at.iso8601(3),
31
+ updated_at: refund.updated_at.iso8601(3)
32
+ }
33
+ end,
34
+ created_at: refund.try(:created_at).try(:iso8601, 3),
35
+ updated_at: refund.try(:updated_at).try(:iso8601, 3)
36
+ }
37
+ end
38
+
39
+ def present_estimate(calculator)
40
+ sub_total = Money.new 0
41
+ tax = Money.new 0
7
42
 
8
- calculator.line_items_return_items.values.flatten.each do |return_item|
9
- sub_total += Money.from_amount return_item.inventory_unit.line_item.price
10
- tax += Money.from_amount calculator.line_item_tax(return_item.inventory_unit.line_item)
43
+ calculator.line_items_return_items.values.flatten.each do |return_item|
44
+ sub_total += Money.from_amount return_item.inventory_unit.line_item.price
45
+ tax += Money.from_amount calculator.line_item_tax(return_item.inventory_unit.line_item)
46
+ end
47
+
48
+ discount = Money.from_amount(calculator.discount)
49
+ total_refund_amount = sub_total + tax - (discount * -1) # discount is negative, so we multiply it by -1 to make it positive for subtraction
50
+ shipping_tax = calculator.shipping_tax
51
+ {
52
+ product_amount: sub_total.to_s,
53
+ tax_amount: tax.to_s,
54
+ discount_amount: (discount * -1).to_s,
55
+ total_refund_amount: total_refund_amount.to_s,
56
+ refundable_shipping_amount: Money.from_amount(calculator.order.shipment_total).to_s,
57
+ refundable_shipping_tax_amount: Money.from_amount(shipping_tax).to_s,
58
+ max_refundable_amount: Money.from_amount(calculator.order.total - calculator.order.refunds.reload.sum(&:amount)).to_s,
59
+ transactions: transactions_for_estimate(
60
+ calculator.order,
61
+ calculator.gift_card,
62
+ total_refund_amount.to_d + calculator.order.shipment_total + shipping_tax
63
+ )
64
+ }
11
65
  end
12
66
 
13
- discount = Money.from_amount(calculator.discount)
14
- total_refund_amount = sub_total + tax - (discount * -1) # discount is negative, so we multiply it by -1 to make it positive for subtraction
15
- shipping_tax = calculator.shipping_tax
16
- {
17
- product_amount: sub_total.to_f,
18
- tax_amount: tax.to_f,
19
- discount_amount: discount.to_f,
20
- total_refund_amount: total_refund_amount.to_f,
21
- refundable_shipping_amount: calculator.order.shipment_total.to_f,
22
- refundable_shipping_tax_amount: shipping_tax.to_f,
23
- max_refundable_amount: (calculator.order.total - calculator.order.refunds.reload.sum(&:amount)).to_f,
24
- refunds_by_payment_method: refunds_by_payment(calculator.order, total_refund_amount.to_d + calculator.order.shipment_total + shipping_tax)
25
- }
26
- end
67
+ def present_refund_with_zero_amount(refunder)
68
+ {
69
+ refund_id: '1',
70
+ line_items: refunder.line_items.map do |line_item|
71
+ {
72
+ refund_line_item_id: '1',
73
+ order_line_item_id: line_item[:order_line_item_id].to_s,
74
+ units: line_item[:units].to_i,
75
+ restock: line_item[:restock].match?(/true/)
76
+ }
77
+ end,
78
+ transactions: [],
79
+ created_at: Time.zone.now.iso8601(3)
80
+ }
81
+ end
82
+
83
+ private
84
+
85
+ def transaction_status(payment)
86
+ return 'SUCCESS' if payment.completed?
87
+ return 'FAILURE' if payment.failed? || payment.invalid?
88
+ 'PENDING'
89
+ end
27
90
 
28
- def self.present_refund(refunder)
29
- customer_return = refunder.customer_return
91
+ def transaction_payment_details(payment, gift_card)
92
+ details = {}
30
93
 
31
- {
32
- refund_id: refunder.order.reload.refunds.last.try(:id).try(:to_s),
33
- line_items: customer_return.return_items.group_by { |ri| ri.inventory_unit.line_item.id }.map do |_, return_items|
34
- first_return_item = return_items.first
35
- {
36
- refund_line_item_id: first_return_item.id.to_s,
37
- order_line_item_id: first_return_item.inventory_unit.line_item.id.to_s,
38
- units: return_items.size,
39
- restock: first_return_item.resellable
40
- }
41
- end,
42
- transactions: refunder.reimbursement.refunds.map do |refund|
43
- {
44
- id: refund.transaction_id,
45
- amount: refund.amount.to_f,
46
- code: refund.payment.source_type.constantize.model_name.human
47
- }
94
+ details[:avs_result_code] = payment.avs_response if payment.avs_response.present?
95
+ details[:cvv_result_code] = payment.cvv_response_code if payment.cvv_response_code.present?
96
+
97
+ source = payment.source
98
+
99
+ if source.respond_to?(:number) || source.respond_to?(:last_digits)
100
+ details[:credit_card_number] = source.number || source.last_digits if source.number.present? || source.last_digits.present?
101
+ details[:credit_card_company] = source.brand if source.brand.present?
48
102
  end
49
- }
50
- end
51
103
 
52
- def self.present_refund_with_zero_amount(refunder)
53
- {
54
- refund_id: '',
55
- line_items: refunder.line_items.map do |line_item|
56
- {
57
- refund_line_item_id: '',
58
- order_line_item_id: line_item[:order_line_item_id].to_s,
59
- units: line_item[:units].to_i,
60
- restock: !!(line_item[:restock].to_s =~ /true/)
61
- }
62
- end,
63
- transactions: []
64
- }
65
- end
104
+ details[:gift_card_id] = gift_card.id if gift_card.id.present?
105
+ details[:gift_card_code] = gift_card.code if gift_card.code.present?
66
106
 
67
- private_class_method def self.refunds_by_payment(order, payment_amount)
68
- ::RefundPayments.new(order).perform!(payment_amount)
69
- end
107
+ details
108
+ end
109
+
110
+ def transactions_for_estimate(order, gift_card, payment_amount)
111
+ ::RefundPayments.new(order, gift_card).perform!(payment_amount)
112
+ end
113
+ end
70
114
  end
71
115
  end
@@ -24,5 +24,13 @@ module Returnly
24
24
  def refund_presenter_class
25
25
  Returnly.refund_presenter || Returnly::RefundPresenter
26
26
  end
27
+
28
+ def gift_card_class
29
+ Returnly.gift_card || Returnly::NilGiftCard
30
+ end
31
+
32
+ def gift_card_estimate_class
33
+ Returnly.git_card_estimate || Returnly::NilGiftCardEstimate
34
+ end
27
35
  end
28
36
  end
@@ -1,5 +1,5 @@
1
1
  module Returnly
2
- VERSION = '0.12.0'
2
+ VERSION = '0.13.0'
3
3
 
4
4
  def platform_version
5
5
  defined?(Solidus)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus-returnly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Returnly Technologies, Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-13 00:00:00.000000000 Z
11
+ date: 2019-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: solidus
@@ -387,6 +387,7 @@ files:
387
387
  - lib/returnly/discounts/order.rb
388
388
  - lib/returnly/engine.rb
389
389
  - lib/returnly/factories.rb
390
+ - lib/returnly/gift_card.rb
390
391
  - lib/returnly/refund/amount_calculator.rb
391
392
  - lib/returnly/refund/return_item_restock_policy.rb
392
393
  - lib/returnly/refund_calculator.rb