solidus-returnly 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 770f17457a8c4b1ef1e54ea9693055061f3dc437
4
- data.tar.gz: cf0ff331d9a612981c085b4e831dd6cd24c6313f
3
+ metadata.gz: 2655c6ac9fa6c07fec8b5ab27a213bdb73a326ee
4
+ data.tar.gz: d8503946bcf7f9c1d03e6bf06354ee8c1dbbf165
5
5
  SHA512:
6
- metadata.gz: f21ab272464d7d9727094bde59dc4b386e644d0f0a0b94e720f6383179dec22f0175188fa844e2cbd905e4aaf052fa229159173b5e4ff0647c07b5c6dbe48b5a
7
- data.tar.gz: ed2e2506d1ae775b53daf470eb1e1524a7801a3172d263de89b83c7b3ac7a32b8bd1acc1fb22f20f08205ab6425fef0207d2ef04e47351c120e1824002e6cbb9
6
+ metadata.gz: 759e8a79160f9d73fa6a1f5ccc9e8e83b6a58bc588b36e74c42faf9acc7fd5d9d8da3c027a1bdf92662833905357d8430448e80aa59d83297be0ee32481a034a
7
+ data.tar.gz: d2424d70d40a0e06d8791b380d9a79f62aed777d4d2bc87163de7359cef2ab6c3babb548b4a6e5384a941c5199aa5f5f1b80a5a8bd1bb41b4af6d6ea6826b5f3
data/LICENSE CHANGED
@@ -1,21 +1,26 @@
1
- The MIT License
1
+ Copyright (c) 2017 [name of plugin creator]
2
+ All rights reserved.
2
3
 
3
- Copyright (c) 2017 Returnly Technologies, Inc.
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
4
6
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
11
15
 
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md CHANGED
@@ -1,7 +1,13 @@
1
1
  Solidus Returnly
2
2
  ===============
3
3
 
4
- This gem adds the required apis to allow returnly obtain an estimate, process a return and apply a reimbursement
4
+ This gem adds the required APIs to allow returnly obtain an estimate, process a return and apply a reimbursement
5
+
6
+
7
+ KNOW ISSUES
8
+ -----------
9
+ * Currently the restock feature only supports the order shipping warehouse
10
+ * The API user should have the right to create an order there is no an special permission yet for this api
5
11
 
6
12
  Installation
7
13
  ------------
@@ -9,7 +15,7 @@ Installation
9
15
  Add solidus_returnly to your Gemfile:
10
16
 
11
17
  ```ruby
12
- gem 'solidus-returnly'
18
+ gem 'solidus_returnly'
13
19
  ```
14
20
 
15
21
  Bundle your dependencies and run the installation generator:
@@ -33,7 +39,7 @@ When testing your applications integration with this extension you may use it's
33
39
  Simply add this require statement to your spec_helper:
34
40
 
35
41
  ```ruby
36
- require 'solidus_returnly/factories'
42
+ require 'solidus/returnly/factories'
37
43
  ```
38
44
 
39
45
  Solidus/Spree Sandbox
@@ -63,7 +69,7 @@ API
63
69
 
64
70
  To get an estimate of the return order and taxes
65
71
 
66
- `POST /api/orders/:order_number/refunds/estimate`
72
+ `POST /api/returnly/refunds/:order_number/estimate`
67
73
 
68
74
  Payload:
69
75
  ```json
@@ -103,7 +109,7 @@ To process the return and apply the reimbursement**immediately**
103
109
  you can pass the `restock` parameter on false to prevent the api
104
110
  to immediately change the stock in the default warehouse
105
111
 
106
- `POST /api/orders/:order_number/refunds/estimate`
112
+ `POST /api/returnly/refunds/:order_number`
107
113
 
108
114
  Payload:
109
115
 
@@ -124,7 +130,7 @@ Payload:
124
130
  }
125
131
  ```
126
132
 
127
- Responce:
133
+ Response:
128
134
 
129
135
  ```json
130
136
  {
@@ -149,4 +155,4 @@ Responce:
149
155
  ```
150
156
 
151
157
 
152
- Copyright (c) 2017 Returnly Technologies, Inc
158
+ Copyright (c) 2017 Returnly Technologies, Inc, released under the New BSD License
data/Rakefile CHANGED
@@ -22,6 +22,6 @@ end
22
22
 
23
23
  desc 'Generates a dummy app for testing'
24
24
  task :test_app do
