solidus_api 1.0.0.pre

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.
Files changed (202) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/CHANGELOG.md +1 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE +27 -0
  6. data/Rakefile +16 -0
  7. data/app/controllers/spree/api/addresses_controller.rb +43 -0
  8. data/app/controllers/spree/api/base_controller.rb +189 -0
  9. data/app/controllers/spree/api/checkouts_controller.rb +133 -0
  10. data/app/controllers/spree/api/classifications_controller.rb +18 -0
  11. data/app/controllers/spree/api/config_controller.rb +6 -0
  12. data/app/controllers/spree/api/countries_controller.rb +23 -0
  13. data/app/controllers/spree/api/credit_cards_controller.rb +25 -0
  14. data/app/controllers/spree/api/images_controller.rb +47 -0
  15. data/app/controllers/spree/api/inventory_units_controller.rb +52 -0
  16. data/app/controllers/spree/api/line_items_controller.rb +74 -0
  17. data/app/controllers/spree/api/option_types_controller.rb +49 -0
  18. data/app/controllers/spree/api/option_values_controller.rb +58 -0
  19. data/app/controllers/spree/api/orders_controller.rb +155 -0
  20. data/app/controllers/spree/api/payments_controller.rb +81 -0
  21. data/app/controllers/spree/api/product_properties_controller.rb +72 -0
  22. data/app/controllers/spree/api/products_controller.rb +129 -0
  23. data/app/controllers/spree/api/promotions_controller.rb +26 -0
  24. data/app/controllers/spree/api/properties_controller.rb +71 -0
  25. data/app/controllers/spree/api/return_authorizations_controller.rb +71 -0
  26. data/app/controllers/spree/api/shipments_controller.rb +172 -0
  27. data/app/controllers/spree/api/states_controller.rb +35 -0
  28. data/app/controllers/spree/api/stock_items_controller.rb +84 -0
  29. data/app/controllers/spree/api/stock_locations_controller.rb +50 -0
  30. data/app/controllers/spree/api/stock_movements_controller.rb +42 -0
  31. data/app/controllers/spree/api/stock_transfers_controller.rb +19 -0
  32. data/app/controllers/spree/api/store_credit_events_controller.rb +9 -0
  33. data/app/controllers/spree/api/stores_controller.rb +55 -0
  34. data/app/controllers/spree/api/taxonomies_controller.rb +64 -0
  35. data/app/controllers/spree/api/taxons_controller.rb +93 -0
  36. data/app/controllers/spree/api/transfer_items_controller.rb +42 -0
  37. data/app/controllers/spree/api/users_controller.rb +56 -0
  38. data/app/controllers/spree/api/variants_controller.rb +75 -0
  39. data/app/controllers/spree/api/zones_controller.rb +50 -0
  40. data/app/helpers/spree/api/api_helpers.rb +190 -0
  41. data/app/models/spree/api_configuration.rb +5 -0
  42. data/app/models/spree/option_value_decorator.rb +9 -0
  43. data/app/views/spree/api/addresses/show.v1.rabl +10 -0
  44. data/app/views/spree/api/adjustments/show.v1.rabl +4 -0
  45. data/app/views/spree/api/config/money.v1.rabl +2 -0
  46. data/app/views/spree/api/config/show.v1.rabl +2 -0
  47. data/app/views/spree/api/countries/index.v1.rabl +7 -0
  48. data/app/views/spree/api/countries/show.v1.rabl +5 -0
  49. data/app/views/spree/api/credit_cards/index.v1.rabl +7 -0
  50. data/app/views/spree/api/credit_cards/show.v1.rabl +3 -0
  51. data/app/views/spree/api/errors/gateway_error.v1.rabl +2 -0
  52. data/app/views/spree/api/errors/invalid_api_key.v1.rabl +2 -0
  53. data/app/views/spree/api/errors/invalid_resource.v1.rabl +3 -0
  54. data/app/views/spree/api/errors/must_specify_api_key.v1.rabl +2 -0
  55. data/app/views/spree/api/errors/not_found.v1.rabl +2 -0
  56. data/app/views/spree/api/errors/unauthorized.v1.rabl +2 -0
  57. data/app/views/spree/api/errors/variant_not_in_stock_transfer.v1.rabl +2 -0
  58. data/app/views/spree/api/images/index.v1.rabl +4 -0
  59. data/app/views/spree/api/images/show.v1.rabl +6 -0
  60. data/app/views/spree/api/inventory_units/show.rabl +2 -0
  61. data/app/views/spree/api/line_items/new.v1.rabl +3 -0
  62. data/app/views/spree/api/line_items/show.v1.rabl +15 -0
  63. data/app/views/spree/api/option_types/index.v1.rabl +3 -0
  64. data/app/views/spree/api/option_types/show.v1.rabl +5 -0
  65. data/app/views/spree/api/option_values/index.v1.rabl +3 -0
  66. data/app/views/spree/api/option_values/show.v1.rabl +2 -0
  67. data/app/views/spree/api/orders/address.v1.rabl +0 -0
  68. data/app/views/spree/api/orders/canceled.v1.rabl +0 -0
  69. data/app/views/spree/api/orders/cart.v1.rabl +0 -0
  70. data/app/views/spree/api/orders/complete.v1.rabl +0 -0
  71. data/app/views/spree/api/orders/could_not_apply_coupon.v1.rabl +2 -0
  72. data/app/views/spree/api/orders/could_not_transition.v1.rabl +3 -0
  73. data/app/views/spree/api/orders/expected_total_mismatch.v1.rabl +2 -0
  74. data/app/views/spree/api/orders/index.v1.rabl +7 -0
  75. data/app/views/spree/api/orders/invalid_shipping_method.v1.rabl +2 -0
  76. data/app/views/spree/api/orders/mine.v1.rabl +9 -0
  77. data/app/views/spree/api/orders/order.v1.rabl +9 -0
  78. data/app/views/spree/api/orders/payment.v1.rabl +3 -0
  79. data/app/views/spree/api/orders/show.v1.rabl +52 -0
  80. data/app/views/spree/api/payments/credit_over_limit.v1.rabl +2 -0
  81. data/app/views/spree/api/payments/index.v1.rabl +7 -0
  82. data/app/views/spree/api/payments/new.v1.rabl +5 -0
  83. data/app/views/spree/api/payments/show.v1.rabl +2 -0
  84. data/app/views/spree/api/payments/update_forbidden.v1.rabl +2 -0
  85. data/app/views/spree/api/product_properties/index.v1.rabl +7 -0
  86. data/app/views/spree/api/product_properties/new.v1.rabl +2 -0
  87. data/app/views/spree/api/product_properties/show.v1.rabl +2 -0
  88. data/app/views/spree/api/products/index.v1.rabl +9 -0
  89. data/app/views/spree/api/products/new.v1.rabl +3 -0
  90. data/app/views/spree/api/products/product.v1.rabl +1 -0
  91. data/app/views/spree/api/products/show.v1.rabl +31 -0
  92. data/app/views/spree/api/promotions/handler.v1.rabl +5 -0
  93. data/app/views/spree/api/promotions/show.v1.rabl +2 -0
  94. data/app/views/spree/api/properties/index.v1.rabl +7 -0
  95. data/app/views/spree/api/properties/new.v1.rabl +2 -0
  96. data/app/views/spree/api/properties/show.v1.rabl +2 -0
  97. data/app/views/spree/api/return_authorizations/index.v1.rabl +7 -0
  98. data/app/views/spree/api/return_authorizations/new.v1.rabl +3 -0
  99. data/app/views/spree/api/return_authorizations/show.v1.rabl +2 -0
  100. data/app/views/spree/api/shared/stock_location_required.v1.rabl +2 -0
  101. data/app/views/spree/api/shipments/big.v1.rabl +48 -0
  102. data/app/views/spree/api/shipments/cannot_ready_shipment.v1.rabl +2 -0
  103. data/app/views/spree/api/shipments/mine.v1.rabl +9 -0
  104. data/app/views/spree/api/shipments/show.v1.rabl +32 -0
  105. data/app/views/spree/api/shipments/small.v1.rabl +37 -0
  106. data/app/views/spree/api/shipping_rates/show.v1.rabl +2 -0
  107. data/app/views/spree/api/states/index.v1.rabl +14 -0
  108. data/app/views/spree/api/states/show.v1.rabl +2 -0
  109. data/app/views/spree/api/stock_items/index.v1.rabl +7 -0
  110. data/app/views/spree/api/stock_items/show.v1.rabl +5 -0
  111. data/app/views/spree/api/stock_locations/index.v1.rabl +7 -0
  112. data/app/views/spree/api/stock_locations/show.v1.rabl +8 -0
  113. data/app/views/spree/api/stock_movements/index.v1.rabl +7 -0
  114. data/app/views/spree/api/stock_movements/show.v1.rabl +5 -0
  115. data/app/views/spree/api/stock_transfers/receive.v1.rabl +5 -0
  116. data/app/views/spree/api/store_credit_events/mine.v1.rabl +10 -0
  117. data/app/views/spree/api/stores/index.v1.rabl +4 -0
  118. data/app/views/spree/api/stores/show.v1.rabl +2 -0
  119. data/app/views/spree/api/taxonomies/index.v1.rabl +7 -0
  120. data/app/views/spree/api/taxonomies/jstree.rabl +8 -0
  121. data/app/views/spree/api/taxonomies/nested.v1.rabl +11 -0
  122. data/app/views/spree/api/taxonomies/new.v1.rabl +3 -0
  123. data/app/views/spree/api/taxonomies/show.v1.rabl +15 -0
  124. data/app/views/spree/api/taxons/index.v1.rabl +12 -0
  125. data/app/views/spree/api/taxons/jstree.rabl +8 -0
  126. data/app/views/spree/api/taxons/new.v1.rabl +3 -0
  127. data/app/views/spree/api/taxons/show.v1.rabl +6 -0
  128. data/app/views/spree/api/taxons/taxons.v1.rabl +5 -0
  129. data/app/views/spree/api/transfer_items/show.v1.rabl +6 -0
  130. data/app/views/spree/api/users/index.v1.rabl +7 -0
  131. data/app/views/spree/api/users/new.v1.rabl +3 -0
  132. data/app/views/spree/api/users/show.v1.rabl +10 -0
  133. data/app/views/spree/api/variants/big.v1.rabl +17 -0
  134. data/app/views/spree/api/variants/index.v1.rabl +9 -0
  135. data/app/views/spree/api/variants/new.v1.rabl +2 -0
  136. data/app/views/spree/api/variants/show.v1.rabl +3 -0
  137. data/app/views/spree/api/variants/small.v1.rabl +17 -0
  138. data/app/views/spree/api/zones/index.v1.rabl +7 -0
  139. data/app/views/spree/api/zones/show.v1.rabl +6 -0
  140. data/config/initializers/metal_load_paths.rb +1 -0
  141. data/config/locales/en.yml +29 -0
  142. data/config/routes.rb +139 -0
  143. data/db/migrate/20100107141738_add_api_key_to_spree_users.rb +7 -0
  144. data/db/migrate/20120411123334_resize_api_key_field.rb +7 -0
  145. data/db/migrate/20120530054546_rename_api_key_to_spree_api_key.rb +7 -0
  146. data/db/migrate/20131017162334_add_index_to_user_spree_api_key.rb +7 -0
  147. data/lib/solidus_api.rb +1 -0
  148. data/lib/spree/api/engine.rb +38 -0
  149. data/lib/spree/api/responders/rabl_template.rb +31 -0
  150. data/lib/spree/api/responders.rb +11 -0
  151. data/lib/spree/api/testing_support/caching.rb +10 -0
  152. data/lib/spree/api/testing_support/helpers.rb +44 -0
  153. data/lib/spree/api/testing_support/setup.rb +16 -0
  154. data/lib/spree/api.rb +10 -0
  155. data/lib/spree_api.rb +3 -0
  156. data/script/rails +9 -0
  157. data/solidus_api.gemspec +21 -0
  158. data/spec/controllers/spree/api/addresses_controller_spec.rb +56 -0
  159. data/spec/controllers/spree/api/base_controller_spec.rb +164 -0
  160. data/spec/controllers/spree/api/checkouts_controller_spec.rb +386 -0
  161. data/spec/controllers/spree/api/classifications_controller_spec.rb +48 -0
  162. data/spec/controllers/spree/api/config_controller_spec.rb +23 -0
  163. data/spec/controllers/spree/api/countries_controller_spec.rb +48 -0
  164. data/spec/controllers/spree/api/credit_cards_controller_spec.rb +80 -0
  165. data/spec/controllers/spree/api/images_controller_spec.rb +93 -0
  166. data/spec/controllers/spree/api/inventory_units_controller_spec.rb +50 -0
  167. data/spec/controllers/spree/api/line_items_controller_spec.rb +186 -0
  168. data/spec/controllers/spree/api/option_types_controller_spec.rb +116 -0
  169. data/spec/controllers/spree/api/option_values_controller_spec.rb +135 -0
  170. data/spec/controllers/spree/api/orders_controller_spec.rb +759 -0
  171. data/spec/controllers/spree/api/payments_controller_spec.rb +254 -0
  172. data/spec/controllers/spree/api/product_properties_controller_spec.rb +116 -0
  173. data/spec/controllers/spree/api/products_controller_spec.rb +454 -0
  174. data/spec/controllers/spree/api/promotion_application_spec.rb +50 -0
  175. data/spec/controllers/spree/api/promotions_controller_spec.rb +64 -0
  176. data/spec/controllers/spree/api/properties_controller_spec.rb +102 -0
  177. data/spec/controllers/spree/api/return_authorizations_controller_spec.rb +173 -0
  178. data/spec/controllers/spree/api/shipments_controller_spec.rb +252 -0
  179. data/spec/controllers/spree/api/states_controller_spec.rb +82 -0
  180. data/spec/controllers/spree/api/stock_items_controller_spec.rb +307 -0
  181. data/spec/controllers/spree/api/stock_locations_controller_spec.rb +172 -0
  182. data/spec/controllers/spree/api/stock_movements_controller_spec.rb +84 -0
  183. data/spec/controllers/spree/api/stock_transfers_controller_spec.rb +83 -0
  184. data/spec/controllers/spree/api/store_credit_events_controller_spec.rb +68 -0
  185. data/spec/controllers/spree/api/stores_controller_spec.rb +133 -0
  186. data/spec/controllers/spree/api/taxonomies_controller_spec.rb +114 -0
  187. data/spec/controllers/spree/api/taxons_controller_spec.rb +177 -0
  188. data/spec/controllers/spree/api/transfer_items_controller_spec.rb +152 -0
  189. data/spec/controllers/spree/api/unauthenticated_products_controller_spec.rb +26 -0
  190. data/spec/controllers/spree/api/users_controller_spec.rb +153 -0
  191. data/spec/controllers/spree/api/variants_controller_spec.rb +235 -0
  192. data/spec/controllers/spree/api/zones_controller_spec.rb +115 -0
  193. data/spec/features/checkout_spec.rb +187 -0
  194. data/spec/fixtures/thinking-cat.jpg +0 -0
  195. data/spec/models/spree/legacy_user_spec.rb +45 -0
  196. data/spec/requests/rabl_cache_spec.rb +32 -0
  197. data/spec/shared_examples/protect_product_actions.rb +17 -0
  198. data/spec/spec_helper.rb +60 -0
  199. data/spec/support/controller_hacks.rb +38 -0
  200. data/spec/support/database_cleaner.rb +14 -0
  201. data/spec/support/have_attributes_matcher.rb +13 -0
  202. metadata +334 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8f7e1c99f480436edbb45f9d9e3d946879794a7f
