mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-04-04 07:09:14 +00:00
Add balance to api v1 customers endpoint
- customers#show: Add balance (data_type: double) to customer attributes. - customers#index: Add balance only if specified in extra_fields query parameter: extra_fields[customer]=balance
This commit is contained in:
@@ -6,11 +6,17 @@ module Api
|
||||
module V1
|
||||
class CustomersController < Api::V1::BaseController
|
||||
include AddressTransformation
|
||||
include ExtraFields
|
||||
|
||||
skip_authorization_check only: :index
|
||||
|
||||
before_action :authorize_action, only: [:show, :update, :destroy]
|
||||
|
||||
# Query parameters
|
||||
before_action only: [:index] do
|
||||
@extra_customer_fields = extra_fields :customer, [:balance]
|
||||
end
|
||||
|
||||
def index
|
||||
@pagy, customers = pagy(search_customers, pagy_options)
|
||||
|
||||
@@ -51,7 +57,11 @@ module Api
|
||||
private
|
||||
|
||||
def customer
|
||||
@customer ||= Customer.find(params[:id])
|
||||
@customer ||= if action_name == "show"
|
||||
CustomersWithBalance.new(Customer.where(id: params[:id])).query.first!
|
||||
else
|
||||
Customer.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
||||
def authorize_action
|
||||
@@ -61,6 +71,11 @@ module Api
|
||||
def search_customers
|
||||
customers = visible_customers.includes(:bill_address, :ship_address)
|
||||
customers = customers.where(enterprise_id: params[:enterprise_id]) if params[:enterprise_id]
|
||||
|
||||
if @extra_customer_fields.include?(:balance)
|
||||
customers = CustomersWithBalance.new(customers).query
|
||||
end
|
||||
|
||||
customers.ransack(params[:q]).result.order(:id)
|
||||
end
|
||||
|
||||
|
||||
@@ -61,4 +61,9 @@ class CustomerSchema < JsonApiSchema
|
||||
def self.relationships
|
||||
[:enterprise]
|
||||
end
|
||||
|
||||
# Optional attributes included with eg: CustomerSchema.schema(extra_fields: :balance)
|
||||
def self.balance
|
||||
{ balance: { type: :number, format: :double } }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,6 +16,10 @@ module Api
|
||||
address(object.shipping_address)
|
||||
end
|
||||
|
||||
attribute :balance, if: proc { |record|
|
||||
record.respond_to?(:balance_value)
|
||||
}, &:balance_value
|
||||
|
||||
belongs_to :enterprise, links: {
|
||||
related: ->(object) {
|
||||
url_helpers.api_v1_enterprise_url(id: object.enterprise_id)
|
||||
|
||||
@@ -26,10 +26,13 @@ describe "Customers", type: :request do
|
||||
get "List customers" do
|
||||
tags "Customers"
|
||||
parameter name: :enterprise_id, in: :query, type: :string
|
||||
parameter name: "extra_fields[customer]", in: :query, type: :string, example: :balance,
|
||||
description: "Add extra fields to each customer"
|
||||
produces "application/json"
|
||||
|
||||
response "200", "Customers list" do
|
||||
param(:enterprise_id) { enterprise1.id }
|
||||
param("extra_fields[customer]") { :balance }
|
||||
schema "$ref": "#/components/schemas/customers_collection"
|
||||
|
||||
run_test!
|
||||
@@ -105,6 +108,33 @@ describe "Customers", type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
describe "query parameters" do
|
||||
describe "extra_fields[customer]" do
|
||||
context "with balance" do
|
||||
it "adds balance to each customer" do
|
||||
get "/api/v1/customers", params: { extra_fields: { customer: :balance } }
|
||||
balances = json_response[:data].map{ |c| c[:attributes][:balance] }
|
||||
expect(balances.all?{ |b| b.is_a? Numeric }).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "with unknown field" do
|
||||
it "returns unprocessable entity" do
|
||||
get "/api/v1/customers", params: { extra_fields: { customer: :unknown } }
|
||||
expect([response.status, json_error_detail]).to eq [422, "Unsupported fields: unknown"]
|
||||
end
|
||||
end
|
||||
|
||||
context "when not recevied" do
|
||||
it "does not add balances" do
|
||||
get "/api/v1/customers"
|
||||
balances = json_response[:data].map{ |c| c[:attributes][:balance] }
|
||||
expect([response.status, balances.compact]).to eq [200, []]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
post "Create customer" do
|
||||
tags "Customers"
|
||||
consumes "application/json"
|
||||
@@ -191,7 +221,10 @@ describe "Customers", type: :request do
|
||||
|
||||
response "200", "Customer" do
|
||||
param(:id) { customer1.id }
|
||||
schema "$ref": "#/components/schemas/customer"
|
||||
schema CustomerSchema.schema(
|
||||
require_all: true,
|
||||
extra_fields: { name: :balance, required: true }
|
||||
)
|
||||
|
||||
run_test! do
|
||||
date_time_string =
|
||||
|
||||
@@ -27,8 +27,9 @@ RSpec.configure do |config|
|
||||
components: {
|
||||
schemas: {
|
||||
error_response: ErrorsSchema.schema,
|
||||
# only customer#show is with extra_fields: {name: :balance, required: true}
|
||||
customer: CustomerSchema.schema(require_all: true),
|
||||
customers_collection: CustomerSchema.collection(require_all: true)
|
||||
customers_collection: CustomerSchema.collection(require_all: true, extra_fields: :balance)
|
||||
},
|
||||
securitySchemes: {
|
||||
api_key_header: {
|
||||
|
||||
@@ -210,6 +210,9 @@ components:
|
||||
country:
|
||||
code: AU
|
||||
name: Australia
|
||||
balance:
|
||||
type: number
|
||||
format: double
|
||||
required:
|
||||
- id
|
||||
- enterprise_id
|
||||
@@ -307,6 +310,12 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
- name: extra_fields[customer]
|
||||
in: query
|
||||
example: balance
|
||||
description: Add extra fields to each customer
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Customers list
|
||||
@@ -406,7 +415,120 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
"$ref": "#/components/schemas/customer"
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
example: '1'
|
||||
type:
|
||||
type: string
|
||||
example: customer
|
||||
attributes:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
example: 1
|
||||
enterprise_id:
|
||||
type: integer
|
||||
example: 2
|
||||
first_name:
|
||||
type: string
|
||||
nullable: true
|
||||
example: Alice
|
||||
last_name:
|
||||
type: string
|
||||
nullable: true
|
||||
example: Springs
|
||||
code:
|
||||
type: string
|
||||
nullable: true
|
||||
example: BUYER1
|
||||
email:
|
||||
type: string
|
||||
example: alice@example.com
|
||||
allow_charges:
|
||||
type: boolean
|
||||
example: false
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example:
|
||||
- staff
|
||||
- discount
|
||||
terms_and_conditions_accepted_at:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
example: '2022-03-12T15:55:00.000+11:00'
|
||||
billing_address:
|
||||
type: object
|
||||
nullable: true
|
||||
example:
|
||||
shipping_address:
|
||||
type: object
|
||||
nullable: true
|
||||
example:
|
||||
phone: 0404 333 222 111
|
||||
latitude: -37.8173751
|
||||
longitude: 144.964803195704
|
||||
first_name: Alice
|
||||
last_name: Springs
|
||||
street_address_1: 1 Flinders Street
|
||||
street_address_2: ''
|
||||
postal_code: '1234'
|
||||
locality: Melbourne
|
||||
region:
|
||||
code: Vic
|
||||
name: Victoria
|
||||
country:
|
||||
code: AU
|
||||
name: Australia
|
||||
balance:
|
||||
type: number
|
||||
format: double
|
||||
required:
|
||||
- id
|
||||
- enterprise_id
|
||||
- first_name
|
||||
- last_name
|
||||
- code
|
||||
- email
|
||||
- allow_charges
|
||||
- tags
|
||||
- terms_and_conditions_accepted_at
|
||||
- billing_address
|
||||
- shipping_address
|
||||
- balance
|
||||
relationships:
|
||||
type: object
|
||||
properties:
|
||||
enterprise:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
example: enterprise
|
||||
links:
|
||||
type: object
|
||||
properties:
|
||||
related:
|
||||
type: string
|
||||
meta:
|
||||
type: object
|
||||
links:
|
||||
type: object
|
||||
required:
|
||||
- data
|
||||
'404':
|
||||
description: Not found
|
||||
content:
|
||||
|
||||
Reference in New Issue
Block a user