25
- ENV['LIB_NAME'] = 'solidus/returnly'
25
+ ENV['LIB_NAME'] = 'solidus_returnly'
26
26
  Rake::Task['extension:test_app'].invoke
27
27
  end
@@ -0,0 +1,14 @@
1
+ module Spree
2
+ module Api
3
+ module Returnly
4
+ class ApiController < Spree::Api::BaseController
5
+ before_filter :set_headers
6
+
7
+ def set_headers
8
+ response.headers['X-Returnly-Extension-Version'] = Solidus::Returnly::VERSION
9
+ response.headers['X-Returnly-Extension-Platform-Qualifier'] = Spree.solidus_version
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,42 @@
1
+ module Spree
2
+ module Api
3
+ module Returnly
4
+ class RefundsController < ApiController
5
+
6
+ def estimate
7
+ authorize! :create, Order
8
+ render json: Solidus::Returnly::Calculator.process(order, line_items_params)
9
+ end
10
+
11
+ def create
12
+ authorize! :create, Order
13
+
14
+ refunds = Solidus::Returnly::Refunds.new order: order,
15
+ line_items: line_items_params,
16
+ restock: refund_restock_param,
17
+ transactions: transactions_params
18
+ render json: refunds.proceed!
19
+ end
20
+
21
+ private
22
+
23
+ def line_items_params
24
+ params.require(:line_items)
25
+ end
26
+
27
+ def transactions_params
28
+ params.require(:transactions)
29
+ end
30
+
31
+ def refund_restock_param
32
+ params.require(:restock) == 'true'
33
+ end
34
+
35
+ def order
36
+ @order ||= Spree::Order.find_by(number: params[:order_id])
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,13 @@
1
+ module Spree
2
+ module Api
3
+ class ReturnlyVersionController < ApiController
4
+ def index
5
+ render json: {
6
+ extension_version: Solidus::Returly::VERSION,
7
+ platform_version: Solidus::VERSION,
8
+ }
9
+ end
10
+
11
+ end
12
+ end
13
+ end
data/config/routes.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  Spree::Core::Engine.routes.draw do
2
2
  namespace :api, defaults: { format: 'json' } do
3
- post '/orders/:order_id/refunds/estimate', to: 'refunds#estimate'
4
- post '/orders/:order_id/refunds', to: 'refunds#create'
3
+ post '/returnly/refunds/:order_id/estimate', to: 'returnly/refunds#estimate'
4
+ post '/returnly/refunds/:order_id', to: 'returnly/refunds#create'
5
+ get '/returnly/version', to: 'returnly/version#index'
5
6
  end
6
7
  end
@@ -4,15 +4,26 @@ module SolidusReturnly
4
4
  class_option :auto_run_migrations, type: :boolean, default: false
5
5
 
6
6
  def add_javascripts
7
+ append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/solidus_returnly\n"
8
+ append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/solidus_returnly\n"
7
9
  end
8
10
 
9
11
  def add_stylesheets
12
+ inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/solidus_returnly\n", before: /\*\//, verbose: true
13
+ inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/solidus_returnly\n", before: /\*\//, verbose: true
10
14
  end
11
15
 
12
16
  def add_migrations
17
+ run 'bundle exec rake railties:install:migrations FROM=solidus_returnly'
13
18
  end
14
19
 
15
20
  def run_migrations
21
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]'))
22
+ if run_migrations
23
+ run 'bundle exec rake db:migrate'
24
+ else
25
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
26
+ end
16
27
  end
17
28
  end
18
29
  end
