API v1 orders endpoints
This commit is contained in:
parent
7d5155bef6
commit
127ae83f04
9 changed files with 165 additions and 10 deletions
19
app/controllers/api/v1/orders_controller.rb
Normal file
19
app/controllers/api/v1/orders_controller.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
class Api::V1::OrdersController < Api::V1::BaseController
|
||||
include Concerns::CollectionScope
|
||||
|
||||
before_action ->{ doorkeeper_authorize! 'orders:read', 'orders:write' }
|
||||
|
||||
def index
|
||||
render_collection search_scope
|
||||
end
|
||||
|
||||
def show
|
||||
render json: scope.find(params.require(:id))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scope
|
||||
Order.includes(:supplier)
|
||||
end
|
||||
end
|
|
@ -53,14 +53,19 @@ module Concerns::AuthApi
|
|||
end
|
||||
|
||||
case scope_parts.first
|
||||
when 'user' then true # access to the current user's own profile
|
||||
when 'config' then current_user.role_admin?
|
||||
when 'users' then current_user.role_admin?
|
||||
when 'workgroups' then current_user.role_admin?
|
||||
when 'suppliers' then current_user.role_suppliers?
|
||||
when 'group_orders' then current_user.role_orders?
|
||||
when 'finance' then current_user.role_finance?
|
||||
when 'user' then return true # access to the current user's own profile
|
||||
when 'config' then return current_user.role_admin?
|
||||
when 'users' then return current_user.role_admin?
|
||||
when 'workgroups' then return current_user.role_admin?
|
||||
when 'suppliers' then return current_user.role_suppliers?
|
||||
when 'group_orders' then return current_user.role_orders?
|
||||
when 'finance' then return current_user.role_finance?
|
||||
# please note that offline_access does not belong here, since it is not used for permission checking
|
||||
end
|
||||
|
||||
case scope
|
||||
when 'orders:read' then return true
|
||||
when 'orders:write' then return current_user.role_orders?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,6 +51,14 @@ class Order < ApplicationRecord
|
|||
include DateTimeAttributeValidate
|
||||
date_time_attribute :starts, :boxfill, :ends
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w(id state supplier_id starts boxfill ends pickup)
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
%w(supplier articles order_articles)
|
||||
end
|
||||
|
||||
def stockit?
|
||||
supplier_id.nil?
|
||||
end
|
||||
|
@ -111,11 +119,11 @@ class Order < ApplicationRecord
|
|||
end
|
||||
|
||||
def boxfill?
|
||||
FoodsoftConfig[:use_boxfill] && open? && boxfill.present? && boxfill < Time.now
|
||||
!!FoodsoftConfig[:use_boxfill] && open? && boxfill.present? && boxfill < Time.now
|
||||
end
|
||||
|
||||
def is_boxfill_useful?
|
||||
FoodsoftConfig[:use_boxfill] && supplier.try(:has_tolerance?)
|
||||
!!FoodsoftConfig[:use_boxfill] && !!supplier.try(:has_tolerance?)
|
||||
end
|
||||
|
||||
def expired?
|
||||
|
|
|
@ -23,6 +23,14 @@ class Supplier < ApplicationRecord
|
|||
scope :undeleted, -> { where(deleted_at: nil) }
|
||||
scope :having_articles, -> { where(id: Article.undeleted.select(:supplier_id).distinct) }
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w(id name)
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
%w(articles stock_articles orders)
|
||||
end
|
||||
|
||||
# sync all articles with the external database
|
||||
# returns an array with articles(and prices), which should be updated (to use in a form)
|
||||
# also returns an array with outlisted_articles, which should be deleted
|
||||
|
|
11
app/serializers/order_serializer.rb
Normal file
11
app/serializers/order_serializer.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
class OrderSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :starts, :ends, :boxfill, :pickup, :is_open, :is_boxfill
|
||||
|
||||
def is_open
|
||||
object.open?
|
||||
end
|
||||
|
||||
def is_boxfill
|
||||
object.boxfill?
|
||||
end
|
||||
end
|
|
@ -49,10 +49,11 @@ Doorkeeper.configure do
|
|||
# https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
|
||||
|
||||
# default is a collection of read-only scopes
|
||||
default_scopes 'config:user', 'finance:user', 'user:read'
|
||||
default_scopes 'config:user', 'finance:user', 'user:read', 'orders:read'
|
||||
|
||||
optional_scopes 'config:read', 'config:write',
|
||||
'finance:read', 'finance:write',
|
||||
'orders:write',
|
||||
'user:write',
|
||||
'offline_access'
|
||||
|
||||
|
|
|
@ -271,6 +271,7 @@ Rails.application.routes.draw do
|
|||
resources :financial_transaction_classes, only: [:index, :show]
|
||||
resources :financial_transaction_types, only: [:index, :show]
|
||||
resources :financial_transactions, only: [:index, :show]
|
||||
resources :orders, only: [:index, :show]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -179,6 +179,65 @@ paths:
|
|||
$ref: '#/definitions/Error404'
|
||||
security:
|
||||
- foodsoft_auth: ['finance:read', 'finance:write']
|
||||
/orders:
|
||||
get:
|
||||
summary: orders
|
||||
tags:
|
||||
- 2. Orders
|
||||
parameters:
|
||||
- $ref: '#/parameters/page'
|
||||
- $ref: '#/parameters/per_page'
|
||||
responses:
|
||||
200:
|
||||
description: success
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
orders:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Order'
|
||||
meta:
|
||||
$ref: '#/definitions/Meta'
|
||||
401:
|
||||
description: not logged-in
|
||||
schema:
|
||||
$ref: '#/definitions/Error401'
|
||||
403:
|
||||
description: missing scope or no permission
|
||||
schema:
|
||||
$ref: '#/definitions/Error403'
|
||||
security:
|
||||
- foodsoft_auth: ['orders:read', 'orders:write']
|
||||
/orders/{id}:
|
||||
parameters:
|
||||
- $ref: '#/parameters/idInUrl'
|
||||
get:
|
||||
summary: find order by id
|
||||
tags:
|
||||
- 2. Order
|
||||
responses:
|
||||
200:
|
||||
description: success
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
order:
|
||||
$ref: '#/definitions/Order'
|
||||
401:
|
||||
description: not logged-in
|
||||
schema:
|
||||
$ref: '#/definitions/Error401'
|
||||
403:
|
||||
description: missing scope or no permission
|
||||
schema:
|
||||
$ref: '#/definitions/Error403'
|
||||
404:
|
||||
description: not found
|
||||
schema:
|
||||
$ref: '#/definitions/Error404'
|
||||
security:
|
||||
- foodsoft_auth: ['orders:read', 'orders:write']
|
||||
|
||||
/financial_transaction_classes:
|
||||
get:
|
||||
|
@ -436,6 +495,37 @@ definitions:
|
|||
description: name of the class of the transaction
|
||||
required: ['id', 'name', 'financial_transaction_class_id', 'financial_transaction_class_name']
|
||||
|
||||
Order:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
description: name of the order's supplier (or stock)
|
||||
starts:
|
||||
type: string
|
||||
format: date-time
|
||||
description: when the order was opened
|
||||
ends:
|
||||
type: ['string', 'null']
|
||||
format: date-time
|
||||
description: when the order will close or was closed
|
||||
boxfill:
|
||||
type: ['string', 'null']
|
||||
format: date-time
|
||||
description: when the order will enter or entered the boxfill phase
|
||||
pickup:
|
||||
type: ['string', 'null']
|
||||
format: date
|
||||
description: pickup date
|
||||
is_open:
|
||||
type: boolean
|
||||
description: if the order is currently open or not
|
||||
is_boxfill:
|
||||
type: boolean
|
||||
description: if the order is currently in the boxfill phase or not
|
||||
|
||||
Navigation:
|
||||
type: array
|
||||
items:
|
||||
|
|
|
@ -113,6 +113,18 @@ describe 'API v1', type: :apivore, order: :defined do
|
|||
it_handles_invalid_token(:get, '/financial_transaction_types')
|
||||
it_handles_invalid_token(:get, '/financial_transaction_types/{id}', ->{ api_auth({'id' => tpy_1.id }) })
|
||||
end
|
||||
|
||||
context 'orders' do
|
||||
let(:api_scopes) { ['orders:read'] }
|
||||
let!(:order) { create :order }
|
||||
|
||||
it { is_expected.to validate(:get, '/orders', 200, api_auth) }
|
||||
it { is_expected.to validate(:get, '/orders/{id}', 200, api_auth({'id' => order.id})) }
|
||||
it { is_expected.to validate(:get, '/orders/{id}', 404, api_auth({'id' => Order.last.id + 1})) }
|
||||
|
||||
it_handles_invalid_token_and_scope(:get, '/orders')
|
||||
it_handles_invalid_token_and_scope(:get, '/orders/{id}', ->{ api_auth({'id' => order.id}) })
|
||||
end
|
||||
end
|
||||
|
||||
# needs to be last context so it is always run at the end
|
||||
|
|
Loading…
Reference in a new issue