solidus_legacy_return_authorizations 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.
- 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
|