@@ -0,0 +1,5 @@
1
+ require 'solidus_core'
2
+
3
+ require 'solidus/returnly/engine'
4
+ require 'solidus/returnly/refunds'
5
+ require 'solidus/returnly/calculator'
@@ -0,0 +1,102 @@
1
+ module Solidus
2
+ module Returnly
3
+ class Calculator
4
+ attr_accessor :line_items, :order
5
+
6
+ def self.process(order, line_items)
7
+ new(order, line_items).calculated_estimate
8
+ end
9
+
10
+ def initialize(order, line_items)
11
+ self.line_items = line_items
12
+ self.order = order
13
+ end
14
+
15
+ def calculated_estimate
16
+ total = line_items_return_items.values.sum {|iu| iu.sum(&:pre_tax_amount)}
17
+
18
+ tax_amount = returnable_inventory_units.sum do |inventory_unit|
19
+ calculate_tax inventory_unit
20
+ end
21
+
22
+ {
23
+ total_amount: total,
24
+ subtotal_amount: total - tax_amount,
25
+ tax_amount: tax_amount,
26
+ discount_amount: order.promo_total,
27
+ shipping_amount: order.shipment_total,
28
+ line_items: present_line_items
29
+ }
30
+ end
31
+
32
+ def present_line_items
33
+ line_items_return_items.map do |line_item_id, inventory_units|
34
+ line_item = line_item(line_item_id)
35
+
36
+ {
37
+ order_line_item_id: line_item.id,
38
+ quantity: inventory_units.size,
39
+ total_amount: inventory_units.sum(&:amount),
40
+ tax_amount: line_item.included_tax_total,
41
+ discount_amount: line_item.adjustment_total,
42
+ }
43
+ end
44
+ end
45
+
46
+
47
+ def calculate_tax(inventory_unit)
48
+ return_item = Spree::ReturnItem.from_inventory_unit(inventory_unit)
49
+ (return_item.amount <= 0) ? 0 : return_item.amount /
50
+ Spree::ReturnItem.refund_amount_calculator.new.compute(return_item)
51
+ end
52
+
53
+
54
+ def line_items_return_items
55
+ found_return_items = {}
56
+
57
+ self.line_items.each do |line_item|
58
+ quantity = line_item[:quantity].to_i
59
+
60
+ if quantity > 0
61
+ available_inventory_units = line_item_inventory_unit(line_item).slice(0, quantity)
62
+
63
+ available_inventory_units.each do |inventory_unit|
64
+ found_return_items[line_item[:order_line_item_id]] ||= []
65
+ found_return_items[line_item[:order_line_item_id]] << Spree::ReturnItem.new({amount: inventory_unit.line_item.price,
66
+ acceptance_status: 'accepted',
67
+ inventory_unit_id: inventory_unit.id,
68
+ reception_status_event: 'receive'
69
+ })
70
+ end
71
+ end
72
+ end
73
+
74
+ found_return_items
75
+ end
76
+
77
+ def line_item_inventory_unit(line_item)
78
+ returnable_inventory_units.select {|iu| iu.line_item_id == line_item[:order_line_item_id].to_i}
79
+ end
80
+
81
+ def line_item(id)
82
+ returnable_line_items.select {|i| i.id == id.to_i}.first
83
+ end
84
+
85
+ def returnable_inventory_units
86
+ @_inventory_units ||= order.inventory_units.includes(:line_item)
87
+ .where(line_item_id: requested_line_items)
88
+ .where('state is not "returned"')
89
+ end
90
+
91
+ def returnable_line_items
92
+ @_line_items ||= returnable_inventory_units.map(&:line_item)
93
+ end
94
+
95
+ def requested_line_items
96
+ line_items.map {|item| item[:order_line_item_id]}
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+
@@ -0,0 +1,56 @@
1
+ module Solidus
2
+ module Returnly
3
+ class Engine < Rails::Engine
4
+ require 'spree/core'
5
+
6
+ engine_name 'returnly'
7
+
8
+ config.autoload_paths += %W(#{config.root}/lib)
9
+
10
+ # use rspec for tests
11
+ config.generators do |g|
12
+ g.test_framework :rspec
13
+ end
14
+
15
+ def self.activate
16
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
17
+ Rails.configuration.cache_classes ? require(c) : load(c)
18
+ end
19
+ end
20
+
21
+ config.to_prepare(&method(:activate).to_proc)
22
+
23
+ rake_tasks do
24
+ namespace :returnly do
25
+ require 'securerandom'
26
+
27
+ desc "Creates an returnly user and prints the generated API key"
28
+ task install_user: :environment do
29
+ returnly_email = 'api@returnly.coim'
30
+
31
+ password = SecureRandom.hex(24)
32
+
33
+ if (user = Spree::User.find_by email: returnly_email)
34
+ puts "The Returnly User is already generated"
35
+ puts "The Api key is: #{user.spree_api_key}"
36
+ else
37
+ user = Spree::User.new email: returnly_email, password: password,
38
+ password_confirmation: password
39
+
40
+ api_key = user.generate_spree_api_key
41
+
42
+ if user.save!
43
+ puts "****************************************************"
44
+ puts "Api key Generated #{api_key}"
45
+ puts "Returnly User Password #{password}"
46
+ puts "Returnly User email #{returnly_email}"
47
+ puts "****************************************************"
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ end
@@ -2,5 +2,5 @@ FactoryGirl.define do
2
2
  # Define your Spree extensions Factories within this file to enable applications, and other extensions to use and override them.
3
3
  #
4
4
  # Example adding this to your spec_helper will load these Factories for use:
5
- # require 'solidus_returnly/factories'
5
+ # require 'returnly/factories'
6
6
  end
@@ -0,0 +1,84 @@
1
+ module Solidus
2
+ module Returnly
3
+ class Refunds
4
+ attr_accessor :calculator, :order, :line_items, :restock, :transactions
5
+
6
+ def initialize(order:, line_items:, restock: true, transactions:)
7
+ self.order = order
8
+ self.line_items = line_items
9
+ self.calculator = Calculator.new order, line_items
10
+ self.restock = restock
11
+ self.transactions = transactions
12
+ end
13
+
14
+ def restock_return(customer_return)
15
+ customer_return.return_items.each do |item|
16
+ customer_return.stock_location.restock(item.inventory_unit.variant, 1, customer_return)
17
+ end
18
+ end
19
+
20
+ def proceed!
21
+ customer_return = Spree::CustomerReturn.new customer_return_params
22
+ customer_return.return_items = calculator.line_items_return_items.values.flatten
23
+
24
+ customer_return.return_items.each do |return_item|
25
+ return_item.amount = refund_amount_per_item
26
+ end
27
+
28
+ if customer_return.save!
29
+ reimbursement = perform_reimbursement(customer_return)
30
+ restock_return(customer_return) if self.restock
31
+
32
+ processed_customer_return(customer_return, reimbursement)
33
+ end
34
+ end
35
+
36
+ def processed_customer_return(customer_return, reimbursement)
37
+ {
38
+ refund_id: customer_return.number,
39
+ created_at: customer_return.created_at,
40
+ updated_at: customer_return.updated_at,
41
+ line_items: customer_return.return_items.map {|ri|
42
+ {
43
+ refund_line_item_id: ri.id,
44
+ order_line_item_id: ri.inventory_unit.line_item.id,
45
+ quantity: 1
46
+ }
47
+ },
48
+ transactions: [
49
+ id: reimbursement.id,
50
+ amount: reimbursement.total
51
+ ],
52
+ note: "comment text",
53
+ restock: true
54
+ }
55
+ end
56
+
57
+ def perform_reimbursement(customer_return)
58
+ reimbursement = Spree::Reimbursement.build_from_customer_return(customer_return)
59
+ reimbursement.save!
60
+ reimbursement.perform!
61
+ reimbursement
62
+ end
63
+
64
+ def customer_return_params
65
+ {
66
+ stock_location_id: stock_location_id,
67
+ }
68
+ end
69
+
70
+ def stock_location_id
71
+ order.shipments.last.stock_location.id
72
+ end
73
+
74
+ def refund_available_amount
75
+ @available_amount ||= self.transactions.sum {|t| Money.from_amount(t[:amount].to_f)}
76
+ end
77
+
78
+ def refund_amount_per_item
79
+ refund_available_amount / line_items.size
80
+ end
81
+ end
82
+ end
83
+
84
+ end
@@ -0,0 +1,5 @@
1
+ module Solidus
2
+ module Returnly
3
+ VERSION = '0.2.0'
4
+ end
5
+ end
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.0.1
4
+ version: 0.2.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: 2017-05-23 00:00:00.000000000 Z
11
+ date: 2017-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: solidus
@@ -243,16 +243,18 @@ files:
243
243
  - LICENSE
244
244
  - README.md
245
245
  - Rakefile
246
- - app/controllers/spree/api/refunds_controller.rb
246
+ - app/controllers/spree/api/returnly/api_controller.rb
247
+ - app/controllers/spree/api/returnly/refunds_controller.rb
248
+ - app/controllers/spree/api/returnly/version_controller.rb
247
249
  - config/locales/en.yml
248
250
  - config/routes.rb
249
251
  - lib/generators/solidus_returnly/install/install_generator.rb
250
- - lib/solidus/returnly.rb
251
- - lib/solidus_returnly/calculator.rb
252
- - lib/solidus_returnly/engine.rb
253
- - lib/solidus_returnly/factories.rb
254
- - lib/solidus_returnly/refunds.rb
255
- - lib/solidus_returnly/version.rb
252
+ - lib/solidus-returnly.rb
253
+ - lib/solidus/returnly/calculator.rb
254
+ - lib/solidus/returnly/engine.rb
255
+ - lib/solidus/returnly/factories.rb
256
+ - lib/solidus/returnly/refunds.rb
257
+ - lib/solidus/returnly/version.rb
256
258
  homepage: https://github.com/returnly/solidus-returnly
257
259
  licenses:
258
260
  - MIT
@@ -1,40 +0,0 @@
1
- module Spree
2
- module Api
3
- class RefundsController < Spree::Api::BaseController
4
-
5
- def estimate
6
- authorize! :create, Order
7
- render json: SolidusReturnly::Calculator.process(order, line_items_params)
8
- end
9
-
10
- def create
11
- authorize! :create, Order
12
-
13
- refunds = SolidusReturnly::Refunds.new order: order,
14
- line_items: line_items_params,
15
- restock: refund_restock_param,
16
- transactions: transactions_params
17
- render json: refunds.proceed!
18
- end
19
-
20
- private
21
-
22
- def line_items_params
23
- params.require(:line_items)
24
- end
25
-
26
- def transactions_params
27
- params.require(:transactions)
28
- end
29
-
30
- def refund_restock_param
31
- params.require(:restock) == 'true'
32
- end
33
-
34
- def order
35
- @order ||= Spree::Order.find_by(number: params[:order_id])
36
- end
37
- end
38
- end
39
- end
40
-
@@ -1,5 +0,0 @@
1
- require 'solidus_core'
2
-
3
- require 'solidus_returnly/engine'
4
- require 'solidus_returnly/refunds'
5
- require 'solidus_returnly/calculator'
@@ -1,98 +0,0 @@
1
- module SolidusReturnly
2
- class Calculator
3
- attr_accessor :line_items, :order
4
-
5
- def self.process(order, line_items)
6
- new(order, line_items).calculated_estimate
7
- end
8
-
9
- def initialize(order, line_items)
10
- self.line_items = line_items
11
- self.order = order
12
- end
13
-
14
- def calculated_estimate
15
- total = line_items_return_items.values.sum{|iu| iu.sum(&:pre_tax_amount) }
16
-
17
- tax_amount = returnable_inventory_units.sum do |inventory_unit|
18
- calculate_tax inventory_unit
19
- end
20
-
21
- {
22
- total_amount: total,
23
- subtotal_amount: total - tax_amount,
24
- tax_amount: tax_amount,
25
- discount_amount: order.promo_total,
26
- shipping_amount: order.shipment_total,
27
- line_items: present_line_items
28
- }
29
- end
30
-
31
- def present_line_items
32
- line_items_return_items.map do| line_item_id, inventory_units|
33
- line_item = line_item(line_item_id)
34
-
35
- {
36
- order_line_item_id: line_item.id,
37
- quantity: inventory_units.size,
38
- total_amount: inventory_units.sum(&:amount),
39
- tax_amount: line_item.included_tax_total,
40
- discount_amount: line_item.adjustment_total,
41
- }
42
- end
43
- end
44
-
45
-
46
- def calculate_tax(inventory_unit)
47
- return_item = Spree::ReturnItem.from_inventory_unit(inventory_unit)
48
- (return_item.amount <= 0) ? 0 : return_item.amount /
49
- Spree::ReturnItem.refund_amount_calculator.new.compute(return_item)
50
- end
51
-
52
-
53
- def line_items_return_items
54
- found_return_items = {}
55
-
56
- self.line_items.each do |line_item|
57
- quantity = line_item[:quantity].to_i
58
-
59
- if quantity > 0
60
- available_inventory_units = line_item_inventory_unit(line_item).slice(0, quantity)
61
-
62
- available_inventory_units.each do |inventory_unit|
63
- found_return_items[line_item[:order_line_item_id]] ||= []
64
- found_return_items[line_item[:order_line_item_id]] << Spree::ReturnItem.new({amount: inventory_unit.line_item.price,
65
- acceptance_status: 'accepted',
66
- inventory_unit_id: inventory_unit.id,
67
- reception_status_event: 'receive'
68
- })
69
- end
70
- end
71
- end
72
-
73
- found_return_items
74
- end
75
-
76
- def line_item_inventory_unit(line_item)
77
- returnable_inventory_units.select{|iu| iu.line_item_id == line_item[:order_line_item_id].to_i }
78
- end
79
-
80
- def line_item(id)
81
- returnable_line_items.select{|i| i.id == id.to_i }.first
82
- end
83
-
84
- def returnable_inventory_units
85
- @_inventory_units ||= order.inventory_units.includes(:line_item)
86
- .where(line_item_id: requested_line_items)
87
- .where('state is not "returned"')
88
- end
89
-
90
- def returnable_line_items
91
- @_line_items ||= returnable_inventory_units.map(&:line_item)
92
- end
93
-
94
- def requested_line_items
95
- line_items.map { |item| item[:order_line_item_id] }
96
- end
97
- end
98
- end
@@ -1,53 +0,0 @@
1
- module SolidusReturnly
2
- class Engine < Rails::Engine
3
- require 'spree/core'
4
-
5
- engine_name 'solidus_returnly'
6
-
7
- config.autoload_paths += %W(#{config.root}/lib)
8
-
9
- # use rspec for tests
10
- config.generators do |g|
11
- g.test_framework :rspec
12
- end
13
-
14
- def self.activate
15
- Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
16
- Rails.configuration.cache_classes ? require(c) : load(c)
17
- end
18
- end
19
-
20
- config.to_prepare(&method(:activate).to_proc)
21
-
22
- rake_tasks do
23
- namespace :returnly do
24
- require 'securerandom'
25
-
26
- desc "Creates an returnly user and prints the generated API key"
27
- task install_user: :environment do
28
- returnly_email = 'api@returnly.coim'
29
-
30
- password = SecureRandom.hex(24)
31
-
32
- if (user = Spree::User.find_by email: returnly_email)
33
- puts "The Returnly User is already generated"
34
- puts "The Api key is: #{user.spree_api_key}"
35
- else
36
- user = Spree::User.new email: returnly_email, password: password,
37
- password_confirmation: password
38
-
39
- api_key = user.generate_spree_api_key
40
-
41
- if user.save!
42
- puts "****************************************************"
43
- puts "Api key Generated #{api_key}"
44
- puts "Returnly User Password #{password}"
45
- puts "Returnly User email #{returnly_email}"
46
- puts "****************************************************"
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,81 +0,0 @@
1
- module SolidusReturnly
2
- class Refunds
3
- attr_accessor :calculator, :order, :line_items, :restock, :transactions
4
-
5
- def initialize(order:, line_items:, restock: true, transactions:)
6
- self.order = order
7
- self.line_items = line_items
8
- self.calculator = Calculator.new order, line_items
9
- self.restock = restock
10
- self.transactions = transactions
11
- end
12
-
13
- def restock_return(customer_return)
14
- customer_return.return_items.each do | item |
15
- customer_return.stock_location.restock(item.inventory_unit.variant, 1, customer_return)
16
- end
17
- end
18
-
19
- def proceed!
20
- customer_return = Spree::CustomerReturn.new customer_return_params
21
- customer_return.return_items = calculator.line_items_return_items.values.flatten
22
-
23
- customer_return.return_items.each do |return_item|
24
- return_item.amount = refund_amount_per_item
25
- end
26
-
27
- if customer_return.save!
28
- reimbursement = perform_reimbursement(customer_return)
29
- restock_return(customer_return) if self.restock
30
-
31
- processed_customer_return(customer_return, reimbursement)
32
- end
33
- end
34
-
35
- def processed_customer_return(customer_return, reimbursement)
36
- {
37
- refund_id: customer_return.number,
38
- created_at: customer_return.created_at,
39
- updated_at: customer_return.updated_at,
40
- line_items: customer_return.return_items.map { |ri|
41
- {
42
- refund_line_item_id: ri.id,
43
- order_line_item_id: ri.inventory_unit.line_item.id,
44
- quantity: 1
45
- }
46
- },
47
- transactions: [
48
- id: reimbursement.id,
49
- amount: reimbursement.total
50
- ],
51
- note: "comment text",
52
- restock: true
53
- }
54
- end
55
-
56
- def perform_reimbursement(customer_return)
57
- reimbursement = Spree::Reimbursement.build_from_customer_return(customer_return)
58
- reimbursement.save!
59
- reimbursement.perform!
60
- reimbursement
61
- end
62
-
63
- def customer_return_params
64
- {
65
- stock_location_id: stock_location_id,
66
- }
67
- end
68
-
69
- def stock_location_id
70
- order.shipments.last.stock_location.id
71
- end
72
-
73
- def refund_available_amount
74
- @available_amount ||= self.transactions.sum{|t| Money.from_amount(t[:amount].to_f) }
75
- end
76
-
77
- def refund_amount_per_item
78
- refund_available_amount / line_items.size
79
- end
80
- end
81
- end
@@ -1,3 +0,0 @@
1
- module SolidusReturnly
2
- VERSION = '0.0.1'
3
- end