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
@@ -0,0 +1,74 @@
1
+ module Spree
2
+ module Api
3
+ class LineItemsController < Spree::Api::BaseController
4
+ class_attribute :line_item_options
5
+
6
+ self.line_item_options = []
7
+
8
+ before_filter :load_order, only: [:create, :update, :destroy]
9
+ around_filter :lock_order, only: [:create, :update, :destroy]
10
+
11
+ def create
12
+ variant = Spree::Variant.find(params[:line_item][:variant_id])
13
+ @line_item = @order.contents.add(
14
+ variant,
15
+ params[:line_item][:quantity] || 1,
16
+ {
17
+ stock_location_quantities: params[:line_item][:stock_location_quantities]
18
+ }.merge(line_item_params[:options] || {})
19
+ )
20
+
21
+ if @line_item.errors.empty?
22
+ respond_with(@line_item, status: 201, default_template: :show)
23
+ else
24
+ invalid_resource!(@line_item)
25
+ end
26
+ end
27
+
28
+ def update
29
+ @line_item = find_line_item
30
+ if @order.contents.update_cart(line_items_attributes)
31
+ @line_item.reload
32
+ respond_with(@line_item, default_template: :show)
33
+ else
34
+ invalid_resource!(@line_item)
35
+ end
36
+ end
37
+
38
+ def destroy
39
+ @line_item = find_line_item
40
+ variant = Spree::Variant.unscoped.find(@line_item.variant_id)
41
+ @order.contents.remove(variant, @line_item.quantity)
42
+ respond_with(@line_item, status: 204)
43
+ end
44
+
45
+ private
46
+ def load_order
47
+ @order ||= Spree::Order.includes(:line_items).find_by!(number: order_id)
48
+ authorize! :update, @order, order_token
49
+ end
50
+
51
+ def find_line_item
52
+ id = params[:id].to_i
53
+ @order.line_items.detect { |line_item| line_item.id == id } or
54
+ raise ActiveRecord::RecordNotFound
55
+ end
56
+
57
+ def line_items_attributes
58
+ {line_items_attributes: {
59
+ id: params[:id],
60
+ quantity: params[:line_item][:quantity],
61
+ options: line_item_params[:options] || {}
62
+ }}
63
+ end
64
+
65
+ def line_item_params
66
+ params.require(:line_item).permit(
67
+ :quantity,
68
+ :variant_id,
69
+ options: line_item_options
70
+ )
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,49 @@
1
+ module Spree
2
+ module Api
3
+ class OptionTypesController < Spree::Api::BaseController
4
+ def index
5
+ if params[:ids]
6
+ @option_types = Spree::OptionType.includes(:option_values).accessible_by(current_ability, :read).where(id: params[:ids].split(','))
7
+ else
8
+ @option_types = Spree::OptionType.includes(:option_values).accessible_by(current_ability, :read).load.ransack(params[:q]).result
9
+ end
10
+ respond_with(@option_types)
11
+ end
12
+
13
+ def show
14
+ @option_type = Spree::OptionType.accessible_by(current_ability, :read).find(params[:id])
15
+ respond_with(@option_type)
16
+ end
17
+
18
+ def create
19
+ authorize! :create, Spree::OptionType
20
+ @option_type = Spree::OptionType.new(option_type_params)
21
+ if @option_type.save
22
+ render :show, :status => 201
23
+ else
24
+ invalid_resource!(@option_type)
25
+ end
26
+ end
27
+
28
+ def update
29
+ @option_type = Spree::OptionType.accessible_by(current_ability, :update).find(params[:id])
30
+ if @option_type.update_attributes(option_type_params)
31
+ render :show
32
+ else
33
+ invalid_resource!(@option_type)
34
+ end
35
+ end
36
+
37
+ def destroy
38
+ @option_type = Spree::OptionType.accessible_by(current_ability, :destroy).find(params[:id])
39
+ @option_type.destroy
40
+ render :text => nil, :status => 204
41
+ end
42
+
43
+ private
44
+ def option_type_params
45
+ params.require(:option_type).permit(permitted_option_type_attributes)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,58 @@
1
+ module Spree
2
+ module Api
3
+ class OptionValuesController < Spree::Api::BaseController
4
+ def index
5
+ if params[:ids]
6
+ @option_values = scope.where(:id => params[:ids])
7
+ else
8
+ @option_values = scope.ransack(params[:q]).result
9
+ end
10
+ respond_with(@option_values)
11
+ end
12
+
13
+ def show
14
+ @option_value = scope.find(params[:id])
15
+ respond_with(@option_value)
16
+ end
17
+
18
+ def create
19
+ authorize! :create, Spree::OptionValue
20
+ @option_value = scope.new(option_value_params)
21
+ if @option_value.save
22
+ render :show, :status => 201
23
+ else
24
+ invalid_resource!(@option_value)
25
+ end
26
+ end
27
+
28
+ def update
29
+ @option_value = scope.accessible_by(current_ability, :update).find(params[:id])
30
+ if @option_value.update_attributes(option_value_params)
31
+ render :show
32
+ else
33
+ invalid_resource!(@option_value)
34
+ end
35
+ end
36
+
37
+ def destroy
38
+ @option_value = scope.accessible_by(current_ability, :destroy).find(params[:id])
39
+ @option_value.destroy
40
+ render :text => nil, :status => 204
41
+ end
42
+
43
+ private
44
+
45
+ def scope
46
+ if params[:option_type_id]
47
+ @scope ||= Spree::OptionType.find(params[:option_type_id]).option_values.accessible_by(current_ability, :read)
48
+ else
49
+ @scope ||= Spree::OptionValue.accessible_by(current_ability, :read).load
50
+ end
51
+ end
52
+
53
+ def option_value_params
54
+ params.require(:option_value).permit(permitted_option_value_attributes)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,155 @@
1
+ module Spree
2
+ module Api
3
+ class OrdersController < Spree::Api::BaseController
4
+ class_attribute :admin_shipment_attributes
5
+ self.admin_shipment_attributes = [:shipping_method, :stock_location, :inventory_units => [:variant_id, :sku]]
6
+
7
+ class_attribute :admin_order_attributes
8
+ self.admin_order_attributes = [:import, :number, :completed_at, :locked_at, :channel]
9
+
10
+ skip_before_action :check_for_user_or_api_key, only: :apply_coupon_code
11
+ skip_before_action :authenticate_user, only: :apply_coupon_code
12
+
13
+ before_action :find_order, except: [:create, :mine, :current, :index, :update]
14
+
15
+ before_filter :find_order, except: [:create, :mine, :current, :index]
16
+ around_filter :lock_order, except: [:create, :mine, :current, :index]
17
+
18
+ # Dynamically defines our stores checkout steps to ensure we check authorization on each step.
19
+ Order.checkout_steps.keys.each do |step|
20
+ define_method step do
21
+ authorize! :update, @order, params[:token]
22
+ end
23
+ end
24
+
25
+ def cancel
26
+ authorize! :update, @order, params[:token]
27
+ @order.cancel!
28
+ respond_with(@order, :default_template => :show)
29
+ end
30
+
31
+ def create
32
+ authorize! :create, Order
33
+ order_user = if @current_user_roles.include?('admin') && order_params[:user_id]
34
+ Spree.user_class.find(order_params[:user_id])
35
+ else
36
+ current_api_user
37
+ end
38
+
39
+ import_params = if @current_user_roles.include?("admin")
40
+ params[:order].present? ? params[:order].permit! : {}
41
+ else
42
+ order_params
43
+ end
44
+
45
+ @order = Spree::Core::Importer::Order.import(order_user, import_params)
46
+ respond_with(@order, default_template: :show, status: 201)
47
+ end
48
+
49
+ def empty
50
+ authorize! :update, @order, order_token
51
+ @order.empty!
52
+ render text: nil, status: 204
53
+ end
54
+
55
+ def index
56
+ authorize! :index, Order
57
+ @orders = Order.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
58
+ respond_with(@orders)
59
+ end
60
+
61
+ def show
62
+ authorize! :show, @order, order_token
63
+ respond_with(@order)
64
+ end
65
+
66
+ def update
67
+ authorize! :update, @order, order_token
68
+
69
+ result = if request.patch?
70
+ # This will update the order without a checkout reset.
71
+ @order.update_attributes(order_params)
72
+ else
73
+ # This will reset checkout back to address and delete all shipments.
74
+ @order.contents.update_cart(order_params)
75
+ end
76
+
77
+ if result
78
+ user_id = params[:order][:user_id]
79
+ if current_api_user.has_spree_role?('admin') && user_id
80
+ @order.associate_user!(Spree.user_class.find(user_id))
81
+ end
82
+ respond_with(@order, default_template: :show)
83
+ else
84
+ invalid_resource!(@order)
85
+ end
86
+ end
87
+
88
+ def current
89
+ if current_api_user && @order = current_api_user.last_incomplete_spree_order(store: current_store)
90
+ respond_with(@order, default_template: :show, locals: { root_object: @order })
91
+ else
92
+ head :no_content
93
+ end
94
+ end
95
+
96
+ def mine
97
+ if current_api_user
98
+ @orders = current_api_user.orders.by_store(current_store).reverse_chronological.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
99
+ else
100
+ render "spree/api/errors/unauthorized", status: :unauthorized
101
+ end
102
+ end
103
+
104
+ def apply_coupon_code
105
+ authorize! :update, @order, order_token
106
+ @order.coupon_code = params[:coupon_code]
107
+ @handler = PromotionHandler::Coupon.new(@order).apply
108
+ status = @handler.successful? ? 200 : 422
109
+ render "spree/api/promotions/handler", :status => status
110
+ end
111
+
112
+ private
113
+ def order_params
114
+ if params[:order]
115
+ normalize_params
116
+ params.require(:order).permit(permitted_order_attributes)
117
+ else
118
+ {}
119
+ end
120
+ end
121
+
122
+ def normalize_params
123
+ params[:order][:payments_attributes] = params[:order].delete(:payments) if params[:order][:payments]
124
+ params[:order][:shipments_attributes] = params[:order].delete(:shipments) if params[:order][:shipments]
125
+ params[:order][:line_items_attributes] = params[:order].delete(:line_items) if params[:order][:line_items]
126
+ params[:order][:ship_address_attributes] = params[:order].delete(:ship_address) if params[:order][:ship_address].present?
127
+ params[:order][:bill_address_attributes] = params[:order].delete(:bill_address) if params[:order][:bill_address].present?
128
+ end
129
+
130
+ def permitted_order_attributes
131
+ if is_admin?
132
+ super + admin_order_attributes
133
+ else
134
+ super
135
+ end
136
+ end
137
+
138
+ def permitted_shipment_attributes
139
+ if is_admin?
140
+ super + admin_shipment_attributes
141
+ else
142
+ super
143
+ end
144
+ end
145
+
146
+ def find_order(lock = false)
147
+ @order = Spree::Order.find_by!(number: params[:id])
148
+ end
149
+
150
+ def order_id
151
+ super || params[:id]
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,81 @@
1
+ module Spree
2
+ module Api
3
+ class PaymentsController < Spree::Api::BaseController
4
+
5
+ before_filter :find_order
6
+ around_filter :lock_order, only: [:create, :update, :destroy, :authorize, :capture, :purchase, :void, :credit]
7
+ before_filter :find_payment, only: [:update, :show, :authorize, :purchase, :capture, :void, :credit]
8
+
9
+ def index
10
+ @payments = @order.payments.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
11
+ respond_with(@payments)
12
+ end
13
+
14
+ def new
15
+ @payment_methods = Spree::PaymentMethod.available
16
+ respond_with(@payment_method)
17
+ end
18
+
19
+ def create
20
+ @payment = @order.payments.build(payment_params)
21
+ if @payment.save
22
+ respond_with(@payment, status: 201, default_template: :show)
23
+ else
24
+ invalid_resource!(@payment)
25
+ end
26
+ end
27
+
28
+ def update
29
+ authorize! params[:action], @payment
30
+ if ! @payment.pending?
31
+ render 'update_forbidden', status: 403
32
+ elsif @payment.update_attributes(payment_params)
33
+ respond_with(@payment, default_template: :show)
34
+ else
35
+ invalid_resource!(@payment)
36
+ end
37
+ end
38
+
39
+ def show
40
+ respond_with(@payment)
41
+ end
42
+
43
+ def authorize
44
+ perform_payment_action(:authorize)
45
+ end
46
+
47
+ def capture
48
+ perform_payment_action(:capture)
49
+ end
50
+
51
+ def purchase
52
+ perform_payment_action(:purchase)
53
+ end
54
+
55
+ def void
56
+ perform_payment_action(:void_transaction)
57
+ end
58
+
59
+ private
60
+
61
+ def find_order
62
+ @order = Spree::Order.find_by(number: order_id)
63
+ authorize! :read, @order, order_token
64
+ end
65
+
66
+ def find_payment
67
+ @payment = @order.payments.find(params[:id])
68
+ end
69
+
70
+ def perform_payment_action(action, *args)
71
+ authorize! action, Payment
72
+ @payment.send("#{action}!", *args)
73
+ respond_with(@payment, default_template: :show)
74
+ end
75
+
76
+ def payment_params
77
+ params.require(:payment).permit(permitted_payment_attributes)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,72 @@
1
+ module Spree
2
+ module Api
3
+ class ProductPropertiesController < Spree::Api::BaseController
4
+
5
+ before_action :find_product
6
+ before_action :product_property, only: [:show, :update, :destroy]
7
+
8
+ def index
9
+ @product_properties = @product.product_properties.accessible_by(current_ability, :read).
10
+ ransack(params[:q]).result.
11
+ page(params[:page]).per(params[:per_page])
12
+ respond_with(@product_properties)
13
+ end
14
+
15
+ def show
16
+ respond_with(@product_property)
17
+ end
18
+
19
+ def new
20
+ end
21
+
22
+ def create
23
+ authorize! :create, ProductProperty
24
+ @product_property = @product.product_properties.new(product_property_params)
25
+ if @product_property.save
26
+ respond_with(@product_property, status: 201, default_template: :show)
27
+ else
28
+ invalid_resource!(@product_property)
29
+ end
30
+ end
31
+
32
+ def update
33
+ if @product_property
34
+ authorize! :update, @product_property
35
+ @product_property.update_attributes(product_property_params)
36
+ respond_with(@product_property, status: 200, default_template: :show)
37
+ else
38
+ invalid_resource!(@product_property)
39
+ end
40
+ end
41
+
42
+ def destroy
43
+ if @product_property
44
+ authorize! :destroy, @product_property
45
+ @product_property.destroy
46
+ respond_with(@product_property, status: 204)
47
+ else
48
+ invalid_resource!(@product_property)
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def find_product
55
+ @product = super(params[:product_id])
56
+ authorize! :read, @product
57
+ end
58
+
59
+ def product_property
60
+ if @product
61
+ @product_property ||= @product.product_properties.find_by(id: params[:id])
62
+ @product_property ||= @product.product_properties.includes(:property).where(spree_properties: { name: params[:id] }).first
63
+ authorize! :read, @product_property
64
+ end
65
+ end
66
+
67
+ def product_property_params
68
+ params.require(:product_property).permit(permitted_product_properties_attributes)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,129 @@
1
+ module Spree
2
+ module Api
3
+ class ProductsController < Spree::Api::BaseController
4
+
5
+ def index
6
+ if params[:ids]
7
+ ids = params[:ids].split(",").flatten
8
+ @products = product_scope.where(:id => ids)
9
+ else
10
+ @products = product_scope.ransack(params[:q]).result
11
+ end
12
+
13
+ @products = @products.distinct.page(params[:page]).per(params[:per_page])
14
+ expires_in 15.minutes, :public => true
15
+ headers['Surrogate-Control'] = "max-age=#{15.minutes}"
16
+ respond_with(@products)
17
+ end
18
+
19
+ def show
20
+ @product = find_product(params[:id])
21
+ expires_in 15.minutes, :public => true
22
+ headers['Surrogate-Control'] = "max-age=#{15.minutes}"
23
+ headers['Surrogate-Key'] = "product_id=1"
24
+ respond_with(@product)
25
+ end
26
+
27
+ # Takes besides the products attributes either an array of variants or
28
+ # an array of option types.
29
+ #
30
+ # By submitting an array of variants the option types will be created
31
+ # using the *name* key in options hash. e.g
32
+ #
33
+ # product: {
34
+ # ...
35
+ # variants: {
36
+ # price: 19.99,
37
+ # sku: "hey_you",
38
+ # options: [
39
+ # { name: "size", value: "small" },
40
+ # { name: "color", value: "black" }
41
+ # ]
42
+ # }
43
+ # }
44
+ #
45
+ # Or just pass in the option types hash:
46
+ #
47
+ # product: {
48
+ # ...
49
+ # option_types: ['size', 'color']
50
+ # }
51
+ #
52
+ # By passing the shipping category name you can fetch or create that
53
+ # shipping category on the fly. e.g.
54
+ #
55
+ # product: {
56
+ # ...
57
+ # shipping_category: "Free Shipping Items"
58
+ # }
59
+ #
60
+ def create
61
+ authorize! :create, Product
62
+ params[:product][:available_on] ||= Time.now
63
+ set_up_shipping_category
64
+
65
+ options = { variants_attrs: variants_params, options_attrs: option_types_params }
66
+ @product = Core::Importer::Product.new(nil, product_params, options).create
67
+
68
+ if @product.persisted?
69
+ respond_with(@product, :status => 201, :default_template => :show)
70
+ else
71
+ invalid_resource!(@product)
72
+ end
73
+ end
74
+
75
+ def update
76
+ @product = find_product(params[:id])
77
+ authorize! :update, @product
78
+
79
+ options = { variants_attrs: variants_params, options_attrs: option_types_params }
80
+ @product = Core::Importer::Product.new(@product, product_params, options).update
81
+
82
+ if @product.errors.empty?
83
+ respond_with(@product.reload, :status => 200, :default_template => :show)
84
+ else
85
+ invalid_resource!(@product)
86
+ end
87
+ end
88
+
89
+ def destroy
90
+ @product = find_product(params[:id])
91
+ authorize! :destroy, @product
92
+ @product.destroy
93
+ respond_with(@product, :status => 204)
94
+ end
95
+
96
+ private
97
+ def product_params
98
+ product_params = params.require(:product).permit(permitted_product_attributes)
99
+ if product_params[:taxon_ids].present?
100
+ product_params[:taxon_ids] = product_params[:taxon_ids].split(',')
101
+ end
102
+ product_params
103
+ end
104
+
105
+ def variants_params
106
+ variants_key = if params[:product].has_key? :variants
107
+ :variants
108
+ else
109
+ :variants_attributes
110
+ end
111
+
112
+ params.require(:product).permit(
113
+ variants_key => [permitted_variant_attributes, :id],
114
+ ).delete(variants_key) || []
115
+ end
116
+
117
+ def option_types_params
118
+ params[:product].fetch(:option_types, [])
119
+ end
120
+
121
+ def set_up_shipping_category
122
+ if shipping_category = params[:product].delete(:shipping_category)
123
+ id = ShippingCategory.find_or_create_by(name: shipping_category).id
124
+ params[:product][:shipping_category_id] = id
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,26 @@
1
+ module Spree
2
+ module Api
3
+ class PromotionsController < Spree::Api::BaseController
4
+ before_filter :requires_admin
5
+ before_filter :load_promotion
6
+
7
+ def show
8
+ if @promotion
9
+ respond_with(@promotion, default_template: :show)
10
+ else
11
+ raise ActiveRecord::RecordNotFound
12
+ end
13
+ end
14
+
15
+ private
16
+ def requires_admin
17
+ return if @current_user_roles.include?("admin")
18
+ unauthorized and return
19
+ end
20
+
21
+ def load_promotion
22
+ @promotion = Spree::Promotion.find_by_id(params[:id]) || Spree::Promotion.with_coupon_code(params[:id])
23
+ end
24
+ end
25
+ end
26
+ end