4
+ data.tar.gz: 8cca45deec26d1b9f7dcbf03eb66f2dfb0f8ba01
5
+ SHA512:
6
+ metadata.gz: 54ddece7d71fafe19fdb104acd90b823ca011dd2fdec6c0e6df56e3a396994336fa1d2adb973a18b51ef5b07ef5bc49ed3e32494ea2be31b1f99fc990bf9b5bc
7
+ data.tar.gz: a7ff37cb7e28ffe0a6bbedb442a79256997cbf504623ae0f48b98fdb8dcc261236aa0f153bbf20d328352cb582f90dd683cfea90cad8025034ae7794681c1c68
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ ## Spree 2.4.0 (unreleased) ##
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ eval(File.read(File.dirname(__FILE__) + '/../common_spree_dependencies.rb'))
2
+
3
+ gem 'solidus_core', :path => '../core'
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2007-2014, Spree Commerce, Inc. and other contributors
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.
27
+
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/common_rake'
6
+ require 'rails/all'
7
+
8
+ RSpec::Core::RakeTask.new
9
+
10
+ task :default => :spec
11
+
12
+ desc "Generates a dummy app for testing"
13
+ task :test_app do
14
+ ENV['LIB_NAME'] = 'spree/api'
15
+ Rake::Task['common:test_app'].invoke
16
+ end
@@ -0,0 +1,43 @@
1
+ module Spree
2
+ module Api
3
+ class AddressesController < Spree::Api::BaseController
4
+ before_action :find_order
5
+
6
+ def show
7
+ authorize! :read, @order, order_token
8
+ find_address
9
+ respond_with(@address)
10
+ end
11
+
12
+ def update
13
+ authorize! :update, @order, order_token
14
+ find_address
15
+
16
+ if @address.update_attributes(address_params)
17
+ respond_with(@address, :default_template => :show)
18
+ else
19
+ invalid_resource!(@address)
20
+ end
21
+ end
22
+
23
+ private
24
+ def address_params
25
+ params.require(:address).permit(permitted_address_attributes)
26
+ end
27
+
28
+ def find_order
29
+ @order = Spree::Order.find_by!(number: order_id)
30
+ end
31
+
32
+ def find_address
33
+ @address = if @order.bill_address_id == params[:id].to_i
34
+ @order.bill_address
35
+ elsif @order.ship_address_id == params[:id].to_i
36
+ @order.ship_address
37
+ else
38
+ raise CanCan::AccessDenied
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,189 @@
1
+ require 'spree/api/responders'
2
+
3
+ module Spree
4
+ module Api
5
+ class BaseController < ActionController::Base
6
+ prepend_view_path Rails.root + "app/views"
7
+ append_view_path File.expand_path("../../../app/views", File.dirname(__FILE__))
8
+
9
+ self.responder = Spree::Api::Responders::AppResponder
10
+ respond_to :json
11
+
12
+ include CanCan::ControllerAdditions
13
+ include Spree::Core::ControllerHelpers::Store
14
+ include Spree::Core::ControllerHelpers::StrongParameters
15
+
16
+ class_attribute :admin_line_item_attributes
17
+ self.admin_line_item_attributes = [:price, :variant_id, :sku]
18
+
19
+ attr_accessor :current_api_user
20
+
21
+ class_attribute :error_notifier
22
+
23
+ before_action :set_content_type
24
+ before_action :load_user
25
+ before_action :authorize_for_order, if: Proc.new { order_token.present? }
26
+ before_action :authenticate_user
27
+ before_action :load_user_roles
28
+
29
+ rescue_from StandardError, with: :error_during_processing
30
+ rescue_from ActiveRecord::RecordNotFound, with: :not_found
31
+ rescue_from CanCan::AccessDenied, with: :unauthorized
32
+ rescue_from Spree::Core::GatewayError, with: :gateway_error
33
+
34
+ helper Spree::Api::ApiHelpers
35
+
36
+ def map_nested_attributes_keys(klass, attributes)
37
+ nested_keys = klass.nested_attributes_options.keys
38
+ attributes.inject({}) do |h, (k,v)|
39
+ key = nested_keys.include?(k.to_sym) ? "#{k}_attributes" : k
40
+ h[key] = v
41
+ h
42
+ end.with_indifferent_access
43
+ end
44
+
45
+ # users should be able to set price when importing orders via api
46
+ def permitted_line_item_attributes
47
+ if is_admin?
48
+ super + admin_line_item_attributes
49
+ else
50
+ super
51
+ end
52
+ end
53
+
54
+ protected
55
+
56
+ def is_admin?
57
+ current_api_user && current_api_user.has_spree_role?("admin")
58
+ end
59
+
60
+ private
61
+
62
+ def set_content_type
63
+ content_type = case params[:format]
64
+ when "json"
65
+ "application/json; charset=utf-8"
66
+ when "xml"
67
+ "text/xml; charset=utf-8"
68
+ end
69
+ headers["Content-Type"] = content_type
70
+ end
71
+
72
+ def load_user
73
+ @current_api_user ||= Spree.user_class.find_by(spree_api_key: api_key.to_s)
74
+ end
75
+
76
+ def authenticate_user
77
+ unless @current_api_user
78
+ if requires_authentication? && api_key.blank? && order_token.blank?
79
+ render "spree/api/errors/must_specify_api_key", :status => 401 and return
80
+ elsif order_token.blank? && (requires_authentication? || api_key.present?)
81
+ render "spree/api/errors/invalid_api_key", :status => 401 and return
82
+ end
83
+ end
84
+ end
85
+
86
+ def load_user_roles
87
+ @current_user_roles = if @current_api_user
88
+ @current_api_user.spree_roles.pluck(:name)
89
+ else
90
+ []
91
+ end
92
+ end
93
+
94
+ def unauthorized
95
+ render "spree/api/errors/unauthorized", status: 401 and return
96
+ end
97
+
98
+ def error_during_processing(exception)
99
+ Rails.logger.error exception.message
100
+ Rails.logger.error exception.backtrace.join("\n")
101
+
102
+ error_notifier.call(exception, self) if error_notifier
103
+
104
+ render text: { exception: exception.message }.to_json,
105
+ status: 422 and return
106
+ end
107
+
108
+ def gateway_error(exception)
109
+ @order.errors.add(:base, exception.message)
110
+ invalid_resource!(@order)
111
+ end
112
+
113
+ def requires_authentication?
114
+ Spree::Api::Config[:requires_authentication]
115
+ end
116
+
117
+ def not_found
118
+ render "spree/api/errors/not_found", status: 404 and return
119
+ end
120
+
121
+ def current_ability
122
+ Spree::Ability.new(current_api_user)
123
+ end
124
+
125
+ def current_currency
126
+ Spree::Config[:currency]
127
+ end
128
+ helper_method :current_currency
129
+
130
+ def invalid_resource!(resource)
131
+ @resource = resource
132
+ render "spree/api/errors/invalid_resource", :status => 422
133
+ end
134
+
135
+ def api_key
136
+ request.headers["X-Spree-Token"] || params[:token]
137
+ end
138
+ helper_method :api_key
139
+
140
+ def order_token
141
+ request.headers["X-Spree-Order-Token"] || params[:order_token]
142
+ end
143
+
144
+ def find_product(id)
145
+ product_scope.friendly.find(id.to_s)
146
+ rescue ActiveRecord::RecordNotFound
147
+ product_scope.find(id)
148
+ end
149
+
150
+ def product_scope
151
+ if is_admin?
152
+ scope = Product.with_deleted.accessible_by(current_ability, :read).includes(*product_includes)
153
+
154
+ unless params[:show_deleted]
155
+ scope = scope.not_deleted
156
+ end
157
+ else
158
+ scope = Product.accessible_by(current_ability, :read).active.includes(*product_includes)
159
+ end
160
+
161
+ scope
162
+ end
163
+
164
+ def variants_associations
165
+ [{ option_values: :option_type }, :default_price, :images]
166
+ end
167
+
168
+ def product_includes
169
+ [ :option_types, :taxons, product_properties: :property, variants: variants_associations, master: variants_associations ]
170
+ end
171
+
172
+ def order_id
173
+ params[:order_id] || params[:checkout_id] || params[:order_number]
174
+ end
175
+
176
+ def authorize_for_order
177
+ @order = Spree::Order.find_by(number: order_id)
178
+ authorize! :read, @order, order_token
179
+ end
180
+
181
+ def lock_order
182
+ OrderMutex.with_lock!(@order) { yield }
183
+ rescue Spree::OrderMutex::LockFailed => e
184
+ render text: e.message, status: 409
185
+ end
186
+
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,133 @@
1
+ module Spree
2
+ module Api
3
+ class CheckoutsController < Spree::Api::BaseController
4
+ before_filter :load_order, only: [:next, :advance, :update, :complete]
5
+ around_filter :lock_order, only: [:next, :advance, :update, :complete]
6
+ before_filter :update_order_state, only: [:next, :advance, :update, :complete]
7
+
8
+ rescue_from Spree::Order::InsufficientStock, with: :insufficient_stock_error
9
+
10
+ include Spree::Core::ControllerHelpers::Order
11
+ # This before_filter comes from Spree::Core::ControllerHelpers::Order
12
+ skip_before_action :set_current_order
13
+
14
+ def next
15
+ if @order.confirm?
16
+ ActiveSupport::Deprecation.warn "Using Spree::Api::CheckoutsController#next to transition to complete is deprecated. Please use #complete instead of #next.", caller
17
+ complete
18
+ return
19
+ end
20
+
21
+ authorize! :update, @order, order_token
22
+ if !expected_total_ok?(params[:expected_total])
23
+ respond_with(@order, default_template: 'spree/api/orders/expected_total_mismatch', status: 400)
24
+ return
25
+ end
26
+ authorize! :update, @order, order_token
27
+ @order.next!
28
+ respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
29
+ rescue StateMachines::InvalidTransition
30
+ respond_with(@order, default_template: 'spree/api/orders/could_not_transition', status: 422)
31
+ end
32
+
33
+ def advance
34
+ authorize! :update, @order, order_token
35
+ @order.contents.advance
36
+ respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
37
+ end
38
+
39
+ def complete
40
+ authorize! :update, @order, order_token
41
+ if !expected_total_ok?(params[:expected_total])
42
+ respond_with(@order, default_template: 'spree/api/orders/expected_total_mismatch', status: 400)
43
+ else
44
+ @order.complete!
45
+ respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
46
+ end
47
+ rescue StateMachines::InvalidTransition
48
+ respond_with(@order, default_template: 'spree/api/orders/could_not_transition', status: 422)
49
+ end
50
+
51
+ def update
52
+ authorize! :update, @order, order_token
53
+
54
+ if @order.update_from_params(params, permitted_checkout_attributes, request.headers.env)
55
+ if current_api_user.has_spree_role?('admin') && user_id.present?
56
+ @order.associate_user!(Spree.user_class.find(user_id))
57
+ end
58
+
59
+ return if after_update_attributes
60
+
61
+ if @order.completed? || @order.next
62
+ state_callback(:after)
63
+ respond_with(@order, default_template: 'spree/api/orders/show')
64
+ else
65
+ respond_with(@order, default_template: 'spree/api/orders/could_not_transition', status: 422)
66
+ end
67
+ else
68
+ invalid_resource!(@order)
69
+ end
70
+ end
71
+
72
+ private
73
+ def user_id
74
+ params[:order][:user_id] if params[:order]
75
+ end
76
+
77
+ def nested_params
78
+ map_nested_attributes_keys Order, params[:order] || {}
79
+ end
80
+
81
+ # Should be overriden if you have areas of your checkout that don't match
82
+ # up to a step within checkout_steps, such as a registration step
83
+ def skip_state_validation?
84
+ false
85
+ end
86
+
87
+ def load_order
88
+ @order = Spree::Order.find_by!(number: params[:id])
89
+ raise_insufficient_quantity and return if @order.insufficient_stock_lines.present?
90
+ end
91
+
92
+ def update_order_state
93
+ @order.state = params[:state] if params[:state]
94
+ state_callback(:before)
95
+ end
96
+
97
+ def raise_insufficient_quantity
98
+ respond_with(@order, default_template: 'spree/api/orders/insufficient_quantity')
99
+ end
100
+
101
+ def state_callback(before_or_after = :before)
102
+ method_name = :"#{before_or_after}_#{@order.state}"
103
+ send(method_name) if respond_to?(method_name, true)
104
+ end
105
+
106
+ def after_update_attributes
107
+ if nested_params && nested_params[:coupon_code].present?
108
+ handler = PromotionHandler::Coupon.new(@order).apply
109
+
110
+ if handler.error.present?
111
+ @coupon_message = handler.error
112
+ respond_with(@order, default_template: 'spree/api/orders/could_not_apply_coupon')
113
+ return true
114
+ end
115
+ end
116
+ false
117
+ end
118
+
119
+ def order_id
120
+ super || params[:id]
121
+ end
122
+
123
+ def expected_total_ok?(expected_total)
124
+ return true if expected_total.blank?
125
+ @order.total == BigDecimal(expected_total)
126
+ end
127
+
128
+ def insufficient_stock_error(exception)
129
+ render json: { errors: [I18n.t(:quantity_is_not_available, :scope => "spree.api.order")], type: 'insufficient_stock' }, status: 422
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module Api
3
+ class ClassificationsController < Spree::Api::BaseController
4
+ def update
5
+ authorize! :update, Product
6
+ authorize! :update, Taxon
7
+ classification = Spree::Classification.find_by(
8
+ :product_id => params[:product_id],
9
+ :taxon_id => params[:taxon_id]
10
+ )
11
+ # Because position we get back is 0-indexed.
12
+ # acts_as_list is 1-indexed.
13
+ classification.insert_at(params[:position].to_i + 1)
14
+ render :nothing => true
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ module Spree
2
+ module Api
3
+ class ConfigController < Spree::Api::BaseController
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,23 @@
1
+ module Spree
2
+ module Api
3
+ class CountriesController < Spree::Api::BaseController
4
+ skip_before_action :check_for_user_or_api_key
5
+ skip_before_action :authenticate_user
6
+
7
+ def index
8
+ @countries = Country.accessible_by(current_ability, :read).ransack(params[:q]).result.
9
+ includes(:states).order('name ASC').
10
+ page(params[:page]).per(params[:per_page])
11
+ country = Country.order("updated_at ASC").last
12
+ if stale?(country)
13
+ respond_with(@countries)
14
+ end
15
+ end
16
+
17
+ def show
18
+ @country = Country.accessible_by(current_ability, :read).find(params[:id])
19
+ respond_with(@country)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module Spree
2
+ module Api
3
+ class CreditCardsController < Spree::Api::BaseController
4
+ before_action :user
5
+
6
+ def index
7
+ @credit_cards = user
8
+ .credit_cards
9
+ .accessible_by(current_ability, :read)
10
+ .with_payment_profile
11
+ .ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
12
+ respond_with(@credit_cards)
13
+ end
14
+
15
+ private
16
+
17
+ def user
18
+ if params[:user_id].present?
19
+ @user ||= Spree::user_class.accessible_by(current_ability, :read).find(params[:user_id])
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,47 @@
1
+ module Spree
2
+ module Api
3
+ class ImagesController < Spree::Api::BaseController
4
+
5
+ def index
6
+ @images = scope.images.accessible_by(current_ability, :read)
7
+ respond_with(@images)
8
+ end
9
+
10
+ def show
11
+ @image = Image.accessible_by(current_ability, :read).find(params[:id])
12
+ respond_with(@image)
13
+ end
14
+
15
+ def create
16
+ authorize! :create, Image
17
+ @image = scope.images.create(image_params)
18
+ respond_with(@image, :status => 201, :default_template => :show)
19
+ end
20
+
21
+ def update
22
+ @image = scope.images.accessible_by(current_ability, :update).find(params[:id])
23
+ @image.update_attributes(image_params)
24
+ respond_with(@image, :default_template => :show)
25
+ end
26
+
27
+ def destroy
28
+ @image = scope.images.accessible_by(current_ability, :destroy).find(params[:id])
29
+ @image.destroy
30
+ respond_with(@image, :status => 204)
31
+ end
32
+
33
+ private
34
+ def image_params
35
+ params.require(:image).permit(permitted_image_attributes)
36
+ end
37
+
38
+ def scope
39
+ if params[:product_id]
40
+ scope = Spree::Product.friendly.find(params[:product_id])
41
+ elsif params[:variant_id]
42
+ scope = Spree::Variant.find(params[:variant_id])
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,52 @@
1
+ module Spree
2
+ module Api
3
+ class InventoryUnitsController < Spree::Api::BaseController
4
+ before_action :prepare_event, only: :update
5
+
6
+ def show
7
+ @inventory_unit = inventory_unit
8
+ respond_with(@inventory_unit)
9
+ end
10
+
11
+ def update
12
+ authorize! :update, inventory_unit.order
13
+
14
+ inventory_unit.transaction do
15
+ if inventory_unit.update_attributes(inventory_unit_params)
16
+ fire
17
+ render :show, :status => 200
18
+ else
19
+ invalid_resource!(inventory_unit)
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def inventory_unit
27
+ @inventory_unit ||= InventoryUnit.accessible_by(current_ability, :read).find(params[:id])
28
+ end
29
+
30
+ def prepare_event
31
+ return unless @event = params[:fire]
32
+
33
+ can_event = "can_#{@event}?"
34
+
35
+ unless inventory_unit.respond_to?(can_event) &&
36
+ inventory_unit.send(can_event)
37
+ render :text => { :exception => "cannot transition to #{@event}" }.to_json,
38
+ :status => 200
39
+ false
40
+ end
41
+ end
42
+
43
+ def fire
44
+ inventory_unit.send("#{@event}!") if @event
45
+ end
46
+
47
+ def inventory_unit_params
48
+ params.require(:inventory_unit).permit(permitted_inventory_unit_attributes)
49
+ end
50
+ end
51
+ end
52
+ end