mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-04-01 06:41:41 +00:00
Merge pull request #6960 from andrewpbrett/namespace-api
Namespace existing API endpoints to api/v0/*
This commit is contained in:
@@ -1170,7 +1170,7 @@ Style/FrozenStringLiteralComment:
|
||||
- 'engines/order_management/app/services/reports/renderers/base.rb'
|
||||
- 'engines/order_management/app/services/reports/report_data/base.rb'
|
||||
- 'engines/web/app/controllers/web/angular_templates_controller.rb'
|
||||
- 'engines/web/app/controllers/web/api/cookies_consent_controller.rb'
|
||||
- 'engines/web/app/controllers/web/api/v0/cookies_consent_controller.rb'
|
||||
- 'engines/web/app/controllers/web/application_controller.rb'
|
||||
- 'engines/web/app/helpers/web/cookies_policy_helper.rb'
|
||||
- 'engines/web/lib/web/cookies_consent.rb'
|
||||
|
||||
@@ -147,7 +147,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
if confirm("Are you sure?")
|
||||
$http(
|
||||
method: "DELETE"
|
||||
url: "/api/products/" + product.id
|
||||
url: "/api/v0/products/" + product.id
|
||||
).success (data) ->
|
||||
$scope.products.splice $scope.products.indexOf(product), 1
|
||||
DirtyProducts.deleteProduct product.id
|
||||
@@ -162,7 +162,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
if confirm(t("are_you_sure"))
|
||||
$http(
|
||||
method: "DELETE"
|
||||
url: "/api/products/" + product.permalink_live + "/variants/" + variant.id
|
||||
url: "/api/v0/products/" + product.permalink_live + "/variants/" + variant.id
|
||||
).success (data) ->
|
||||
$scope.removeVariant(product, variant)
|
||||
else
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
angular.module('admin.enterpriseFees').directive 'spreeDeleteResource', ->
|
||||
(scope, element, attrs) ->
|
||||
if scope.enterprise_fee.id
|
||||
url = '/api/enterprise_fees/' + scope.enterprise_fee.id
|
||||
url = '/api/v0/enterprise_fees/' + scope.enterprise_fee.id
|
||||
html = '<a href="' + url + '" class="delete-resource icon_link icon-trash no-text" data-action="remove" data-confirm="' + t('are_you_sure') + '" url="' + url + '"></a>'
|
||||
#var html = '<a href="'+url+'" class="delete-resource" data-confirm="Are you sure?"><img alt="Delete" src="/assets/admin/icons/delete.png" /> Delete</a>';
|
||||
element.append html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module("admin.indexUtils").factory "resources", ($resource) ->
|
||||
LineItem = $resource '/api/orders/:order_number/line_items/:line_item_id.json',
|
||||
LineItem = $resource '/api/v0/orders/:order_number/line_items/:line_item_id.json',
|
||||
{ order_number: '@order_number', line_item_id: '@line_item_id'},
|
||||
'update': { method: 'PUT' }
|
||||
Customer = $resource '/admin/customers/:customer_id.json',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module('admin.orderCycles').factory('ExchangeProduct', ($resource) ->
|
||||
ExchangeProductResource = $resource('/api/exchanges/:exchange_id/products.json', {}, {
|
||||
ExchangeProductResource = $resource('/api/v0/exchanges/:exchange_id/products.json', {}, {
|
||||
'index': { method: 'GET' }
|
||||
'variant_count': { method: 'GET', params: { action_name: "variant_count" }}
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ angular.module("ofn.admin").factory "ProductImageService", (FileUploader, SpreeA
|
||||
autoUpload: true
|
||||
|
||||
configure: (product) =>
|
||||
@imageUploader.url = "/api/product_images/#{product.id}"
|
||||
@imageUploader.url = "/api/v0/product_images/#{product.id}"
|
||||
@imagePreview = product.image_url
|
||||
@imageUploader.onSuccessItem = (image, response) =>
|
||||
product.thumb_url = response.thumb_url
|
||||
|
||||
@@ -9,12 +9,12 @@ angular.module("admin.resources").factory 'EnterpriseResource', ($resource) ->
|
||||
'update':
|
||||
method: 'PUT'
|
||||
'removeLogo':
|
||||
url: '/api/enterprises/:id/logo.json'
|
||||
url: '/api/v0/enterprises/:id/logo.json'
|
||||
method: 'DELETE'
|
||||
'removePromoImage':
|
||||
url: '/api/enterprises/:id/promo_image.json'
|
||||
url: '/api/v0/enterprises/:id/promo_image.json'
|
||||
method: 'DELETE'
|
||||
'removeTermsAndConditions':
|
||||
url: '/api/enterprises/:id/terms_and_conditions.json'
|
||||
url: '/api/v0/enterprises/:id/terms_and_conditions.json'
|
||||
method: 'DELETE'
|
||||
})
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
angular.module("admin.resources").factory 'OrderResource', ($resource) ->
|
||||
$resource('/admin/orders/:id/:action.json', {}, {
|
||||
'index':
|
||||
url: '/api/orders.json'
|
||||
url: '/api/v0/orders.json'
|
||||
method: 'GET'
|
||||
'update':
|
||||
method: 'PUT'
|
||||
'capture':
|
||||
url: '/api/orders/:id/capture.json'
|
||||
url: '/api/v0/orders/:id/capture.json'
|
||||
method: 'PUT'
|
||||
params:
|
||||
id: '@id'
|
||||
'ship':
|
||||
url: '/api/orders/:id/ship.json'
|
||||
url: '/api/v0/orders/:id/ship.json'
|
||||
method: 'PUT'
|
||||
params:
|
||||
id: '@id'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
angular.module("admin.resources").factory 'ProductResource', ($resource) ->
|
||||
$resource('/admin/product/:id/:action.json', {}, {
|
||||
'index':
|
||||
url: '/api/products/bulk_products.json'
|
||||
url: '/api/v0/products/bulk_products.json'
|
||||
method: 'GET'
|
||||
})
|
||||
|
||||
@@ -10,8 +10,8 @@ angular.module("ofn.admin").factory "BulkProducts", (ProductResource, dataFetche
|
||||
angular.extend(@pagination, data.pagination)
|
||||
|
||||
cloneProduct: (product) ->
|
||||
$http.post("/api/products/" + product.id + "/clone").success (data) =>
|
||||
dataFetcher("/api/products/" + data.id + "?template=bulk_show").then (newProduct) =>
|
||||
$http.post("/api/v0/products/" + product.id + "/clone").success (data) =>
|
||||
dataFetcher("/api/v0/products/" + data.id + "?template=bulk_show").then (newProduct) =>
|
||||
@unpackProduct newProduct
|
||||
@insertProductAfter(product, newProduct)
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl",
|
||||
$scope.fetchProducts()
|
||||
|
||||
$scope.fetchProducts = ->
|
||||
url = "/api/products/overridable?page=::page::;per_page=100"
|
||||
url = "/api/v0/products/overridable?page=::page::;per_page=100"
|
||||
PagedFetcher.fetch url, $scope.addProducts
|
||||
|
||||
$scope.addProducts = (data) ->
|
||||
|
||||
@@ -24,7 +24,7 @@ Darkswarm.controller "HubNodeCtrl", ($scope, HashNavigation, CurrentHub, $http,
|
||||
$scope.shopfront_loading = true
|
||||
$scope.toggle_tab(event)
|
||||
|
||||
$http.get("/api/shops/" + $scope.hub.id)
|
||||
$http.get("/api/v0/shops/" + $scope.hub.id)
|
||||
.success (data) ->
|
||||
$scope.shopfront_loading = false
|
||||
$scope.hub = data
|
||||
|
||||
@@ -24,7 +24,7 @@ Darkswarm.controller "ProducerNodeCtrl", ($scope, HashNavigation, $anchorScroll,
|
||||
$scope.shopfront_loading = true
|
||||
$scope.toggle_tab(event)
|
||||
|
||||
$http.get("/api/shops/" + $scope.producer.id)
|
||||
$http.get("/api/v0/shops/" + $scope.producer.id)
|
||||
.success (data) ->
|
||||
$scope.shopfront_loading = false
|
||||
$scope.producer = data
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module("Darkswarm").factory 'Customer', ($resource, $injector, Messages) ->
|
||||
Customer = $resource('/api/customers/:id/:action.json', {}, {
|
||||
Customer = $resource('/api/v0/customers/:id/:action.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
isArray: true
|
||||
|
||||
@@ -8,5 +8,5 @@ Darkswarm.factory "EnterpriseImageService", (FileUploader, spreeApiKey) ->
|
||||
autoUpload: true
|
||||
|
||||
configure: (enterprise) =>
|
||||
@imageUploader.url = "/api/enterprises/#{enterprise.id}/update_image"
|
||||
@imageUploader.url = "/api/v0/enterprises/#{enterprise.id}/update_image"
|
||||
@imageUploader.onSuccessItem = (image, response) => @imageSrc = response
|
||||
|
||||
@@ -5,7 +5,7 @@ Darkswarm.factory "EnterpriseModal", ($modal, $rootScope, $http)->
|
||||
scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise
|
||||
scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1
|
||||
|
||||
$http.get("/api/shops/" + enterprise.id).success (data) ->
|
||||
$http.get("/api/v0/shops/" + enterprise.id).success (data) ->
|
||||
scope.enterprise = data
|
||||
$modal.open(templateUrl: "enterprise_modal.html", scope: scope)
|
||||
.error (data) ->
|
||||
|
||||
@@ -18,7 +18,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
|
||||
Loading.message = t('creating') + " " + @enterprise.name
|
||||
$http(
|
||||
method: "POST"
|
||||
url: "/api/enterprises"
|
||||
url: "/api/v0/enterprises"
|
||||
data:
|
||||
enterprise: @prepare()
|
||||
params:
|
||||
@@ -42,7 +42,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
|
||||
Loading.message = t('updating') + " " + @enterprise.name
|
||||
$http(
|
||||
method: "PUT"
|
||||
url: "/api/enterprises/#{@enterprise.id}"
|
||||
url: "/api/v0/enterprises/#{@enterprise.id}"
|
||||
data:
|
||||
enterprise: @prepare()
|
||||
params:
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
Darkswarm.factory 'OrderCycleResource', ($resource) ->
|
||||
$resource('/api/order_cycles/:id.json', {}, {
|
||||
$resource('/api/v0/order_cycles/:id.json', {}, {
|
||||
'products':
|
||||
method: 'GET'
|
||||
isArray: true
|
||||
url: '/api/order_cycles/:id/products.json'
|
||||
url: '/api/v0/order_cycles/:id/products.json'
|
||||
params:
|
||||
id: '@id'
|
||||
'taxons':
|
||||
method: 'GET'
|
||||
isArray: true
|
||||
url: '/api/order_cycles/:id/taxons.json'
|
||||
url: '/api/v0/order_cycles/:id/taxons.json'
|
||||
params:
|
||||
id: '@id'
|
||||
'properties':
|
||||
method: 'GET'
|
||||
isArray: true
|
||||
url: '/api/order_cycles/:id/properties.json'
|
||||
url: '/api/v0/order_cycles/:id/properties.json'
|
||||
params:
|
||||
id: '@id'
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Darkswarm.factory 'ShopsResource', ($resource) ->
|
||||
$resource('/api/shops/:id.json', {}, {
|
||||
$resource('/api/v0/shops/:id.json', {}, {
|
||||
'closed_shops':
|
||||
method: 'GET'
|
||||
isArray: true
|
||||
url: '/api/shops/closed_shops.json'
|
||||
url: '/api/v0/shops/closed_shops.json'
|
||||
})
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
# Base controller for OFN's API
|
||||
require_dependency 'spree/api/controller_setup'
|
||||
require "spree/core/controller_helpers/ssl"
|
||||
|
||||
module Api
|
||||
class BaseController < ActionController::Metal
|
||||
include RawParams
|
||||
include ActionController::StrongParameters
|
||||
include ActionController::RespondWith
|
||||
include Spree::Api::ControllerSetup
|
||||
include Spree::Core::ControllerHelpers::SSL
|
||||
include ::ActionController::Head
|
||||
include ::ActionController::ConditionalGet
|
||||
include ActionView::Layouts
|
||||
|
||||
layout false
|
||||
|
||||
attr_accessor :current_api_user
|
||||
|
||||
before_action :set_content_type
|
||||
before_action :authenticate_user
|
||||
|
||||
rescue_from Exception, with: :error_during_processing
|
||||
rescue_from CanCan::AccessDenied, with: :unauthorized
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
||||
|
||||
helper Spree::Api::ApiHelpers
|
||||
|
||||
ssl_allowed
|
||||
|
||||
# Include these because we inherit from ActionController::Metal
|
||||
# rather than ActionController::Base and these are required for AMS
|
||||
include ActionController::Serialization
|
||||
include ActionController::UrlFor
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
use_renderers :json
|
||||
check_authorization
|
||||
|
||||
def respond_with_conflict(json_hash)
|
||||
render json: json_hash, status: :conflict
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Use logged in user (spree_current_user) for API authentication (current_api_user)
|
||||
def authenticate_user
|
||||
return if @current_api_user = spree_current_user
|
||||
|
||||
if api_key.blank?
|
||||
# An anonymous user
|
||||
@current_api_user = Spree.user_class.new
|
||||
return
|
||||
end
|
||||
|
||||
return if @current_api_user = Spree.user_class.find_by(spree_api_key: api_key.to_s)
|
||||
|
||||
invalid_api_key
|
||||
end
|
||||
|
||||
def set_content_type
|
||||
headers["Content-Type"] = "application/json"
|
||||
end
|
||||
|
||||
def error_during_processing(exception)
|
||||
Bugsnag.notify(exception)
|
||||
|
||||
render(json: { exception: exception.message },
|
||||
status: :unprocessable_entity) && return
|
||||
end
|
||||
|
||||
def current_ability
|
||||
Spree::Ability.new(current_api_user)
|
||||
end
|
||||
|
||||
def api_key
|
||||
request.headers["X-Spree-Token"] || params[:token]
|
||||
end
|
||||
helper_method :api_key
|
||||
|
||||
def invalid_resource!(resource)
|
||||
@resource = resource
|
||||
render(json: { error: I18n.t(:invalid_resource, scope: "spree.api"),
|
||||
errors: @resource.errors },
|
||||
status: :unprocessable_entity)
|
||||
end
|
||||
|
||||
def invalid_api_key
|
||||
render(json: { error: I18n.t(:invalid_api_key, key: api_key, scope: "spree.api") },
|
||||
status: :unauthorized) && return
|
||||
end
|
||||
|
||||
def unauthorized
|
||||
render(json: { error: I18n.t(:unauthorized, scope: "spree.api") },
|
||||
status: :unauthorized) && return
|
||||
end
|
||||
|
||||
def not_found
|
||||
render(json: { error: I18n.t(:resource_not_found, scope: "spree.api") },
|
||||
status: :not_found) && return
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,37 +0,0 @@
|
||||
module Api
|
||||
class CustomersController < Api::BaseController
|
||||
skip_authorization_check only: :index
|
||||
|
||||
def index
|
||||
@customers = current_api_user.customers
|
||||
render json: @customers, each_serializer: CustomerSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@customer = Customer.find(params[:id])
|
||||
authorize! :update, @customer
|
||||
|
||||
client_secret = RecurringPayments.setup_for(@customer) if params[:customer][:allow_charges]
|
||||
|
||||
if @customer.update(customer_params)
|
||||
add_recurring_payment_info(client_secret)
|
||||
render json: @customer, serializer: CustomerSerializer, status: :ok
|
||||
else
|
||||
invalid_resource!(@customer)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_recurring_payment_info(client_secret)
|
||||
return unless client_secret
|
||||
|
||||
@customer.gateway_recurring_payment_client_secret = client_secret
|
||||
@customer.gateway_shop_id = @customer.enterprise.stripe_account&.stripe_user_id
|
||||
end
|
||||
|
||||
def customer_params
|
||||
params.require(:customer).permit(:code, :email, :enterprise_id, :allow_charges)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,42 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'api/admin/enterprise_serializer'
|
||||
|
||||
module Api
|
||||
class EnterpriseAttachmentController < Api::BaseController
|
||||
class MissingImplementationError < StandardError; end
|
||||
class UnknownEnterpriseAuthorizationActionError < StandardError; end
|
||||
|
||||
before_action :load_enterprise
|
||||
|
||||
respond_to :json
|
||||
|
||||
def destroy
|
||||
return respond_with_conflict(error: destroy_attachment_does_not_exist_error_message) unless @enterprise.public_send("#{attachment_name}?")
|
||||
|
||||
@enterprise.update!(attachment_name => nil)
|
||||
render json: @enterprise, serializer: Admin::EnterpriseSerializer, spree_current_user: spree_current_user
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def attachment_name
|
||||
raise MissingImplementationError, "Method attachment_name should be defined"
|
||||
end
|
||||
|
||||
def enterprise_authorize_action
|
||||
raise MissingImplementationError, "Method enterprise_authorize_action should be defined"
|
||||
end
|
||||
|
||||
def load_enterprise
|
||||
@enterprise = Enterprise.find_by(permalink: params[:enterprise_id].to_s)
|
||||
raise UnknownEnterpriseAuthorizationActionError if enterprise_authorize_action.blank?
|
||||
|
||||
authorize!(enterprise_authorize_action, @enterprise)
|
||||
end
|
||||
|
||||
def destroy_attachment_does_not_exist_error_message
|
||||
I18n.t("api.enterprise_#{attachment_name}.destroy_attachment_does_not_exist")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,21 +0,0 @@
|
||||
module Api
|
||||
class EnterpriseFeesController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def destroy
|
||||
authorize! :destroy, enterprise_fee
|
||||
|
||||
if enterprise_fee.destroy
|
||||
render plain: I18n.t(:successfully_removed), status: :no_content
|
||||
else
|
||||
render plain: enterprise_fee.errors.full_messages.first, status: :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def enterprise_fee
|
||||
@enterprise_fee ||= EnterpriseFee.find_by id: params[:id]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,78 +0,0 @@
|
||||
module Api
|
||||
class EnterprisesController < Api::BaseController
|
||||
before_action :override_owner, only: [:create, :update]
|
||||
before_action :check_type, only: :update
|
||||
before_action :override_sells, only: [:create, :update]
|
||||
before_action :override_visible, only: [:create, :update]
|
||||
respond_to :json
|
||||
|
||||
def create
|
||||
authorize! :create, Enterprise
|
||||
|
||||
# params[:user_ids] breaks the enterprise creation
|
||||
# We remove them from params and save them after creating the enterprise
|
||||
user_ids = enterprise_params.delete(:user_ids)
|
||||
@enterprise = Enterprise.new(enterprise_params)
|
||||
if @enterprise.save
|
||||
@enterprise.user_ids = user_ids
|
||||
render json: @enterprise.id, status: :created
|
||||
else
|
||||
invalid_resource!(@enterprise)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id])
|
||||
authorize! :update, @enterprise
|
||||
|
||||
if @enterprise.update(enterprise_params)
|
||||
render json: @enterprise.id, status: :ok
|
||||
else
|
||||
invalid_resource!(@enterprise)
|
||||
end
|
||||
end
|
||||
|
||||
def update_image
|
||||
@enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id])
|
||||
authorize! :update, @enterprise
|
||||
|
||||
if params[:logo] && @enterprise.update( logo: params[:logo] )
|
||||
render plain: @enterprise.logo.url(:medium), status: :ok
|
||||
elsif params[:promo] && @enterprise.update( promo_image: params[:promo] )
|
||||
render plain: @enterprise.promo_image.url(:medium), status: :ok
|
||||
else
|
||||
invalid_resource!(@enterprise)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def override_owner
|
||||
enterprise_params[:owner_id] = current_api_user.id
|
||||
end
|
||||
|
||||
def check_type
|
||||
enterprise_params.delete :type unless current_api_user.admin?
|
||||
end
|
||||
|
||||
def override_sells
|
||||
has_hub = current_api_user.owned_enterprises.is_hub.any?
|
||||
new_enterprise_is_producer = !!enterprise_params[:is_primary_producer]
|
||||
|
||||
enterprise_params[:sells] = if has_hub && !new_enterprise_is_producer
|
||||
'any'
|
||||
else
|
||||
'unspecified'
|
||||
end
|
||||
end
|
||||
|
||||
def override_visible
|
||||
enterprise_params[:visible] = false
|
||||
end
|
||||
|
||||
def enterprise_params
|
||||
@enterprise_params ||= PermittedAttributes::Enterprise.new(params).call.
|
||||
to_h.with_indifferent_access
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,100 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This controller lists products that can be added to an exchange
|
||||
#
|
||||
# Pagination is optional and can be required by using param[:page]
|
||||
module Api
|
||||
class ExchangeProductsController < Api::BaseController
|
||||
include PaginationData
|
||||
DEFAULT_PER_PAGE = 100
|
||||
|
||||
skip_authorization_check only: [:index]
|
||||
|
||||
# If exchange_id is present in the URL:
|
||||
# Lists Products that can be added to that Exchange
|
||||
#
|
||||
# If exchange_id is not present in the URL:
|
||||
# Lists Products of the Enterprise given that can be added to the given Order Cycle
|
||||
# In this case parameters are: enterprise_id, order_cycle_id and incoming
|
||||
# (order_cycle_id is not necessary for incoming exchanges)
|
||||
def index
|
||||
if exchange_params[:exchange_id].present?
|
||||
load_data_from_exchange
|
||||
else
|
||||
load_data_from_other_params
|
||||
end
|
||||
|
||||
render_variant_count && return if params[:action_name] == "variant_count"
|
||||
|
||||
render_paginated_products paginated_products
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_variant_count
|
||||
render plain: {
|
||||
count: variants.count
|
||||
}.to_json
|
||||
end
|
||||
|
||||
def variants
|
||||
renderer.exchange_variants(@incoming, @enterprise)
|
||||
end
|
||||
|
||||
def products
|
||||
renderer.exchange_products(@incoming, @enterprise)
|
||||
end
|
||||
|
||||
def renderer
|
||||
@renderer ||= ExchangeProductsRenderer.
|
||||
new(@order_cycle, spree_current_user)
|
||||
end
|
||||
|
||||
def paginated_products
|
||||
return products unless pagination_required?
|
||||
|
||||
products.
|
||||
page(params[:page]).
|
||||
per(params[:per_page] || DEFAULT_PER_PAGE)
|
||||
end
|
||||
|
||||
def load_data_from_exchange
|
||||
exchange = Exchange.find_by(id: exchange_params[:exchange_id])
|
||||
|
||||
@order_cycle = exchange.order_cycle
|
||||
@incoming = exchange.incoming
|
||||
@enterprise = exchange.sender
|
||||
end
|
||||
|
||||
def load_data_from_other_params
|
||||
@enterprise = Enterprise.find_by(id: exchange_params[:enterprise_id])
|
||||
|
||||
# This will be a string (eg "true") when it arrives via params, but we want a boolean
|
||||
@incoming = ActiveModel::Type::Boolean.new.cast exchange_params[:incoming]
|
||||
|
||||
if exchange_params[:order_cycle_id]
|
||||
@order_cycle = OrderCycle.find_by(id: exchange_params[:order_cycle_id])
|
||||
elsif !@incoming
|
||||
raise "order_cycle_id is required to list products for new outgoing exchange"
|
||||
end
|
||||
end
|
||||
|
||||
def render_paginated_products(paginated_products)
|
||||
serialized_products = ActiveModel::ArraySerializer.new(
|
||||
paginated_products,
|
||||
each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer,
|
||||
order_cycle: @order_cycle
|
||||
)
|
||||
|
||||
render json: {
|
||||
products: serialized_products,
|
||||
pagination: pagination_data(paginated_products)
|
||||
}
|
||||
end
|
||||
|
||||
def exchange_params
|
||||
params.permit(:enterprise_id, :exchange_id, :order_cycle_id, :incoming).
|
||||
to_h.with_indifferent_access
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,16 +0,0 @@
|
||||
module Api
|
||||
class LogosController < Api::EnterpriseAttachmentController
|
||||
private
|
||||
|
||||
def attachment_name
|
||||
:logo
|
||||
end
|
||||
|
||||
def enterprise_authorize_action
|
||||
case action_name.to_sym
|
||||
when :destroy
|
||||
:remove_logo
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,101 +0,0 @@
|
||||
module Api
|
||||
class OrderCyclesController < Api::BaseController
|
||||
include EnterprisesHelper
|
||||
include ApiActionCaching
|
||||
|
||||
skip_authorization_check
|
||||
skip_before_action :authenticate_user, :ensure_api_key, only: [:taxons, :properties]
|
||||
|
||||
caches_action :taxons, :properties,
|
||||
expires_in: CacheService::FILTERS_EXPIRY,
|
||||
cache_path: proc { |controller| controller.request.url }
|
||||
|
||||
def products
|
||||
return render_no_products unless order_cycle.open?
|
||||
|
||||
products = ProductsRenderer.new(
|
||||
distributor,
|
||||
order_cycle,
|
||||
customer,
|
||||
search_params
|
||||
).products_json
|
||||
|
||||
render plain: products
|
||||
rescue ProductsRenderer::NoProducts
|
||||
render_no_products
|
||||
end
|
||||
|
||||
def taxons
|
||||
taxons = Spree::Taxon.
|
||||
joins(:products).
|
||||
where(spree_products: { id: distributed_products }).
|
||||
select('DISTINCT spree_taxons.*')
|
||||
|
||||
render plain: ActiveModel::ArraySerializer.new(
|
||||
taxons, each_serializer: Api::TaxonSerializer
|
||||
).to_json
|
||||
end
|
||||
|
||||
def properties
|
||||
render plain: ActiveModel::ArraySerializer.new(
|
||||
product_properties | producer_properties, each_serializer: Api::PropertySerializer
|
||||
).to_json
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_no_products
|
||||
render status: :not_found, json: {}
|
||||
end
|
||||
|
||||
def product_properties
|
||||
Spree::Property.
|
||||
joins(:products).
|
||||
where(spree_products: { id: distributed_products }).
|
||||
select('DISTINCT spree_properties.*')
|
||||
end
|
||||
|
||||
def producer_properties
|
||||
producers = Enterprise.
|
||||
joins(:supplied_products).
|
||||
where(spree_products: { id: distributed_products })
|
||||
|
||||
Spree::Property.
|
||||
joins(:producer_properties).
|
||||
where(producer_properties: { producer_id: producers }).
|
||||
select('DISTINCT spree_properties.*')
|
||||
end
|
||||
|
||||
def search_params
|
||||
permitted_search_params = params.slice :q, :page, :per_page
|
||||
|
||||
if permitted_search_params.key? :q
|
||||
permitted_search_params[:q].slice!(*permitted_ransack_params)
|
||||
end
|
||||
|
||||
permitted_search_params
|
||||
end
|
||||
|
||||
def permitted_ransack_params
|
||||
[:name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont,
|
||||
:properties_id_or_supplier_properties_id_in_any,
|
||||
:primary_taxon_id_in_any]
|
||||
end
|
||||
|
||||
def distributor
|
||||
@distributor ||= Enterprise.find_by(id: params[:distributor])
|
||||
end
|
||||
|
||||
def order_cycle
|
||||
@order_cycle ||= OrderCycle.find_by(id: params[:id])
|
||||
end
|
||||
|
||||
def customer
|
||||
@current_api_user.andand.customer_of(distributor) || nil
|
||||
end
|
||||
|
||||
def distributed_products
|
||||
OrderCycleDistributedProducts.new(distributor, order_cycle, customer).products_relation
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,67 +0,0 @@
|
||||
module Api
|
||||
class OrdersController < Api::BaseController
|
||||
include PaginationData
|
||||
|
||||
def show
|
||||
authorize! :read, order
|
||||
render json: order, serializer: Api::OrderDetailedSerializer, current_order: order
|
||||
end
|
||||
|
||||
def index
|
||||
authorize! :admin, Spree::Order
|
||||
|
||||
orders = SearchOrders.new(params, current_api_user).orders
|
||||
|
||||
render json: {
|
||||
orders: serialized_orders(orders),
|
||||
pagination: pagination_data(orders)
|
||||
}
|
||||
end
|
||||
|
||||
def ship
|
||||
authorize! :admin, order
|
||||
|
||||
if order.ship
|
||||
render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok
|
||||
else
|
||||
render json: { error: I18n.t('api.orders.failed_to_update') }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def capture
|
||||
authorize! :admin, order
|
||||
|
||||
pending_payment = order.pending_payments.first
|
||||
|
||||
return payment_capture_failed unless order.payment_required? && pending_payment
|
||||
|
||||
if pending_payment.capture!
|
||||
render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok
|
||||
else
|
||||
payment_capture_failed
|
||||
end
|
||||
rescue Spree::Core::GatewayError => e
|
||||
error_during_processing(e)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def payment_capture_failed
|
||||
render json: { error: I18n.t(:payment_processing_failed) }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
def serialized_orders(orders)
|
||||
ActiveModel::ArraySerializer.new(
|
||||
orders,
|
||||
each_serializer: Api::Admin::OrderSerializer
|
||||
)
|
||||
end
|
||||
|
||||
def order
|
||||
@order ||= Spree::Order.
|
||||
where(number: params[:id]).
|
||||
includes(line_items: { variant: [:product, :stock_items, :default_price] }).
|
||||
first!
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
module Api
|
||||
class ProductImagesController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def update_product_image
|
||||
@product = Spree::Product.find(params[:product_id])
|
||||
authorize! :update, @product
|
||||
|
||||
if @product.images.first.nil?
|
||||
@image = Spree::Image.create(attachment: params[:file], viewable_id: @product.master.id, viewable_type: 'Spree::Variant')
|
||||
render json: @image, serializer: ImageSerializer, status: :created
|
||||
else
|
||||
@image = @product.images.first
|
||||
@image.update(attachment: params[:file])
|
||||
render json: @image, serializer: ImageSerializer, status: :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,159 +0,0 @@
|
||||
require 'open_food_network/permissions'
|
||||
require 'spree/core/product_duplicator'
|
||||
|
||||
module Api
|
||||
class ProductsController < Api::BaseController
|
||||
include PaginationData
|
||||
respond_to :json
|
||||
DEFAULT_PER_PAGE = 15
|
||||
|
||||
before_action :set_default_available_on, only: :create
|
||||
|
||||
skip_authorization_check only: [:show, :bulk_products, :overridable]
|
||||
|
||||
def show
|
||||
@product = find_product(params[:id])
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Spree::Product
|
||||
@product = Spree::Product.new(product_params)
|
||||
|
||||
begin
|
||||
if @product.save
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
@product.permalink = nil
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Spree::Product
|
||||
@product = find_product(params[:id])
|
||||
if @product.update(product_params)
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :ok
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Spree::Product
|
||||
@product = find_product(params[:id])
|
||||
authorize! :delete, @product
|
||||
@product.destroy
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :no_content
|
||||
end
|
||||
|
||||
def bulk_products
|
||||
product_query = OpenFoodNetwork::Permissions.
|
||||
new(current_api_user).
|
||||
editable_products.
|
||||
merge(product_scope)
|
||||
|
||||
if params[:import_date].present?
|
||||
product_query = product_query.
|
||||
imported_on(params[:import_date]).
|
||||
group_by_products_id
|
||||
end
|
||||
|
||||
@products = product_query.
|
||||
ransack(query_params_with_defaults).
|
||||
result.
|
||||
page(params[:page] || 1).
|
||||
per(params[:per_page] || DEFAULT_PER_PAGE)
|
||||
|
||||
render_paged_products @products
|
||||
end
|
||||
|
||||
def overridable
|
||||
producer_ids = OpenFoodNetwork::Permissions.new(current_api_user).
|
||||
variant_override_producers.by_name.select('enterprises.id')
|
||||
|
||||
@products = paged_products_for_producers producer_ids
|
||||
|
||||
render_paged_products @products, ::Api::Admin::ProductSimpleSerializer
|
||||
end
|
||||
|
||||
# POST /api/products/:product_id/clone
|
||||
#
|
||||
def clone
|
||||
authorize! :create, Spree::Product
|
||||
original_product = find_product(params[:product_id])
|
||||
authorize! :update, original_product
|
||||
|
||||
@product = original_product.duplicate
|
||||
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_product(id)
|
||||
product_scope.find_by!(permalink: id.to_s)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
product_scope.find(id)
|
||||
end
|
||||
|
||||
def product_scope
|
||||
if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present?
|
||||
scope = Spree::Product
|
||||
if params[:show_deleted]
|
||||
scope = scope.with_deleted
|
||||
end
|
||||
else
|
||||
scope = Spree::Product.active
|
||||
end
|
||||
|
||||
scope.includes(product_query_includes)
|
||||
end
|
||||
|
||||
def product_query_includes
|
||||
[
|
||||
master: [:images],
|
||||
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides,
|
||||
{ option_values: :option_type }]
|
||||
]
|
||||
end
|
||||
|
||||
def paged_products_for_producers(producer_ids)
|
||||
Spree::Product.where(nil).
|
||||
merge(product_scope).
|
||||
includes(variants: [:product, :default_price, :stock_items]).
|
||||
where(supplier_id: producer_ids).
|
||||
by_producer.by_name.
|
||||
ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
end
|
||||
|
||||
def render_paged_products(products, product_serializer = ::Api::Admin::ProductSerializer)
|
||||
serialized_products = ActiveModel::ArraySerializer.new(
|
||||
products,
|
||||
each_serializer: product_serializer
|
||||
)
|
||||
|
||||
render json: {
|
||||
products: serialized_products,
|
||||
pagination: pagination_data(products)
|
||||
}
|
||||
end
|
||||
|
||||
def query_params_with_defaults
|
||||
(params[:q] || {}).reverse_merge(s: 'created_at desc')
|
||||
end
|
||||
|
||||
def product_params
|
||||
@product_params ||=
|
||||
params.permit(product: PermittedAttributes::Product.attributes)[:product].to_h
|
||||
end
|
||||
|
||||
def set_default_available_on
|
||||
product_params[:available_on] ||= Time.zone.now
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,16 +0,0 @@
|
||||
module Api
|
||||
class PromoImagesController < Api::EnterpriseAttachmentController
|
||||
private
|
||||
|
||||
def attachment_name
|
||||
:promo_image
|
||||
end
|
||||
|
||||
def enterprise_authorize_action
|
||||
case action_name.to_sym
|
||||
when :destroy
|
||||
:remove_promo_image
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,112 +0,0 @@
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
module Api
|
||||
class ShipmentsController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
before_action :find_order
|
||||
before_action :find_and_update_shipment, only: [:ship, :ready, :add, :remove]
|
||||
|
||||
def create
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
@shipment = get_or_create_shipment(params[:stock_location_id])
|
||||
|
||||
@order.contents.add(variant, quantity, nil, @shipment)
|
||||
|
||||
@shipment.refresh_rates
|
||||
@shipment.save!
|
||||
|
||||
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :read, Spree::Shipment
|
||||
@shipment = @order.shipments.find_by!(number: params[:id])
|
||||
params[:shipment] ||= []
|
||||
unlock = params[:shipment].delete(:unlock)
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.fee_adjustment.open
|
||||
end
|
||||
|
||||
@shipment.update(shipment_params[:shipment])
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.fee_adjustment.close
|
||||
end
|
||||
|
||||
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def ready
|
||||
authorize! :read, Spree::Shipment
|
||||
unless @shipment.ready?
|
||||
if @shipment.can_ready?
|
||||
@shipment.ready!
|
||||
else
|
||||
render(json: { error: I18n.t(:cannot_ready, scope: "spree.api.shipment") },
|
||||
status: :unprocessable_entity) && return
|
||||
end
|
||||
end
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def ship
|
||||
authorize! :read, Spree::Shipment
|
||||
unless @shipment.shipped?
|
||||
@shipment.ship!
|
||||
end
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def add
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
|
||||
@order.contents.add(variant, quantity, nil, @shipment)
|
||||
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def remove
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
|
||||
@order.contents.remove(variant, quantity, @shipment)
|
||||
@shipment.reload if @shipment.persisted?
|
||||
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_order
|
||||
@order = Spree::Order.find_by!(number: params[:order_id])
|
||||
authorize! :read, @order
|
||||
end
|
||||
|
||||
def find_and_update_shipment
|
||||
@shipment = @order.shipments.find_by!(number: params[:id])
|
||||
@shipment.update(shipment_params[:shipment]) if shipment_params[:shipment].present?
|
||||
@shipment.reload
|
||||
end
|
||||
|
||||
def scoped_variant(variant_id)
|
||||
variant = Spree::Variant.find(variant_id)
|
||||
OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
|
||||
variant
|
||||
end
|
||||
|
||||
def get_or_create_shipment(stock_location_id)
|
||||
@order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
|
||||
end
|
||||
|
||||
def shipment_params
|
||||
params.permit(
|
||||
[:id, :order_id, :variant_id, :quantity,
|
||||
{ shipment: [:tracking, :selected_shipping_rate_id] }]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
class ShopsController < BaseController
|
||||
respond_to :json
|
||||
skip_authorization_check only: [:show, :closed_shops]
|
||||
|
||||
def show
|
||||
enterprise = Enterprise.find_by(id: params[:id])
|
||||
|
||||
render plain: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok
|
||||
end
|
||||
|
||||
def closed_shops
|
||||
@active_distributor_ids = []
|
||||
@earliest_closing_times = []
|
||||
|
||||
serialized_closed_shops = ActiveModel::ArraySerializer.new(
|
||||
ShopsListService.new.closed_shops,
|
||||
each_serializer: Api::EnterpriseSerializer,
|
||||
data: OpenFoodNetwork::EnterpriseInjectionData.new
|
||||
)
|
||||
|
||||
render json: serialized_closed_shops
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,44 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
class StatesController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check
|
||||
|
||||
def index
|
||||
render json: states, each_serializer: Api::StateSerializer, status: :ok
|
||||
end
|
||||
|
||||
def show
|
||||
@state = scope.find(params[:id])
|
||||
render json: @state, serializer: Api::StateSerializer, status: :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scope
|
||||
if params[:country_id]
|
||||
@country = Spree::Country.find(params[:country_id])
|
||||
@country.states
|
||||
else
|
||||
Spree::State.all
|
||||
end
|
||||
end
|
||||
|
||||
def states
|
||||
states = scope.ransack(params[:q]).result.
|
||||
includes(:country).order('name ASC')
|
||||
|
||||
if pagination?
|
||||
states = states.page(params[:page]).per(params[:per_page])
|
||||
end
|
||||
|
||||
states
|
||||
end
|
||||
|
||||
def pagination?
|
||||
params[:page] || params[:per_page]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,16 +0,0 @@
|
||||
module Api
|
||||
class StatusesController < ::BaseController
|
||||
respond_to :json
|
||||
|
||||
def job_queue
|
||||
render json: { alive: job_queue_alive? }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def job_queue_alive?
|
||||
Spree::Config.last_job_queue_heartbeat_at.present? &&
|
||||
Time.parse(Spree::Config.last_job_queue_heartbeat_at).in_time_zone > 6.minutes.ago
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,12 +0,0 @@
|
||||
module Api
|
||||
class TaxonomiesController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: :jstree
|
||||
|
||||
def jstree
|
||||
@taxonomy = Spree::Taxonomy.find(params[:id])
|
||||
render json: @taxonomy.root, serializer: Api::TaxonJstreeSerializer
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,76 +0,0 @@
|
||||
module Api
|
||||
class TaxonsController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: [:index, :show, :jstree]
|
||||
|
||||
def index
|
||||
@taxons = if taxonomy
|
||||
taxonomy.root.children
|
||||
elsif params[:ids]
|
||||
Spree::Taxon.where(id: raw_params[:ids].split(","))
|
||||
else
|
||||
Spree::Taxon.ransack(raw_params[:q]).result
|
||||
end
|
||||
render json: @taxons, each_serializer: Api::TaxonSerializer
|
||||
end
|
||||
|
||||
def jstree
|
||||
@taxon = taxon
|
||||
render json: @taxon.children, each_serializer: Api::TaxonJstreeSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Spree::Taxon
|
||||
@taxon = Spree::Taxon.new(taxon_params)
|
||||
@taxon.taxonomy_id = params[:taxonomy_id]
|
||||
taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id])
|
||||
|
||||
if taxonomy.nil?
|
||||
@taxon.errors[:taxonomy_id] = I18n.t(:invalid_taxonomy_id, scope: 'spree.api')
|
||||
invalid_resource!(@taxon) && return
|
||||
end
|
||||
|
||||
@taxon.parent_id = taxonomy.root.id unless params.dig(:taxon, :parent_id)
|
||||
|
||||
if @taxon.save
|
||||
render json: @taxon, serializer: Api::TaxonSerializer, status: :created
|
||||
else
|
||||
invalid_resource!(@taxon)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Spree::Taxon
|
||||
if taxon.update(taxon_params)
|
||||
render json: taxon, serializer: Api::TaxonSerializer, status: :ok
|
||||
else
|
||||
invalid_resource!(taxon)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Spree::Taxon
|
||||
taxon.destroy
|
||||
render json: taxon, serializer: Api::TaxonSerializer, status: :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def taxonomy
|
||||
return if params[:taxonomy_id].blank?
|
||||
|
||||
@taxonomy ||= Spree::Taxonomy.find(params[:taxonomy_id])
|
||||
end
|
||||
|
||||
def taxon
|
||||
@taxon ||= taxonomy.taxons.find(params[:id])
|
||||
end
|
||||
|
||||
def taxon_params
|
||||
return if params[:taxon].blank?
|
||||
|
||||
params.require(:taxon).permit([:name, :parent_id])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,18 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
class TermsAndConditionsController < Api::EnterpriseAttachmentController
|
||||
private
|
||||
|
||||
def attachment_name
|
||||
:terms_and_conditions
|
||||
end
|
||||
|
||||
def enterprise_authorize_action
|
||||
case action_name.to_sym
|
||||
when :destroy
|
||||
:remove_terms_and_conditions
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
107
app/controllers/api/v0/base_controller.rb
Normal file
107
app/controllers/api/v0/base_controller.rb
Normal file
@@ -0,0 +1,107 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Base controller for OFN's API
|
||||
require_dependency 'spree/api/controller_setup'
|
||||
require "spree/core/controller_helpers/ssl"
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class BaseController < ActionController::Metal
|
||||
include RawParams
|
||||
include ActionController::StrongParameters
|
||||
include ActionController::RespondWith
|
||||
include Spree::Api::ControllerSetup
|
||||
include Spree::Core::ControllerHelpers::SSL
|
||||
include ::ActionController::Head
|
||||
include ::ActionController::ConditionalGet
|
||||
include ActionView::Layouts
|
||||
|
||||
layout false
|
||||
|
||||
attr_accessor :current_api_user
|
||||
|
||||
before_action :set_content_type
|
||||
before_action :authenticate_user
|
||||
|
||||
rescue_from Exception, with: :error_during_processing
|
||||
rescue_from CanCan::AccessDenied, with: :unauthorized
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
||||
|
||||
helper Spree::Api::ApiHelpers
|
||||
|
||||
ssl_allowed
|
||||
|
||||
# Include these because we inherit from ActionController::Metal
|
||||
# rather than ActionController::Base and these are required for AMS
|
||||
include ActionController::Serialization
|
||||
include ActionController::UrlFor
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
use_renderers :json
|
||||
check_authorization
|
||||
|
||||
def respond_with_conflict(json_hash)
|
||||
render json: json_hash, status: :conflict
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Use logged in user (spree_current_user) for API authentication (current_api_user)
|
||||
def authenticate_user
|
||||
return if @current_api_user = spree_current_user
|
||||
|
||||
if api_key.blank?
|
||||
# An anonymous user
|
||||
@current_api_user = Spree.user_class.new
|
||||
return
|
||||
end
|
||||
|
||||
return if @current_api_user = Spree.user_class.find_by(spree_api_key: api_key.to_s)
|
||||
|
||||
invalid_api_key
|
||||
end
|
||||
|
||||
def set_content_type
|
||||
headers["Content-Type"] = "application/json"
|
||||
end
|
||||
|
||||
def error_during_processing(exception)
|
||||
Bugsnag.notify(exception)
|
||||
|
||||
render(json: { exception: exception.message },
|
||||
status: :unprocessable_entity) && return
|
||||
end
|
||||
|
||||
def current_ability
|
||||
Spree::Ability.new(current_api_user)
|
||||
end
|
||||
|
||||
def api_key
|
||||
request.headers["X-Spree-Token"] || params[:token]
|
||||
end
|
||||
helper_method :api_key
|
||||
|
||||
def invalid_resource!(resource)
|
||||
@resource = resource
|
||||
render(json: { error: I18n.t(:invalid_resource, scope: "spree.api"),
|
||||
errors: @resource.errors },
|
||||
status: :unprocessable_entity)
|
||||
end
|
||||
|
||||
def invalid_api_key
|
||||
render(json: { error: I18n.t(:invalid_api_key, key: api_key, scope: "spree.api") },
|
||||
status: :unauthorized) && return
|
||||
end
|
||||
|
||||
def unauthorized
|
||||
render(json: { error: I18n.t(:unauthorized, scope: "spree.api") },
|
||||
status: :unauthorized) && return
|
||||
end
|
||||
|
||||
def not_found
|
||||
render(json: { error: I18n.t(:resource_not_found, scope: "spree.api") },
|
||||
status: :not_found) && return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
41
app/controllers/api/v0/customers_controller.rb
Normal file
41
app/controllers/api/v0/customers_controller.rb
Normal file
@@ -0,0 +1,41 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class CustomersController < Api::V0::BaseController
|
||||
skip_authorization_check only: :index
|
||||
|
||||
def index
|
||||
@customers = current_api_user.customers
|
||||
render json: @customers, each_serializer: CustomerSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@customer = Customer.find(params[:id])
|
||||
authorize! :update, @customer
|
||||
|
||||
client_secret = RecurringPayments.setup_for(@customer) if params[:customer][:allow_charges]
|
||||
|
||||
if @customer.update(customer_params)
|
||||
add_recurring_payment_info(client_secret)
|
||||
render json: @customer, serializer: CustomerSerializer, status: :ok
|
||||
else
|
||||
invalid_resource!(@customer)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_recurring_payment_info(client_secret)
|
||||
return unless client_secret
|
||||
|
||||
@customer.gateway_recurring_payment_client_secret = client_secret
|
||||
@customer.gateway_shop_id = @customer.enterprise.stripe_account&.stripe_user_id
|
||||
end
|
||||
|
||||
def customer_params
|
||||
params.require(:customer).permit(:code, :email, :enterprise_id, :allow_charges)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
49
app/controllers/api/v0/enterprise_attachment_controller.rb
Normal file
49
app/controllers/api/v0/enterprise_attachment_controller.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'api/admin/enterprise_serializer'
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class EnterpriseAttachmentController < Api::V0::BaseController
|
||||
class MissingImplementationError < StandardError; end
|
||||
|
||||
class UnknownEnterpriseAuthorizationActionError < StandardError; end
|
||||
|
||||
before_action :load_enterprise
|
||||
|
||||
respond_to :json
|
||||
|
||||
def destroy
|
||||
unless @enterprise.public_send("#{attachment_name}?")
|
||||
return respond_with_conflict(error: destroy_attachment_does_not_exist_error_message)
|
||||
end
|
||||
|
||||
@enterprise.update!(attachment_name => nil)
|
||||
render json: @enterprise,
|
||||
serializer: Admin::EnterpriseSerializer,
|
||||
spree_current_user: spree_current_user
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def attachment_name
|
||||
raise MissingImplementationError, "Method attachment_name should be defined"
|
||||
end
|
||||
|
||||
def enterprise_authorize_action
|
||||
raise MissingImplementationError, "Method enterprise_authorize_action should be defined"
|
||||
end
|
||||
|
||||
def load_enterprise
|
||||
@enterprise = Enterprise.find_by(permalink: params[:enterprise_id].to_s)
|
||||
raise UnknownEnterpriseAuthorizationActionError if enterprise_authorize_action.blank?
|
||||
|
||||
authorize!(enterprise_authorize_action, @enterprise)
|
||||
end
|
||||
|
||||
def destroy_attachment_does_not_exist_error_message
|
||||
I18n.t("api.enterprise_#{attachment_name}.destroy_attachment_does_not_exist")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
25
app/controllers/api/v0/enterprise_fees_controller.rb
Normal file
25
app/controllers/api/v0/enterprise_fees_controller.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class EnterpriseFeesController < Api::V0::BaseController
|
||||
respond_to :json
|
||||
|
||||
def destroy
|
||||
authorize! :destroy, enterprise_fee
|
||||
|
||||
if enterprise_fee.destroy
|
||||
render plain: I18n.t(:successfully_removed), status: :no_content
|
||||
else
|
||||
render plain: enterprise_fee.errors.full_messages.first, status: :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def enterprise_fee
|
||||
@enterprise_fee ||= EnterpriseFee.find_by id: params[:id]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
82
app/controllers/api/v0/enterprises_controller.rb
Normal file
82
app/controllers/api/v0/enterprises_controller.rb
Normal file
@@ -0,0 +1,82 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class EnterprisesController < Api::V0::BaseController
|
||||
before_action :override_owner, only: [:create, :update]
|
||||
before_action :check_type, only: :update
|
||||
before_action :override_sells, only: [:create, :update]
|
||||
before_action :override_visible, only: [:create, :update]
|
||||
respond_to :json
|
||||
|
||||
def create
|
||||
authorize! :create, Enterprise
|
||||
|
||||
# params[:user_ids] breaks the enterprise creation
|
||||
# We remove them from params and save them after creating the enterprise
|
||||
user_ids = enterprise_params.delete(:user_ids)
|
||||
@enterprise = Enterprise.new(enterprise_params)
|
||||
if @enterprise.save
|
||||
@enterprise.user_ids = user_ids
|
||||
render json: @enterprise.id, status: :created
|
||||
else
|
||||
invalid_resource!(@enterprise)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id])
|
||||
authorize! :update, @enterprise
|
||||
|
||||
if @enterprise.update(enterprise_params)
|
||||
render json: @enterprise.id, status: :ok
|
||||
else
|
||||
invalid_resource!(@enterprise)
|
||||
end
|
||||
end
|
||||
|
||||
def update_image
|
||||
@enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id])
|
||||
authorize! :update, @enterprise
|
||||
|
||||
if params[:logo] && @enterprise.update( logo: params[:logo] )
|
||||
render plain: @enterprise.logo.url(:medium), status: :ok
|
||||
elsif params[:promo] && @enterprise.update( promo_image: params[:promo] )
|
||||
render plain: @enterprise.promo_image.url(:medium), status: :ok
|
||||
else
|
||||
invalid_resource!(@enterprise)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def override_owner
|
||||
enterprise_params[:owner_id] = current_api_user.id
|
||||
end
|
||||
|
||||
def check_type
|
||||
enterprise_params.delete :type unless current_api_user.admin?
|
||||
end
|
||||
|
||||
def override_sells
|
||||
has_hub = current_api_user.owned_enterprises.is_hub.any?
|
||||
new_enterprise_is_producer = !!enterprise_params[:is_primary_producer]
|
||||
|
||||
enterprise_params[:sells] = if has_hub && !new_enterprise_is_producer
|
||||
'any'
|
||||
else
|
||||
'unspecified'
|
||||
end
|
||||
end
|
||||
|
||||
def override_visible
|
||||
enterprise_params[:visible] = false
|
||||
end
|
||||
|
||||
def enterprise_params
|
||||
@enterprise_params ||= PermittedAttributes::Enterprise.new(params).call.
|
||||
to_h.with_indifferent_access
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
102
app/controllers/api/v0/exchange_products_controller.rb
Normal file
102
app/controllers/api/v0/exchange_products_controller.rb
Normal file
@@ -0,0 +1,102 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This controller lists products that can be added to an exchange
|
||||
#
|
||||
# Pagination is optional and can be required by using param[:page]
|
||||
module Api
|
||||
module V0
|
||||
class ExchangeProductsController < Api::V0::BaseController
|
||||
include PaginationData
|
||||
DEFAULT_PER_PAGE = 100
|
||||
|
||||
skip_authorization_check only: [:index]
|
||||
|
||||
# If exchange_id is present in the URL:
|
||||
# Lists Products that can be added to that Exchange
|
||||
#
|
||||
# If exchange_id is not present in the URL:
|
||||
# Lists Products of the Enterprise given that can be added to the given Order Cycle
|
||||
# In this case parameters are: enterprise_id, order_cycle_id and incoming
|
||||
# (order_cycle_id is not necessary for incoming exchanges)
|
||||
def index
|
||||
if exchange_params[:exchange_id].present?
|
||||
load_data_from_exchange
|
||||
else
|
||||
load_data_from_other_params
|
||||
end
|
||||
|
||||
render_variant_count && return if params[:action_name] == "variant_count"
|
||||
|
||||
render_paginated_products paginated_products
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_variant_count
|
||||
render plain: {
|
||||
count: variants.count
|
||||
}.to_json
|
||||
end
|
||||
|
||||
def variants
|
||||
renderer.exchange_variants(@incoming, @enterprise)
|
||||
end
|
||||
|
||||
def products
|
||||
renderer.exchange_products(@incoming, @enterprise)
|
||||
end
|
||||
|
||||
def renderer
|
||||
@renderer ||= ExchangeProductsRenderer.
|
||||
new(@order_cycle, spree_current_user)
|
||||
end
|
||||
|
||||
def paginated_products
|
||||
return products unless pagination_required?
|
||||
|
||||
products.
|
||||
page(params[:page]).
|
||||
per(params[:per_page] || DEFAULT_PER_PAGE)
|
||||
end
|
||||
|
||||
def load_data_from_exchange
|
||||
exchange = Exchange.find_by(id: exchange_params[:exchange_id])
|
||||
|
||||
@order_cycle = exchange.order_cycle
|
||||
@incoming = exchange.incoming
|
||||
@enterprise = exchange.sender
|
||||
end
|
||||
|
||||
def load_data_from_other_params
|
||||
@enterprise = Enterprise.find_by(id: exchange_params[:enterprise_id])
|
||||
|
||||
# This will be a string (eg "true") when it arrives via params, but we want a boolean
|
||||
@incoming = ActiveModel::Type::Boolean.new.cast exchange_params[:incoming]
|
||||
|
||||
if exchange_params[:order_cycle_id]
|
||||
@order_cycle = OrderCycle.find_by(id: exchange_params[:order_cycle_id])
|
||||
elsif !@incoming
|
||||
raise "order_cycle_id is required to list products for new outgoing exchange"
|
||||
end
|
||||
end
|
||||
|
||||
def render_paginated_products(paginated_products)
|
||||
serialized_products = ActiveModel::ArraySerializer.new(
|
||||
paginated_products,
|
||||
each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer,
|
||||
order_cycle: @order_cycle
|
||||
)
|
||||
|
||||
render json: {
|
||||
products: serialized_products,
|
||||
pagination: pagination_data(paginated_products)
|
||||
}
|
||||
end
|
||||
|
||||
def exchange_params
|
||||
params.permit(:enterprise_id, :exchange_id, :order_cycle_id, :incoming).
|
||||
to_h.with_indifferent_access
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
app/controllers/api/v0/logos_controller.rb
Normal file
20
app/controllers/api/v0/logos_controller.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class LogosController < Api::V0::EnterpriseAttachmentController
|
||||
private
|
||||
|
||||
def attachment_name
|
||||
:logo
|
||||
end
|
||||
|
||||
def enterprise_authorize_action
|
||||
case action_name.to_sym
|
||||
when :destroy
|
||||
:remove_logo
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
105
app/controllers/api/v0/order_cycles_controller.rb
Normal file
105
app/controllers/api/v0/order_cycles_controller.rb
Normal file
@@ -0,0 +1,105 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class OrderCyclesController < Api::V0::BaseController
|
||||
include EnterprisesHelper
|
||||
include ApiActionCaching
|
||||
|
||||
skip_authorization_check
|
||||
skip_before_action :authenticate_user, :ensure_api_key, only: [:taxons, :properties]
|
||||
|
||||
caches_action :taxons, :properties,
|
||||
expires_in: CacheService::FILTERS_EXPIRY,
|
||||
cache_path: proc { |controller| controller.request.url }
|
||||
|
||||
def products
|
||||
return render_no_products unless order_cycle.open?
|
||||
|
||||
products = ProductsRenderer.new(
|
||||
distributor,
|
||||
order_cycle,
|
||||
customer,
|
||||
search_params
|
||||
).products_json
|
||||
|
||||
render plain: products
|
||||
rescue ProductsRenderer::NoProducts
|
||||
render_no_products
|
||||
end
|
||||
|
||||
def taxons
|
||||
taxons = Spree::Taxon.
|
||||
joins(:products).
|
||||
where(spree_products: { id: distributed_products }).
|
||||
select('DISTINCT spree_taxons.*')
|
||||
|
||||
render plain: ActiveModel::ArraySerializer.new(
|
||||
taxons, each_serializer: Api::TaxonSerializer
|
||||
).to_json
|
||||
end
|
||||
|
||||
def properties
|
||||
render plain: ActiveModel::ArraySerializer.new(
|
||||
product_properties | producer_properties, each_serializer: Api::PropertySerializer
|
||||
).to_json
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_no_products
|
||||
render status: :not_found, json: {}
|
||||
end
|
||||
|
||||
def product_properties
|
||||
Spree::Property.
|
||||
joins(:products).
|
||||
where(spree_products: { id: distributed_products }).
|
||||
select('DISTINCT spree_properties.*')
|
||||
end
|
||||
|
||||
def producer_properties
|
||||
producers = Enterprise.
|
||||
joins(:supplied_products).
|
||||
where(spree_products: { id: distributed_products })
|
||||
|
||||
Spree::Property.
|
||||
joins(:producer_properties).
|
||||
where(producer_properties: { producer_id: producers }).
|
||||
select('DISTINCT spree_properties.*')
|
||||
end
|
||||
|
||||
def search_params
|
||||
permitted_search_params = params.slice :q, :page, :per_page
|
||||
|
||||
if permitted_search_params.key? :q
|
||||
permitted_search_params[:q].slice!(*permitted_ransack_params)
|
||||
end
|
||||
|
||||
permitted_search_params
|
||||
end
|
||||
|
||||
def permitted_ransack_params
|
||||
[:name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont,
|
||||
:properties_id_or_supplier_properties_id_in_any,
|
||||
:primary_taxon_id_in_any]
|
||||
end
|
||||
|
||||
def distributor
|
||||
@distributor ||= Enterprise.find_by(id: params[:distributor])
|
||||
end
|
||||
|
||||
def order_cycle
|
||||
@order_cycle ||= OrderCycle.find_by(id: params[:id])
|
||||
end
|
||||
|
||||
def customer
|
||||
@current_api_user.andand.customer_of(distributor) || nil
|
||||
end
|
||||
|
||||
def distributed_products
|
||||
OrderCycleDistributedProducts.new(distributor, order_cycle, customer).products_relation
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
72
app/controllers/api/v0/orders_controller.rb
Normal file
72
app/controllers/api/v0/orders_controller.rb
Normal file
@@ -0,0 +1,72 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class OrdersController < Api::V0::BaseController
|
||||
include PaginationData
|
||||
|
||||
def show
|
||||
authorize! :read, order
|
||||
render json: order, serializer: Api::OrderDetailedSerializer, current_order: order
|
||||
end
|
||||
|
||||
def index
|
||||
authorize! :admin, Spree::Order
|
||||
|
||||
orders = SearchOrders.new(params, current_api_user).orders
|
||||
|
||||
render json: {
|
||||
orders: serialized_orders(orders),
|
||||
pagination: pagination_data(orders)
|
||||
}
|
||||
end
|
||||
|
||||
def ship
|
||||
authorize! :admin, order
|
||||
|
||||
if order.ship
|
||||
render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok
|
||||
else
|
||||
render json: { error: I18n.t('api.orders.failed_to_update') },
|
||||
status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def capture
|
||||
authorize! :admin, order
|
||||
|
||||
pending_payment = order.pending_payments.first
|
||||
|
||||
return payment_capture_failed unless order.payment_required? && pending_payment
|
||||
|
||||
if pending_payment.capture!
|
||||
render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok
|
||||
else
|
||||
payment_capture_failed
|
||||
end
|
||||
rescue Spree::Core::GatewayError => e
|
||||
error_during_processing(e)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def payment_capture_failed
|
||||
render json: { error: I18n.t(:payment_processing_failed) }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
def serialized_orders(orders)
|
||||
ActiveModel::ArraySerializer.new(
|
||||
orders,
|
||||
each_serializer: Api::Admin::OrderSerializer
|
||||
)
|
||||
end
|
||||
|
||||
def order
|
||||
@order ||= Spree::Order.
|
||||
where(number: params[:id]).
|
||||
includes(line_items: { variant: [:product, :stock_items, :default_price] }).
|
||||
first!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
27
app/controllers/api/v0/product_images_controller.rb
Normal file
27
app/controllers/api/v0/product_images_controller.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class ProductImagesController < Api::V0::BaseController
|
||||
respond_to :json
|
||||
|
||||
def update_product_image
|
||||
@product = Spree::Product.find(params[:product_id])
|
||||
authorize! :update, @product
|
||||
|
||||
if @product.images.first.nil?
|
||||
@image = Spree::Image.create(
|
||||
attachment: params[:file],
|
||||
viewable_id: @product.master.id,
|
||||
viewable_type: 'Spree::Variant'
|
||||
)
|
||||
render json: @image, serializer: ImageSerializer, status: :created
|
||||
else
|
||||
@image = @product.images.first
|
||||
@image.update(attachment: params[:file])
|
||||
render json: @image, serializer: ImageSerializer, status: :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
163
app/controllers/api/v0/products_controller.rb
Normal file
163
app/controllers/api/v0/products_controller.rb
Normal file
@@ -0,0 +1,163 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/permissions'
|
||||
require 'spree/core/product_duplicator'
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class ProductsController < Api::V0::BaseController
|
||||
include PaginationData
|
||||
respond_to :json
|
||||
DEFAULT_PER_PAGE = 15
|
||||
|
||||
before_action :set_default_available_on, only: :create
|
||||
|
||||
skip_authorization_check only: [:show, :bulk_products, :overridable]
|
||||
|
||||
def show
|
||||
@product = find_product(params[:id])
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Spree::Product
|
||||
@product = Spree::Product.new(product_params)
|
||||
|
||||
begin
|
||||
if @product.save
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
@product.permalink = nil
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Spree::Product
|
||||
@product = find_product(params[:id])
|
||||
if @product.update(product_params)
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :ok
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Spree::Product
|
||||
@product = find_product(params[:id])
|
||||
authorize! :delete, @product
|
||||
@product.destroy
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :no_content
|
||||
end
|
||||
|
||||
def bulk_products
|
||||
product_query = OpenFoodNetwork::Permissions.
|
||||
new(current_api_user).
|
||||
editable_products.
|
||||
merge(product_scope)
|
||||
|
||||
if params[:import_date].present?
|
||||
product_query = product_query.
|
||||
imported_on(params[:import_date]).
|
||||
group_by_products_id
|
||||
end
|
||||
|
||||
@products = product_query.
|
||||
ransack(query_params_with_defaults).
|
||||
result.
|
||||
page(params[:page] || 1).
|
||||
per(params[:per_page] || DEFAULT_PER_PAGE)
|
||||
|
||||
render_paged_products @products
|
||||
end
|
||||
|
||||
def overridable
|
||||
producer_ids = OpenFoodNetwork::Permissions.new(current_api_user).
|
||||
variant_override_producers.by_name.select('enterprises.id')
|
||||
|
||||
@products = paged_products_for_producers producer_ids
|
||||
|
||||
render_paged_products @products, ::Api::Admin::ProductSimpleSerializer
|
||||
end
|
||||
|
||||
# POST /api/products/:product_id/clone
|
||||
#
|
||||
def clone
|
||||
authorize! :create, Spree::Product
|
||||
original_product = find_product(params[:product_id])
|
||||
authorize! :update, original_product
|
||||
|
||||
@product = original_product.duplicate
|
||||
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_product(id)
|
||||
product_scope.find_by!(permalink: id.to_s)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
product_scope.find(id)
|
||||
end
|
||||
|
||||
def product_scope
|
||||
if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present?
|
||||
scope = Spree::Product
|
||||
if params[:show_deleted]
|
||||
scope = scope.with_deleted
|
||||
end
|
||||
else
|
||||
scope = Spree::Product.active
|
||||
end
|
||||
|
||||
scope.includes(product_query_includes)
|
||||
end
|
||||
|
||||
def product_query_includes
|
||||
[
|
||||
master: [:images],
|
||||
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides,
|
||||
{ option_values: :option_type }]
|
||||
]
|
||||
end
|
||||
|
||||
def paged_products_for_producers(producer_ids)
|
||||
Spree::Product.where(nil).
|
||||
merge(product_scope).
|
||||
includes(variants: [:product, :default_price, :stock_items]).
|
||||
where(supplier_id: producer_ids).
|
||||
by_producer.by_name.
|
||||
ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
end
|
||||
|
||||
def render_paged_products(products, product_serializer = ::Api::Admin::ProductSerializer)
|
||||
serialized_products = ActiveModel::ArraySerializer.new(
|
||||
products,
|
||||
each_serializer: product_serializer
|
||||
)
|
||||
|
||||
render json: {
|
||||
products: serialized_products,
|
||||
pagination: pagination_data(products)
|
||||
}
|
||||
end
|
||||
|
||||
def query_params_with_defaults
|
||||
(params[:q] || {}).reverse_merge(s: 'created_at desc')
|
||||
end
|
||||
|
||||
def product_params
|
||||
@product_params ||=
|
||||
params.permit(product: PermittedAttributes::Product.attributes)[:product].to_h
|
||||
end
|
||||
|
||||
def set_default_available_on
|
||||
product_params[:available_on] ||= Time.zone.now
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
app/controllers/api/v0/promo_images_controller.rb
Normal file
20
app/controllers/api/v0/promo_images_controller.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class PromoImagesController < Api::V0::EnterpriseAttachmentController
|
||||
private
|
||||
|
||||
def attachment_name
|
||||
:promo_image
|
||||
end
|
||||
|
||||
def enterprise_authorize_action
|
||||
case action_name.to_sym
|
||||
when :destroy
|
||||
:remove_promo_image
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
116
app/controllers/api/v0/shipments_controller.rb
Normal file
116
app/controllers/api/v0/shipments_controller.rb
Normal file
@@ -0,0 +1,116 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class ShipmentsController < Api::V0::BaseController
|
||||
respond_to :json
|
||||
|
||||
before_action :find_order
|
||||
before_action :find_and_update_shipment, only: [:ship, :ready, :add, :remove]
|
||||
|
||||
def create
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
@shipment = get_or_create_shipment(params[:stock_location_id])
|
||||
|
||||
@order.contents.add(variant, quantity, nil, @shipment)
|
||||
|
||||
@shipment.refresh_rates
|
||||
@shipment.save!
|
||||
|
||||
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :read, Spree::Shipment
|
||||
@shipment = @order.shipments.find_by!(number: params[:id])
|
||||
params[:shipment] ||= []
|
||||
unlock = params[:shipment].delete(:unlock)
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.fee_adjustment.open
|
||||
end
|
||||
|
||||
@shipment.update(shipment_params[:shipment])
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.fee_adjustment.close
|
||||
end
|
||||
|
||||
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def ready
|
||||
authorize! :read, Spree::Shipment
|
||||
unless @shipment.ready?
|
||||
if @shipment.can_ready?
|
||||
@shipment.ready!
|
||||
else
|
||||
render(json: { error: I18n.t(:cannot_ready, scope: "spree.api.shipment") },
|
||||
status: :unprocessable_entity) && return
|
||||
end
|
||||
end
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def ship
|
||||
authorize! :read, Spree::Shipment
|
||||
unless @shipment.shipped?
|
||||
@shipment.ship!
|
||||
end
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def add
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
|
||||
@order.contents.add(variant, quantity, nil, @shipment)
|
||||
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def remove
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
|
||||
@order.contents.remove(variant, quantity, @shipment)
|
||||
@shipment.reload if @shipment.persisted?
|
||||
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_order
|
||||
@order = Spree::Order.find_by!(number: params[:order_id])
|
||||
authorize! :read, @order
|
||||
end
|
||||
|
||||
def find_and_update_shipment
|
||||
@shipment = @order.shipments.find_by!(number: params[:id])
|
||||
@shipment.update(shipment_params[:shipment]) if shipment_params[:shipment].present?
|
||||
@shipment.reload
|
||||
end
|
||||
|
||||
def scoped_variant(variant_id)
|
||||
variant = Spree::Variant.find(variant_id)
|
||||
OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
|
||||
variant
|
||||
end
|
||||
|
||||
def get_or_create_shipment(stock_location_id)
|
||||
@order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
|
||||
end
|
||||
|
||||
def shipment_params
|
||||
params.permit(
|
||||
[:id, :order_id, :variant_id, :quantity,
|
||||
{ shipment: [:tracking, :selected_shipping_rate_id] }]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
29
app/controllers/api/v0/shops_controller.rb
Normal file
29
app/controllers/api/v0/shops_controller.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class ShopsController < BaseController
|
||||
respond_to :json
|
||||
skip_authorization_check only: [:show, :closed_shops]
|
||||
|
||||
def show
|
||||
enterprise = Enterprise.find_by(id: params[:id])
|
||||
|
||||
render plain: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok
|
||||
end
|
||||
|
||||
def closed_shops
|
||||
@active_distributor_ids = []
|
||||
@earliest_closing_times = []
|
||||
|
||||
serialized_closed_shops = ActiveModel::ArraySerializer.new(
|
||||
ShopsListService.new.closed_shops,
|
||||
each_serializer: Api::EnterpriseSerializer,
|
||||
data: OpenFoodNetwork::EnterpriseInjectionData.new
|
||||
)
|
||||
|
||||
render json: serialized_closed_shops
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
46
app/controllers/api/v0/states_controller.rb
Normal file
46
app/controllers/api/v0/states_controller.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class StatesController < Api::V0::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check
|
||||
|
||||
def index
|
||||
render json: states, each_serializer: Api::StateSerializer, status: :ok
|
||||
end
|
||||
|
||||
def show
|
||||
@state = scope.find(params[:id])
|
||||
render json: @state, serializer: Api::StateSerializer, status: :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scope
|
||||
if params[:country_id]
|
||||
@country = Spree::Country.find(params[:country_id])
|
||||
@country.states
|
||||
else
|
||||
Spree::State.all
|
||||
end
|
||||
end
|
||||
|
||||
def states
|
||||
states = scope.ransack(params[:q]).result.
|
||||
includes(:country).order('name ASC')
|
||||
|
||||
if pagination?
|
||||
states = states.page(params[:page]).per(params[:per_page])
|
||||
end
|
||||
|
||||
states
|
||||
end
|
||||
|
||||
def pagination?
|
||||
params[:page] || params[:per_page]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
app/controllers/api/v0/statuses_controller.rb
Normal file
20
app/controllers/api/v0/statuses_controller.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class StatusesController < ::BaseController
|
||||
respond_to :json
|
||||
|
||||
def job_queue
|
||||
render json: { alive: job_queue_alive? }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def job_queue_alive?
|
||||
Spree::Config.last_job_queue_heartbeat_at.present? &&
|
||||
Time.parse(Spree::Config.last_job_queue_heartbeat_at).in_time_zone > 6.minutes.ago
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
16
app/controllers/api/v0/taxonomies_controller.rb
Normal file
16
app/controllers/api/v0/taxonomies_controller.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class TaxonomiesController < Api::V0::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: :jstree
|
||||
|
||||
def jstree
|
||||
@taxonomy = Spree::Taxonomy.find(params[:id])
|
||||
render json: @taxonomy.root, serializer: Api::TaxonJstreeSerializer
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
78
app/controllers/api/v0/taxons_controller.rb
Normal file
78
app/controllers/api/v0/taxons_controller.rb
Normal file
@@ -0,0 +1,78 @@
|
||||
module Api
|
||||
module V0
|
||||
class TaxonsController < Api::V0::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: [:index, :show, :jstree]
|
||||
|
||||
def index
|
||||
@taxons = if taxonomy
|
||||
taxonomy.root.children
|
||||
elsif params[:ids]
|
||||
Spree::Taxon.where(id: raw_params[:ids].split(","))
|
||||
else
|
||||
Spree::Taxon.ransack(raw_params[:q]).result
|
||||
end
|
||||
render json: @taxons, each_serializer: Api::TaxonSerializer
|
||||
end
|
||||
|
||||
def jstree
|
||||
@taxon = taxon
|
||||
render json: @taxon.children, each_serializer: Api::TaxonJstreeSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Spree::Taxon
|
||||
@taxon = Spree::Taxon.new(taxon_params)
|
||||
@taxon.taxonomy_id = params[:taxonomy_id]
|
||||
taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id])
|
||||
|
||||
if taxonomy.nil?
|
||||
@taxon.errors[:taxonomy_id] = I18n.t(:invalid_taxonomy_id, scope: 'spree.api')
|
||||
invalid_resource!(@taxon) && return
|
||||
end
|
||||
|
||||
@taxon.parent_id = taxonomy.root.id unless params.dig(:taxon, :parent_id)
|
||||
|
||||
if @taxon.save
|
||||
render json: @taxon, serializer: Api::TaxonSerializer, status: :created
|
||||
else
|
||||
invalid_resource!(@taxon)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Spree::Taxon
|
||||
if taxon.update(taxon_params)
|
||||
render json: taxon, serializer: Api::TaxonSerializer, status: :ok
|
||||
else
|
||||
invalid_resource!(taxon)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Spree::Taxon
|
||||
taxon.destroy
|
||||
render json: taxon, serializer: Api::TaxonSerializer, status: :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def taxonomy
|
||||
return if params[:taxonomy_id].blank?
|
||||
|
||||
@taxonomy ||= Spree::Taxonomy.find(params[:taxonomy_id])
|
||||
end
|
||||
|
||||
def taxon
|
||||
@taxon ||= taxonomy.taxons.find(params[:id])
|
||||
end
|
||||
|
||||
def taxon_params
|
||||
return if params[:taxon].blank?
|
||||
|
||||
params.require(:taxon).permit([:name, :parent_id])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
app/controllers/api/v0/terms_and_conditions_controller.rb
Normal file
20
app/controllers/api/v0/terms_and_conditions_controller.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class TermsAndConditionsController < Api::V0::EnterpriseAttachmentController
|
||||
private
|
||||
|
||||
def attachment_name
|
||||
:terms_and_conditions
|
||||
end
|
||||
|
||||
def enterprise_authorize_action
|
||||
case action_name.to_sym
|
||||
when :destroy
|
||||
:remove_terms_and_conditions
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
81
app/controllers/api/v0/variants_controller.rb
Normal file
81
app/controllers/api/v0/variants_controller.rb
Normal file
@@ -0,0 +1,81 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class VariantsController < Api::V0::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: [:index, :show]
|
||||
before_action :product
|
||||
|
||||
def index
|
||||
@variants = scope.includes(option_values: :option_type).ransack(params[:q]).result
|
||||
render json: @variants, each_serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
@variant = scope.includes(option_values: :option_type).find(params[:id])
|
||||
render json: @variant, serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Spree::Variant
|
||||
@variant = scope.new(variant_params)
|
||||
if @variant.save
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: :created
|
||||
else
|
||||
invalid_resource!(@variant)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Spree::Variant
|
||||
@variant = scope.find(params[:id])
|
||||
if @variant.update(variant_params)
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: :ok
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Spree::Variant
|
||||
@variant = scope.find(params[:id])
|
||||
authorize! :delete, @variant
|
||||
|
||||
VariantDeleter.new.delete(@variant)
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def product
|
||||
@product ||= Spree::Product.find_by(permalink: params[:product_id]) if params[:product_id]
|
||||
end
|
||||
|
||||
def scope
|
||||
if @product
|
||||
variants = if current_api_user.has_spree_role?("admin") || params[:show_deleted]
|
||||
@product.variants_including_master.with_deleted
|
||||
else
|
||||
@product.variants_including_master
|
||||
end
|
||||
else
|
||||
variants = Spree::Variant.where(nil)
|
||||
if current_api_user.has_spree_role?("admin")
|
||||
unless params[:show_deleted]
|
||||
variants = Spree::Variant.active
|
||||
end
|
||||
else
|
||||
variants = variants.active
|
||||
end
|
||||
end
|
||||
variants
|
||||
end
|
||||
|
||||
def variant_params
|
||||
params.require(:variant).permit(PermittedAttributes::Variant.attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,77 +0,0 @@
|
||||
module Api
|
||||
class VariantsController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: [:index, :show]
|
||||
before_action :product
|
||||
|
||||
def index
|
||||
@variants = scope.includes(option_values: :option_type).ransack(params[:q]).result
|
||||
render json: @variants, each_serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
@variant = scope.includes(option_values: :option_type).find(params[:id])
|
||||
render json: @variant, serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Spree::Variant
|
||||
@variant = scope.new(variant_params)
|
||||
if @variant.save
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: :created
|
||||
else
|
||||
invalid_resource!(@variant)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Spree::Variant
|
||||
@variant = scope.find(params[:id])
|
||||
if @variant.update(variant_params)
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: :ok
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Spree::Variant
|
||||
@variant = scope.find(params[:id])
|
||||
authorize! :delete, @variant
|
||||
|
||||
VariantDeleter.new.delete(@variant)
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def product
|
||||
@product ||= Spree::Product.find_by(permalink: params[:product_id]) if params[:product_id]
|
||||
end
|
||||
|
||||
def scope
|
||||
if @product
|
||||
variants = if current_api_user.has_spree_role?("admin") || params[:show_deleted]
|
||||
@product.variants_including_master.with_deleted
|
||||
else
|
||||
@product.variants_including_master
|
||||
end
|
||||
else
|
||||
variants = Spree::Variant.where(nil)
|
||||
if current_api_user.has_spree_role?("admin")
|
||||
unless params[:show_deleted]
|
||||
variants = Spree::Variant.active
|
||||
end
|
||||
else
|
||||
variants = variants.active
|
||||
end
|
||||
end
|
||||
variants
|
||||
end
|
||||
|
||||
def variant_params
|
||||
params.require(:variant).permit(PermittedAttributes::Variant.attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -80,7 +80,7 @@ module Spree
|
||||
product_set.collection.each { |p| authorize! :update, p }
|
||||
|
||||
if product_set.save
|
||||
redirect_to main_app.bulk_products_api_products_path(bulk_index_query)
|
||||
redirect_to main_app.bulk_products_api_v0_products_path(bulk_index_query)
|
||||
elsif product_set.errors.present?
|
||||
render json: { errors: product_set.errors }, status: :bad_request
|
||||
else
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
}
|
||||
Spree.routes = <%== {
|
||||
:variants_search => spree.admin_search_variants_path(:format => 'json'),
|
||||
:taxons_search => main_app.api_taxons_path(:format => 'json'),
|
||||
:orders_api => main_app.api_orders_path,
|
||||
:states_search => main_app.api_states_path(:format => 'json')
|
||||
:taxons_search => main_app.api_v0_taxons_path(:format => 'json'),
|
||||
:orders_api => main_app.api_v0_orders_path,
|
||||
:states_search => main_app.api_v0_states_path(:format => 'json')
|
||||
}.to_json %>;
|
||||
</script>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
= label_tag nil, t("spree.tree")
|
||||
%br/
|
||||
:javascript
|
||||
Spree.routes.taxonomy_taxons_path = "#{main_app.api_taxonomy_taxons_path(@taxonomy)}";
|
||||
Spree.routes.taxonomy_taxons_path = "#{main_app.api_v0_taxonomy_taxons_path(@taxonomy)}";
|
||||
Spree.routes.admin_taxonomy_taxons_path = "#{spree.admin_taxonomy_taxons_path(@taxonomy)}";
|
||||
#taxonomy_tree.tree
|
||||
#progress{style: "display:none;"}
|
||||
|
||||
@@ -1,80 +1,84 @@
|
||||
Openfoodnetwork::Application.routes.draw do
|
||||
namespace :api do
|
||||
resources :products do
|
||||
collection do
|
||||
get :bulk_products
|
||||
get :overridable
|
||||
end
|
||||
post :clone
|
||||
namespace :v0 do
|
||||
resources :products do
|
||||
collection do
|
||||
get :bulk_products
|
||||
get :overridable
|
||||
end
|
||||
post :clone
|
||||
|
||||
resources :variants
|
||||
end
|
||||
|
||||
resources :variants, :only => [:index]
|
||||
|
||||
resources :orders, only: [:index, :show] do
|
||||
member do
|
||||
put :capture
|
||||
put :ship
|
||||
resources :variants
|
||||
end
|
||||
|
||||
resources :shipments, :only => [:create, :update] do
|
||||
resources :variants, :only => [:index]
|
||||
|
||||
resources :orders, only: [:index, :show] do
|
||||
member do
|
||||
put :ready
|
||||
put :capture
|
||||
put :ship
|
||||
put :add
|
||||
put :remove
|
||||
end
|
||||
|
||||
resources :shipments, :only => [:create, :update] do
|
||||
member do
|
||||
put :ready
|
||||
put :ship
|
||||
put :add
|
||||
put :remove
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
resources :enterprises do
|
||||
post :update_image, on: :member
|
||||
resources :enterprises do
|
||||
post :update_image, on: :member
|
||||
|
||||
resource :logo, only: [:destroy]
|
||||
resource :promo_image, only: [:destroy]
|
||||
resource :terms_and_conditions, only: [:destroy]
|
||||
end
|
||||
|
||||
resources :shops, only: [:show] do
|
||||
collection do
|
||||
get :closed_shops
|
||||
resource :logo, only: [:destroy]
|
||||
resource :promo_image, only: [:destroy]
|
||||
resource :terms_and_conditions, only: [:destroy]
|
||||
end
|
||||
end
|
||||
|
||||
resources :order_cycles do
|
||||
get :products, on: :member
|
||||
get :taxons, on: :member
|
||||
get :properties, on: :member
|
||||
end
|
||||
|
||||
resources :exchanges, only: [:show], to: 'exchange_products#index' do
|
||||
get :products, to: 'exchange_products#index'
|
||||
end
|
||||
|
||||
resource :status do
|
||||
get :job_queue
|
||||
end
|
||||
|
||||
resources :customers, only: [:index, :update]
|
||||
|
||||
resources :enterprise_fees, only: [:destroy]
|
||||
|
||||
post '/product_images/:product_id', to: 'product_images#update_product_image'
|
||||
|
||||
resources :states, :only => [:index, :show]
|
||||
|
||||
resources :taxons, :only => [:index]
|
||||
|
||||
resources :taxonomies do
|
||||
member do
|
||||
get :jstree
|
||||
resources :shops, only: [:show] do
|
||||
collection do
|
||||
get :closed_shops
|
||||
end
|
||||
end
|
||||
resources :taxons do
|
||||
|
||||
resources :order_cycles do
|
||||
get :products, on: :member
|
||||
get :taxons, on: :member
|
||||
get :properties, on: :member
|
||||
end
|
||||
|
||||
resources :exchanges, only: [:show], to: 'exchange_products#index' do
|
||||
get :products, to: 'exchange_products#index'
|
||||
end
|
||||
|
||||
resource :status do
|
||||
get :job_queue
|
||||
end
|
||||
|
||||
resources :customers, only: [:index, :update]
|
||||
|
||||
resources :enterprise_fees, only: [:destroy]
|
||||
|
||||
post '/product_images/:product_id', to: 'product_images#update_product_image'
|
||||
|
||||
resources :states, :only => [:index, :show]
|
||||
|
||||
resources :taxons, :only => [:index]
|
||||
|
||||
resources :taxonomies do
|
||||
member do
|
||||
get :jstree
|
||||
end
|
||||
resources :taxons do
|
||||
member do
|
||||
get :jstree
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
match '*path', to: redirect(path: "/api/v0/%{path}"), via: :all, constraints: { path: /(?!v[0-9]).+/ }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Darkswarm.controller "CookiesBannerCtrl", ($scope, CookiesBannerService, $http, $window)->
|
||||
|
||||
$scope.acceptCookies = ->
|
||||
$http.post('/api/cookies/consent')
|
||||
$http.post('/api/v0/cookies/consent')
|
||||
CookiesBannerService.close()
|
||||
CookiesBannerService.disable()
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
require_dependency 'web/cookies_consent'
|
||||
|
||||
module Web
|
||||
module Api
|
||||
class CookiesConsentController < BaseController
|
||||
include ActionController::Cookies
|
||||
respond_to :json
|
||||
|
||||
def show
|
||||
render json: { cookies_consent: cookies_consent.exists? }
|
||||
end
|
||||
|
||||
def create
|
||||
cookies_consent.set
|
||||
show
|
||||
end
|
||||
|
||||
def destroy
|
||||
cookies_consent.destroy
|
||||
show
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cookies_consent
|
||||
@cookies_consent ||= Web::CookiesConsent.new(cookies, request.host)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_dependency 'web/cookies_consent'
|
||||
|
||||
module Web
|
||||
module Api
|
||||
module V0
|
||||
class CookiesConsentController < BaseController
|
||||
include ActionController::Cookies
|
||||
respond_to :json
|
||||
|
||||
def show
|
||||
render json: { cookies_consent: cookies_consent.exists? }
|
||||
end
|
||||
|
||||
def create
|
||||
cookies_consent.set
|
||||
show
|
||||
end
|
||||
|
||||
def destroy
|
||||
cookies_consent.destroy
|
||||
show
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cookies_consent
|
||||
@cookies_consent ||= Web::CookiesConsent.new(cookies, request.host)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Openfoodnetwork::Application.routes.append do
|
||||
scope '/api/cookies' do
|
||||
resource :consent, only: [:show, :create, :destroy], controller: "web/api/cookies_consent"
|
||||
scope '/api/v0/cookies' do
|
||||
resource :consent, only: [:show, :create, :destroy], controller: "web/api/v0/cookies_consent"
|
||||
end
|
||||
|
||||
get "/angular-templates/:id", to: "web/angular_templates#show", constraints: { name: %r{[\/\w\.]+} }
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Api::BaseController do
|
||||
describe Api::V0::BaseController do
|
||||
render_views
|
||||
controller(Api::BaseController) do
|
||||
controller(Api::V0::BaseController) do
|
||||
skip_authorization_check only: :index
|
||||
|
||||
def index
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Api
|
||||
describe CustomersController, type: :controller do
|
||||
describe V0::CustomersController, type: :controller do
|
||||
include AuthenticationHelper
|
||||
render_views
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Api
|
||||
describe EnterpriseFeesController, type: :controller do
|
||||
describe V0::EnterpriseFeesController, type: :controller do
|
||||
include AuthenticationHelper
|
||||
|
||||
let!(:unreferenced_fee) { create(:enterprise_fee) }
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Api::EnterprisesController, type: :controller do
|
||||
describe Api::V0::EnterprisesController, type: :controller do
|
||||
render_views
|
||||
|
||||
let(:enterprise) { create(:distributor_enterprise) }
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Api
|
||||
describe ExchangeProductsController, type: :controller do
|
||||
describe V0::ExchangeProductsController, type: :controller do
|
||||
include AuthenticationHelper
|
||||
|
||||
let(:order_cycle) { create(:order_cycle) }
|
||||
@@ -54,7 +54,7 @@ module Api
|
||||
let(:products_relation) { Spree::Product.includes(:variants).where("spree_variants.id": exchange.variants.map(&:id)) }
|
||||
|
||||
before do
|
||||
stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1)
|
||||
stub_const("#{Api::V0::ExchangeProductsController}::DEFAULT_PER_PAGE", 1)
|
||||
end
|
||||
|
||||
describe "when a specific page is requested" do
|
||||
@@ -3,7 +3,7 @@
|
||||
require "spec_helper"
|
||||
|
||||
module Api
|
||||
describe LogosController, type: :controller do
|
||||
describe V0::LogosController, type: :controller do
|
||||
include AuthenticationHelper
|
||||
|
||||
let(:admin_user) { create(:admin_user) }
|
||||
@@ -3,7 +3,7 @@
|
||||
require "spec_helper"
|
||||
|
||||
module Api
|
||||
describe OrderCyclesController, type: :controller do
|
||||
describe V0::OrderCyclesController, type: :controller do
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor]) }
|
||||
let!(:exchange) { order_cycle.exchanges.to_enterprises(distributor).outgoing.first }
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Api
|
||||
describe OrdersController, type: :controller do
|
||||
describe V0::OrdersController, type: :controller do
|
||||
include AuthenticationHelper
|
||||
render_views
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Api
|
||||
describe ProductImagesController, type: :controller do
|
||||
describe V0::ProductImagesController, type: :controller do
|
||||
include AuthenticationHelper
|
||||
render_views
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
require 'spree/core/product_duplicator'
|
||||
|
||||
describe Api::ProductsController, type: :controller do
|
||||
describe Api::V0::ProductsController, type: :controller do
|
||||
render_views
|
||||
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
@@ -3,7 +3,7 @@
|
||||
require "spec_helper"
|
||||
|
||||
module Api
|
||||
describe PromoImagesController, type: :controller do
|
||||
describe V0::PromoImagesController, type: :controller do
|
||||
include AuthenticationHelper
|
||||
|
||||
let(:admin_user) { create(:admin_user) }
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Api::ShipmentsController, type: :controller do
|
||||
describe Api::V0::ShipmentsController, type: :controller do
|
||||
render_views
|
||||
|
||||
let!(:shipment) { create(:shipment) }
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Api::ShopsController, type: :controller do
|
||||
describe Api::V0::ShopsController, type: :controller do
|
||||
include AuthenticationHelper
|
||||
render_views
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Api
|
||||
describe StatesController do
|
||||
describe V0::StatesController do
|
||||
render_views
|
||||
|
||||
let!(:state) { create(:state, name: "Victoria") }
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Api
|
||||
describe StatusesController, type: :controller do
|
||||
describe V0::StatusesController, type: :controller do
|
||||
render_views
|
||||
|
||||
describe "job queue status" do
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Api
|
||||
describe TaxonomiesController do
|
||||
describe V0::TaxonomiesController do
|
||||
render_views
|
||||
|
||||
let(:taxonomy) { create(:taxonomy) }
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Api::TaxonsController do
|
||||
describe Api::V0::TaxonsController do
|
||||
render_views
|
||||
|
||||
let(:taxonomy) { create(:taxonomy) }
|
||||
@@ -3,7 +3,7 @@
|
||||
require "spec_helper"
|
||||
|
||||
module Api
|
||||
describe TermsAndConditionsController, type: :controller do
|
||||
describe V0::TermsAndConditionsController, type: :controller do
|
||||
include AuthenticationHelper
|
||||
|
||||
let(:enterprise_owner) { create(:user) }
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Api::VariantsController, type: :controller do
|
||||
describe Api::V0::VariantsController, type: :controller do
|
||||
render_views
|
||||
|
||||
let(:supplier) { FactoryBot.create(:supplier_enterprise) }
|
||||
@@ -66,7 +66,7 @@ describe Spree::Admin::ProductsController, type: :controller do
|
||||
]
|
||||
|
||||
expect(response).to redirect_to(
|
||||
'/api/products/bulk_products'
|
||||
'/api/v0/products/bulk_products'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,7 +16,7 @@ feature '
|
||||
let!(:new_product) { create(:product, supplier: supplier_enterprise) }
|
||||
|
||||
before do
|
||||
stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1)
|
||||
stub_const("#{Api::V0::ExchangeProductsController}::DEFAULT_PER_PAGE", 1)
|
||||
|
||||
login_as_admin_and_visit admin_order_cycle_incoming_path(order_cycle)
|
||||
expect(page).to have_content "1 / 2 selected"
|
||||
|
||||
@@ -47,8 +47,8 @@ feature "Shops caching", js: true, caching: true do
|
||||
let(:exchange) { order_cycle.exchanges.to_enterprises(distributor).outgoing.first }
|
||||
|
||||
let(:test_domain) { "#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}" }
|
||||
let(:taxons_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/taxons.json?distributor=#{distributor.id}" }
|
||||
let(:properties_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/properties.json?distributor=#{distributor.id}" }
|
||||
let(:taxons_key) { "views/#{test_domain}/api/v0/order_cycles/#{order_cycle.id}/taxons.json?distributor=#{distributor.id}" }
|
||||
let(:properties_key) { "views/#{test_domain}/api/v0/order_cycles/#{order_cycle.id}/properties.json?distributor=#{distributor.id}" }
|
||||
let(:options) { { expires_in: CacheService::FILTERS_EXPIRY } }
|
||||
|
||||
before do
|
||||
|
||||
@@ -820,7 +820,7 @@ describe "AdminProductEditCtrl", ->
|
||||
}
|
||||
]
|
||||
$scope.dirtyProducts = {}
|
||||
$httpBackend.expectDELETE("/api/products/13").respond 200, "data"
|
||||
$httpBackend.expectDELETE("/api/v0/products/13").respond 200, "data"
|
||||
$scope.deleteProduct $scope.products[1]
|
||||
$httpBackend.flush()
|
||||
|
||||
@@ -839,7 +839,7 @@ describe "AdminProductEditCtrl", ->
|
||||
DirtyProducts.addProductProperty 9, "someProperty", "something"
|
||||
DirtyProducts.addProductProperty 13, "name", "P1"
|
||||
|
||||
$httpBackend.expectDELETE("/api/products/13").respond 200, "data"
|
||||
$httpBackend.expectDELETE("/api/v0/products/13").respond 200, "data"
|
||||
$scope.deleteProduct $scope.products[1]
|
||||
$httpBackend.flush()
|
||||
expect($scope.products).toEqual [
|
||||
@@ -901,7 +901,7 @@ describe "AdminProductEditCtrl", ->
|
||||
}
|
||||
]
|
||||
$scope.dirtyProducts = {}
|
||||
$httpBackend.expectDELETE("/api/products/apples/variants/3").respond 200, "data"
|
||||
$httpBackend.expectDELETE("/api/v0/products/apples/variants/3").respond 200, "data"
|
||||
$scope.deleteVariant $scope.products[0], $scope.products[0].variants[0]
|
||||
$httpBackend.flush()
|
||||
|
||||
@@ -931,7 +931,7 @@ describe "AdminProductEditCtrl", ->
|
||||
DirtyProducts.addVariantProperty 9, 4, "price", 6.0
|
||||
DirtyProducts.addProductProperty 13, "name", "P1"
|
||||
|
||||
$httpBackend.expectDELETE("/api/products/apples/variants/3").respond 200, "data"
|
||||
$httpBackend.expectDELETE("/api/v0/products/apples/variants/3").respond 200, "data"
|
||||
$scope.deleteVariant $scope.products[0], $scope.products[0].variants[0]
|
||||
$httpBackend.flush()
|
||||
expect($scope.products[0].variants).toEqual [
|
||||
|
||||
@@ -127,7 +127,7 @@ describe "Enterprises service", ->
|
||||
|
||||
beforeEach ->
|
||||
enterprise = new EnterpriseResource({ id: 15, permalink: "enterprise1", name: "Enterprise 1", logo: {} })
|
||||
$httpBackend.expectDELETE("/api/enterprises/enterprise1/logo.json").respond 200, { id: 15, name: "Enterprise 1"}
|
||||
$httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/logo.json").respond 200, { id: 15, name: "Enterprise 1"}
|
||||
Enterprises.removeLogo(enterprise).then( -> resolved = true)
|
||||
$httpBackend.flush()
|
||||
|
||||
@@ -144,7 +144,7 @@ describe "Enterprises service", ->
|
||||
|
||||
beforeEach ->
|
||||
enterprise = new EnterpriseResource( { id: 15, permalink: "enterprise1", name: "Enterprise 1" } )
|
||||
$httpBackend.expectDELETE("/api/enterprises/enterprise1/logo.json").respond 409, { error: "obj" }
|
||||
$httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/logo.json").respond 409, { error: "obj" }
|
||||
Enterprises.removeLogo(enterprise).catch( -> rejected = true)
|
||||
$httpBackend.flush()
|
||||
|
||||
@@ -162,7 +162,7 @@ describe "Enterprises service", ->
|
||||
|
||||
beforeEach ->
|
||||
enterprise = new EnterpriseResource({ id: 15, permalink: "enterprise1", name: "Enterprise 1", promo_image: {} })
|
||||
$httpBackend.expectDELETE("/api/enterprises/enterprise1/promo_image.json").respond 200, { id: 15, name: "Enterprise 1"}
|
||||
$httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/promo_image.json").respond 200, { id: 15, name: "Enterprise 1"}
|
||||
Enterprises.removePromoImage(enterprise).then( -> resolved = true)
|
||||
$httpBackend.flush()
|
||||
|
||||
@@ -179,7 +179,7 @@ describe "Enterprises service", ->
|
||||
|
||||
beforeEach ->
|
||||
enterprise = new EnterpriseResource( { id: 15, permalink: "enterprise1", name: "Enterprise 1" } )
|
||||
$httpBackend.expectDELETE("/api/enterprises/enterprise1/promo_image.json").respond 409, { error: "obj" }
|
||||
$httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/promo_image.json").respond 409, { error: "obj" }
|
||||
Enterprises.removePromoImage(enterprise).catch( -> rejected = true)
|
||||
$httpBackend.flush()
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ describe "LineItemsCtrl", ->
|
||||
index: jasmine.createSpy('index').and.returnValue(lineItem)
|
||||
all: [lineItem]
|
||||
|
||||
httpBackend.expectGET("/api/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}}
|
||||
httpBackend.expectGET("/api/v0/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}}
|
||||
httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bsells_in%5D%5B%5D=own&q%5Bsells_in%5D%5B%5D=any").respond [distributor]
|
||||
httpBackend.expectGET("/admin/order_cycles.json?ams_prefix=basic&as=distributor&q%5Borders_close_at_gt%5D=SomeDate").respond [orderCycle]
|
||||
httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bis_primary_producer_eq%5D=true").respond [supplier]
|
||||
|
||||
@@ -19,7 +19,7 @@ describe "Orders service", ->
|
||||
|
||||
beforeEach ->
|
||||
response = { orders: [{ id: 5, name: 'Order 1'}], pagination: {page: 1, pages: 1, results: 1} }
|
||||
$httpBackend.expectGET('/api/orders.json').respond 200, response
|
||||
$httpBackend.expectGET('/api/v0/orders.json').respond 200, response
|
||||
result = Orders.index()
|
||||
$httpBackend.flush()
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ describe "BulkProducts service", ->
|
||||
BulkProducts.products = [
|
||||
id: 13
|
||||
]
|
||||
$httpBackend.expectPOST("/api/products/13/clone").respond 201,
|
||||
$httpBackend.expectPOST("/api/v0/products/13/clone").respond 201,
|
||||
id: 17
|
||||
$httpBackend.expectGET("/api/products/17?template=bulk_show").respond 200, [
|
||||
$httpBackend.expectGET("/api/v0/products/17?template=bulk_show").respond 200, [
|
||||
id: 17
|
||||
]
|
||||
BulkProducts.cloneProduct BulkProducts.products[0]
|
||||
@@ -30,8 +30,8 @@ describe "BulkProducts service", ->
|
||||
spyOn(BulkProducts, "insertProductAfter")
|
||||
spyOn(BulkProducts, "unpackProduct")
|
||||
BulkProducts.products = [originalProduct]
|
||||
$httpBackend.expectPOST("/api/products/16/clone").respond 201, clonedProduct
|
||||
$httpBackend.expectGET("/api/products/17?template=bulk_show").respond 200, clonedProduct
|
||||
$httpBackend.expectPOST("/api/v0/products/16/clone").respond 201, clonedProduct
|
||||
$httpBackend.expectGET("/api/v0/products/17?template=bulk_show").respond 200, clonedProduct
|
||||
BulkProducts.cloneProduct BulkProducts.products[0]
|
||||
$httpBackend.flush()
|
||||
expect(BulkProducts.unpackProduct).toHaveBeenCalledWith clonedProduct
|
||||
|
||||
@@ -36,7 +36,7 @@ describe 'CreditCards service', ->
|
||||
|
||||
it "loads a success flash", ->
|
||||
CreditCards.setDefault(card2)
|
||||
$httpBackend.expectGET('/api/customers.json').respond 200, []
|
||||
$httpBackend.expectGET('/api/v0/customers.json').respond 200, []
|
||||
$httpBackend.flush()
|
||||
expect(RailsFlashLoader.loadFlash).toHaveBeenCalledWith({success: t('js.default_card_updated')})
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@ describe 'Customer', ->
|
||||
|
||||
it "nests the params inside 'customer'", ->
|
||||
$httpBackend
|
||||
.expectPUT('/api/customers/3.json', { customer: { id: 3 } })
|
||||
.expectPUT('/api/v0/customers/3.json', { customer: { id: 3 } })
|
||||
.respond 200, response
|
||||
customer.update()
|
||||
$httpBackend.flush()
|
||||
|
||||
describe "when the request succeeds", ->
|
||||
it "shows a success flash", ->
|
||||
$httpBackend.expectPUT('/api/customers/3.json').respond 200, response
|
||||
$httpBackend.expectPUT('/api/v0/customers/3.json').respond 200, response
|
||||
customer.update()
|
||||
$httpBackend.flush()
|
||||
expect(RailsFlashLoaderMock.loadFlash)
|
||||
@@ -32,7 +32,7 @@ describe 'Customer', ->
|
||||
|
||||
describe "when the request fails", ->
|
||||
it "shows a error flash", ->
|
||||
$httpBackend.expectPUT('/api/customers/3.json').respond 400, { error: 'Some error' }
|
||||
$httpBackend.expectPUT('/api/v0/customers/3.json').respond 400, { error: 'Some error' }
|
||||
customer.update()
|
||||
$httpBackend.flush()
|
||||
expect(RailsFlashLoaderMock.loadFlash)
|
||||
|
||||
@@ -16,7 +16,7 @@ describe 'Customers', ->
|
||||
|
||||
it "asks for customers and returns @all, promises to populate via @load", ->
|
||||
spyOn(Customers,'load').and.callThrough()
|
||||
$httpBackend.expectGET('/api/customers.json').respond 200, customerList
|
||||
$httpBackend.expectGET('/api/v0/customers.json').respond 200, customerList
|
||||
result = Customers.index()
|
||||
$httpBackend.flush()
|
||||
expect(Customers.load).toHaveBeenCalled()
|
||||
|
||||
@@ -32,7 +32,7 @@ describe "EnterpriseRegistrationService", ->
|
||||
describe "success", ->
|
||||
beforeEach ->
|
||||
spyOn(RegistrationServiceMock, "select")
|
||||
$httpBackend.expectPOST("/api/enterprises?token=keykeykeykey").respond 200, 6
|
||||
$httpBackend.expectPOST("/api/v0/enterprises?token=keykeykeykey").respond 200, 6
|
||||
EnterpriseRegistrationService.create()
|
||||
$httpBackend.flush()
|
||||
|
||||
@@ -46,7 +46,7 @@ describe "EnterpriseRegistrationService", ->
|
||||
beforeEach ->
|
||||
spyOn(RegistrationServiceMock, "select")
|
||||
spyOn(window, "alert")
|
||||
$httpBackend.expectPOST("/api/enterprises?token=keykeykeykey").respond 400, 6
|
||||
$httpBackend.expectPOST("/api/v0/enterprises?token=keykeykeykey").respond 400, 6
|
||||
EnterpriseRegistrationService.create()
|
||||
$httpBackend.flush()
|
||||
|
||||
@@ -60,7 +60,7 @@ describe "EnterpriseRegistrationService", ->
|
||||
beforeEach ->
|
||||
spyOn(RegistrationServiceMock, "select")
|
||||
spyOn(window, "alert")
|
||||
$httpBackend.expectPOST("/api/enterprises?token=keykeykeykey").respond 400, {"error": "Invalid resource. Please fix errors and try again.", "errors": {"name": ["has already been taken. If this is your enterprise and you would like to claim ownership, please contact the current manager of this profile at owner@example.com."], "permalink": [] }}
|
||||
$httpBackend.expectPOST("/api/v0/enterprises?token=keykeykeykey").respond 400, {"error": "Invalid resource. Please fix errors and try again.", "errors": {"name": ["has already been taken. If this is your enterprise and you would like to claim ownership, please contact the current manager of this profile at owner@example.com."], "permalink": [] }}
|
||||
EnterpriseRegistrationService.create()
|
||||
$httpBackend.flush()
|
||||
|
||||
@@ -78,7 +78,7 @@ describe "EnterpriseRegistrationService", ->
|
||||
|
||||
describe "success", ->
|
||||
beforeEach ->
|
||||
$httpBackend.expectPUT("/api/enterprises/78?token=keykeykeykey").respond 200, 6
|
||||
$httpBackend.expectPUT("/api/v0/enterprises/78?token=keykeykeykey").respond 200, 6
|
||||
EnterpriseRegistrationService.update('step')
|
||||
$httpBackend.flush()
|
||||
|
||||
@@ -88,7 +88,7 @@ describe "EnterpriseRegistrationService", ->
|
||||
describe "failure", ->
|
||||
beforeEach ->
|
||||
spyOn(window, "alert")
|
||||
$httpBackend.expectPUT("/api/enterprises/78?token=keykeykeykey").respond 400, 6
|
||||
$httpBackend.expectPUT("/api/v0/enterprises/78?token=keykeykeykey").respond 400, 6
|
||||
EnterpriseRegistrationService.update('step')
|
||||
$httpBackend.flush()
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ describe 'Products service', ->
|
||||
properties = null
|
||||
taxons = null
|
||||
GmapsGeo = {}
|
||||
endpoint = "/api/order_cycles/1/products.json?distributor=1"
|
||||
endpoint = "/api/v0/order_cycles/1/products.json?distributor=1"
|
||||
|
||||
beforeEach ->
|
||||
product =
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
require 'swagger_helper'
|
||||
|
||||
describe 'api/orders', type: :request do
|
||||
path '/api/orders' do
|
||||
describe 'api/v0/orders', type: :request do
|
||||
path '/api/v0/orders' do
|
||||
get('list orders') do
|
||||
tags 'Orders'
|
||||
# type should be replaced with swagger 3.01 valid schema: {type: string} when rswag #317 is resolved:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user