solidus_legacy_return_authorizations 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/Gemfile +10 -0
- data/LICENSE +26 -0
- data/README.md +62 -0
- data/Rakefile +21 -0
- data/app/assets/javascripts/spree/backend/solidus_legacy_return_authorizations.js +2 -0
- data/app/assets/stylesheets/spree/backend/solidus_legacy_return_authorizations.css +4 -0
- data/app/controllers/spree/admin/legacy_return_authorizations_controller.rb +25 -0
- data/app/controllers/spree/api/legacy_return_authorizations_controller.rb +74 -0
- data/app/helpers/spree/admin/navigation_helper_decorator.rb +12 -0
- data/app/helpers/spree/api/api_helpers_decorator.rb +7 -0
- data/app/models/spree/adjustment_decorator.rb +3 -0
- data/app/models/spree/inventory_unit_decorator.rb +3 -0
- data/app/models/spree/legacy_return_authorization.rb +108 -0
- data/app/models/spree/order_decorator.rb +3 -0
- data/app/models/spree/permission_sets/legacy_return_authorization_display.rb +9 -0
- data/app/models/spree/permission_sets/legacy_return_authorization_management.rb +9 -0
- data/app/models/spree/strong_parameters_decorator.rb +5 -0
- data/app/overrides/admin_legacy_return_authorizations.rb +14 -0
- data/app/views/spree/admin/legacy_return_authorizations/_form.html.erb +78 -0
- data/app/views/spree/admin/legacy_return_authorizations/edit.html.erb +32 -0
- data/app/views/spree/admin/legacy_return_authorizations/index.html.erb +48 -0
- data/app/views/spree/api/legacy_return_authorizations/index.v1.rabl +7 -0
- data/app/views/spree/api/legacy_return_authorizations/new.v1.rabl +3 -0
- data/app/views/spree/api/legacy_return_authorizations/show.v1.rabl +2 -0
- data/bin/rails +7 -0
- data/circle.yml +6 -0
- data/config/locales/en.yml +19 -0
- data/config/routes.rb +25 -0
- data/db/migrate/20140710044402_create_spree_legacy_return_authorizations.rb +26 -0
- data/lib/generators/solidus_legacy_return_authorizations/install/install_generator.rb +29 -0
- data/lib/solidus_legacy_return_authorizations.rb +2 -0
- data/lib/spree_legacy_return_authorizations/engine.rb +20 -0
- data/lib/spree_legacy_return_authorizations/factories.rb +13 -0
- data/solidus_legacy_return_authorizations.gemspec +29 -0
- data/spec/controllers/admin/legacy_return_authorizations_controller_spec.rb +32 -0
- data/spec/controllers/spree/api/legacy_return_authorizations_controller_spec.rb +157 -0
- data/spec/features/admin/orders/legacy_return_authorizations_spec.rb +26 -0
- data/spec/models/spree/legacy_return_authorization_spec.rb +214 -0
- data/spec/models/spree/permission_sets/legacy_return_authorization_display_spec.rb +22 -0
- data/spec/models/spree/permission_sets/legacy_return_authorization_management_spec.rb +20 -0
- data/spec/spec_helper.rb +74 -0
- data/spec/support/authentication_support.rb +7 -0
- data/spec/support/have_attributes_matcher.rb +8 -0
- metadata +245 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 18ac64c290153dc76aa973685a5dc58ea3190508
|
4
|
+
data.tar.gz: 539c2555b6e921869fee35ff7925b155446d3472
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b3767c15416db0beb83c325f3a50557fd3ac98c222fa9f37ae490aa9598a74bbb046b05d5405921c60638e0635b3d63230a5b20a1276bedea2d94b5ea61b478e
|
7
|
+
data.tar.gz: 79ea178bd773d20e8bdd6741dd8f6c67afb7206948f51be81a82c631c215eaccf26195d3c2d2a7bf92329c19955fe507e3dfb4f17bd0d0264665340105348eb6
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Copyright (c) 2014 Bonobos, Inc
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
are permitted provided that the following conditions are met:
|
6
|
+
|
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.
|
15
|
+
|
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
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
Solidus Legacy Return Authorizations
|
2
|
+
====================================
|
3
|
+
|
4
|
+
This is an extension for users migrating from legacy versions of Spree (2.3.x
|
5
|
+
and prior) which had a different representation of and handling for return
|
6
|
+
authorizations.
|
7
|
+
|
8
|
+
When upgrading from a prior version of Spree to Solidus, simply include this
|
9
|
+
extension in your application's Gemfile and your old data will be preserved in
|
10
|
+
separate tables (e.g., `spree_legacy_return_authorizations`) and columns (e.g.
|
11
|
+
`spree_inventory_units.legacy_return_authorization_id`).
|
12
|
+
|
13
|
+
This extension maintains the legacy admin interfaces for viewing and closing
|
14
|
+
out (receiving/canceling) any existing legacy return authorizations. It does
|
15
|
+
not allow creating any new legacy return authorizations. New return
|
16
|
+
authorizations should be handled through the new returns system included in
|
17
|
+
Solidus.
|
18
|
+
|
19
|
+
If an order has existing legacy return authorizations then an additional admin
|
20
|
+
menu item "Legacy Return Authorizations" will appear in the admin interface for
|
21
|
+
that order (/admin/orders/XXX/edit).
|
22
|
+
|
23
|
+
Installation
|
24
|
+
------------
|
25
|
+
|
26
|
+
Add solidus_legacy_return_authorizations to your Gemfile:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
gem "solidus_legacy_return_authorizations"
|
30
|
+
```
|
31
|
+
|
32
|
+
Bundle your dependencies and run the installation generator:
|
33
|
+
|
34
|
+
```shell
|
35
|
+
bundle
|
36
|
+
bundle exec rails g solidus_legacy_return_authorizations:install
|
37
|
+
```
|
38
|
+
|
39
|
+
Authorization
|
40
|
+
-------------
|
41
|
+
|
42
|
+
For discrete authorization, two permission sets have been added to allow for granular display in the admin.
|
43
|
+
|
44
|
+
`Spree::PermissionSets::LegacyReturnAuthorizationDisplay` and `Spree::PermissionSets::LegacyReturnAuthorizationManagement` have been added and can be assigned via [RoleConfiguration](http://docs.solidus.io/Spree/RoleConfiguration.html)
|
45
|
+
|
46
|
+
|
47
|
+
Testing
|
48
|
+
-------
|
49
|
+
|
50
|
+
First bundle your dependencies, then run `rake`. `rake` will default to building the dummy app if it does not exist, then it will run specs. The dummy app can be regenerated by using `rake test_app`.
|
51
|
+
|
52
|
+
```shell
|
53
|
+
bundle
|
54
|
+
bundle exec rake
|
55
|
+
```
|
56
|
+
|
57
|
+
When testing your applications integration with this extension you may use it's factories.
|
58
|
+
Simply add this require statement to your spec_helper:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
require 'spree_legacy_return_authorizations/factories'
|
62
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'spree/testing_support/extension_rake'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new
|
8
|
+
|
9
|
+
task :default do
|
10
|
+
if Dir["spec/dummy"].empty?
|
11
|
+
Rake::Task[:test_app].invoke
|
12
|
+
Dir.chdir("../../")
|
13
|
+
end
|
14
|
+
Rake::Task[:spec].invoke
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Generates a dummy app for testing'
|
18
|
+
task :test_app do
|
19
|
+
ENV['LIB_NAME'] = 'solidus_legacy_return_authorizations'
|
20
|
+
Rake::Task['extension:test_app'].invoke
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Spree
|
2
|
+
module Admin
|
3
|
+
class LegacyReturnAuthorizationsController < ResourceController
|
4
|
+
belongs_to 'spree/order', :find_by => :number
|
5
|
+
|
6
|
+
update.after :associate_inventory_units
|
7
|
+
create.after :associate_inventory_units
|
8
|
+
|
9
|
+
def fire
|
10
|
+
@legacy_return_authorization.send("#{params[:e]}!")
|
11
|
+
flash[:success] = Spree.t(:legacy_return_authorization_updated)
|
12
|
+
redirect_to :back
|
13
|
+
end
|
14
|
+
|
15
|
+
# We don't want to allow creating new legacy RMAs so remove the default methods provided by Admin::ResourceController
|
16
|
+
undef new
|
17
|
+
undef create
|
18
|
+
|
19
|
+
protected
|
20
|
+
def associate_inventory_units
|
21
|
+
(params[:return_quantity] || []).each { |variant_id, qty| @legacy_return_authorization.add_variant(variant_id.to_i, qty.to_i) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
class LegacyReturnAuthorizationsController < Spree::Api::BaseController
|
4
|
+
|
5
|
+
def destroy
|
6
|
+
@legacy_return_authorization = order.legacy_return_authorizations.accessible_by(current_ability, :destroy).find(params[:id])
|
7
|
+
@legacy_return_authorization.destroy
|
8
|
+
respond_with(@legacy_return_authorization, status: 204)
|
9
|
+
end
|
10
|
+
|
11
|
+
def index
|
12
|
+
authorize! :admin, LegacyReturnAuthorization
|
13
|
+
@legacy_return_authorizations = order.legacy_return_authorizations.accessible_by(current_ability, :read).
|
14
|
+
ransack(params[:q]).result.
|
15
|
+
page(params[:page]).per(params[:per_page])
|
16
|
+
respond_with(@legacy_return_authorizations)
|
17
|
+
end
|
18
|
+
|
19
|
+
def show
|
20
|
+
authorize! :admin, LegacyReturnAuthorization
|
21
|
+
@legacy_return_authorization = order.legacy_return_authorizations.accessible_by(current_ability, :read).find(params[:id])
|
22
|
+
respond_with(@legacy_return_authorization)
|
23
|
+
end
|
24
|
+
|
25
|
+
def update
|
26
|
+
@legacy_return_authorization = order.legacy_return_authorizations.accessible_by(current_ability, :update).find(params[:id])
|
27
|
+
if @legacy_return_authorization.update_attributes(legacy_return_authorization_params)
|
28
|
+
respond_with(@legacy_return_authorization, default_template: :show)
|
29
|
+
else
|
30
|
+
invalid_resource!(@legacy_return_authorization)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def add
|
35
|
+
@legacy_return_authorization = order.legacy_return_authorizations.accessible_by(current_ability, :update).find(params[:id])
|
36
|
+
@legacy_return_authorization.add_variant params[:variant_id].to_i, params[:quantity].to_i
|
37
|
+
if @legacy_return_authorization.valid?
|
38
|
+
respond_with @legacy_return_authorization, default_template: :show
|
39
|
+
else
|
40
|
+
invalid_resource!(@legacy_return_authorization)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def receive
|
45
|
+
@legacy_return_authorization = order.legacy_return_authorizations.accessible_by(current_ability, :update).find(params[:id])
|
46
|
+
if @legacy_return_authorization.receive
|
47
|
+
respond_with @legacy_return_authorization, default_template: :show
|
48
|
+
else
|
49
|
+
invalid_resource!(@legacy_return_authorization)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def cancel
|
54
|
+
@legacy_return_authorization = order.legacy_return_authorizations.accessible_by(current_ability, :update).find(params[:id])
|
55
|
+
if @legacy_return_authorization.cancel
|
56
|
+
respond_with @legacy_return_authorization, default_template: :show
|
57
|
+
else
|
58
|
+
invalid_resource!(@legacy_return_authorization)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def order
|
65
|
+
@order ||= Spree::Order.find_by!(number: order_id)
|
66
|
+
authorize! :read, @order
|
67
|
+
end
|
68
|
+
|
69
|
+
def legacy_return_authorization_params
|
70
|
+
params.require(:legacy_return_authorization).permit(permitted_legacy_return_authorization_attributes)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Spree::Admin::NavigationHelper.module_eval do
|
2
|
+
def tab_with_legacy_return_authorizations(*args)
|
3
|
+
if args.first == :orders
|
4
|
+
options = args.pop if args.last.is_a?(Hash)
|
5
|
+
args << :legacy_return_authorizations
|
6
|
+
args << options
|
7
|
+
end
|
8
|
+
tab_without_legacy_return_authorizations(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
alias_method_chain :tab, :legacy_return_authorizations
|
12
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Spree
|
2
|
+
class LegacyReturnAuthorization < ActiveRecord::Base
|
3
|
+
belongs_to :order, class_name: 'Spree::Order'
|
4
|
+
|
5
|
+
has_many :inventory_units, dependent: :nullify
|
6
|
+
belongs_to :stock_location
|
7
|
+
before_create :generate_number
|
8
|
+
before_save :force_positive_amount
|
9
|
+
|
10
|
+
validates :order, presence: true
|
11
|
+
validates :amount, numericality: true
|
12
|
+
validate :must_have_shipped_units
|
13
|
+
|
14
|
+
state_machine initial: :authorized do
|
15
|
+
after_transition to: :received, do: :process_return
|
16
|
+
|
17
|
+
event :receive do
|
18
|
+
transition to: :received, from: :authorized, if: :allow_receive?
|
19
|
+
end
|
20
|
+
event :cancel do
|
21
|
+
transition to: :canceled, from: :authorized
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def currency
|
26
|
+
order.nil? ? Spree::Config[:currency] : order.currency
|
27
|
+
end
|
28
|
+
|
29
|
+
def display_amount
|
30
|
+
Spree::Money.new(amount, { currency: currency })
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_variant(variant_id, quantity)
|
34
|
+
order_units = returnable_inventory.group_by(&:variant_id)
|
35
|
+
returned_units = inventory_units.group_by(&:variant_id)
|
36
|
+
return false if order_units.empty?
|
37
|
+
|
38
|
+
count = 0
|
39
|
+
|
40
|
+
if returned_units[variant_id].nil? || returned_units[variant_id].size < quantity
|
41
|
+
count = returned_units[variant_id].nil? ? 0 : returned_units[variant_id].size
|
42
|
+
|
43
|
+
order_units[variant_id].each do |inventory_unit|
|
44
|
+
next unless inventory_unit.legacy_return_authorization.nil? && count < quantity
|
45
|
+
|
46
|
+
inventory_unit.legacy_return_authorization = self
|
47
|
+
inventory_unit.save!
|
48
|
+
|
49
|
+
count += 1
|
50
|
+
end
|
51
|
+
elsif returned_units[variant_id].size > quantity
|
52
|
+
(returned_units[variant_id].size - quantity).times do |i|
|
53
|
+
returned_units[variant_id][i].legacy_return_authorization_id = nil
|
54
|
+
returned_units[variant_id][i].save!
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
order.authorize_return! if inventory_units.reload.size > 0 && !order.awaiting_return?
|
59
|
+
end
|
60
|
+
|
61
|
+
def returnable_inventory
|
62
|
+
order.shipped_shipments.collect{|s| s.inventory_units.to_a}.flatten
|
63
|
+
end
|
64
|
+
|
65
|
+
# Used when Adjustment#update! wants to update the related adjustmenrt
|
66
|
+
def compute_amount(*args)
|
67
|
+
amount.abs * -1
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def must_have_shipped_units
|
73
|
+
errors.add(:order, Spree.t(:has_no_shipped_units)) if order.nil? || !order.shipped_shipments.any?
|
74
|
+
end
|
75
|
+
|
76
|
+
def generate_number
|
77
|
+
self.number ||= loop do
|
78
|
+
random = "RMA#{Array.new(9){rand(9)}.join}"
|
79
|
+
break random unless self.class.exists?(number: random)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def process_return
|
84
|
+
inventory_units(include: :variant).each do |iu|
|
85
|
+
iu.return!
|
86
|
+
|
87
|
+
if iu.variant.should_track_inventory?
|
88
|
+
if stock_item = Spree::StockItem.find_by(variant_id: iu.variant_id, stock_location_id: stock_location_id)
|
89
|
+
Spree::StockMovement.create!(stock_item_id: stock_item.id, quantity: 1)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
Adjustment.create(adjustable: order, amount: compute_amount, label: Spree.t(:legacy_rma_credit), source: self)
|
95
|
+
order.update!
|
96
|
+
|
97
|
+
order.return if inventory_units.all?(&:returned?)
|
98
|
+
end
|
99
|
+
|
100
|
+
def allow_receive?
|
101
|
+
!inventory_units.empty?
|
102
|
+
end
|
103
|
+
|
104
|
+
def force_positive_amount
|
105
|
+
self.amount = amount.abs
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|