/admin/catalog
Path: /admin/catalog
Namespace: admin
Resource: catalog
Overview
The Catalog section provides complete product catalog functionality including product templates, properties, property types, and their associations.
ERPax's catalog system allows you to:
- Products - Define product templates with base information
- Properties - Define product characteristics (size, color, material, etc.)
- Property Types - Organize properties into categories
- Product Properties - Associate properties with products
All catalog resources support standard REST operations (GET, POST, PATCH, DELETE).
Relationships
Product Relationships
Model Associations
Product connects to the following resources:
Property[] (via ProductProperty)
- Type:
has_manythroughProductPropertyjoin table - Description: Product properties (characteristics) associated with this product. Properties define product attributes like size, color, material, etc.
- Reverse: Property has many products (via ProductProperty join table)
- API Access:
- Direct: Included in product response as
propertiesarray (if present) - Filter:
GET /admin/products.json?q[properties_id_eq]=123(products with specific property)
- Direct: Included in product response as
- Example: Get all properties for a product:javascript
const product = await fetch('/admin/products/123.json', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json()); const properties = product.product.properties; // Properties included in response
ProductProperty[]
- Type:
has_manyviaproduct_id - Description: Product-property associations linking products to their properties with different kinds (property, variant, option).
- Reverse: ProductProperty belongs to Product (
product_property.product) - API Access:
- Filter:
GET /admin/product_properties.json?q[product_id_eq]=123
- Filter:
- Example: Get all product-property associations for a product:javascript
const productProperties = await fetch('/admin/product_properties.json?q[product_id_eq]=123', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Item[]
- Type:
has_manyviaproduct_id(optional) - Description: Sellable product instances created from this product template. Items are actual sellable products created from products.
- Reverse: Item belongs to Product (
item.product) - API Access:
- Filter:
GET /admin/items.json?q[product_id_eq]=123
- Filter:
- Related Documentation: Items
- Example: Get all items created from a product:javascript
const items = await fetch('/admin/items.json?q[product_id_eq]=123', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Property Relationships
Model Associations
Property connects to the following resources:
PropertyType
- Type:
belongs_toviaproperty_type_id - Field:
property_type_id - Description: Property type category organizing this property. Properties are organized into types (e.g., "Size", "Color", "Material").
- Reverse: PropertyType has many properties (
property_type.properties) - API Access:
- Direct: Included in property response as
property_type_id - Filter:
GET /admin/properties.json?q[property_type_id_eq]=123
- Direct: Included in property response as
- Related Documentation: Property Types
- Example: Get all properties of a specific type:javascript
const properties = await fetch('/admin/properties.json?q[property_type_id_eq]=123', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Product[] (via ProductProperty)
- Type:
has_manythroughProductPropertyjoin table - Description: Products using this property. Properties can be associated with multiple products.
- Reverse: Product has many properties (via ProductProperty join table)
- API Access:
- Filter:
GET /admin/products.json?q[properties_id_eq]=123(products using this property)
- Filter:
- Related Documentation: Products
ProductProperty[]
- Type:
has_manyviaproperty_id - Description: Product-property associations linking this property to products.
- Reverse: ProductProperty belongs to Property (
product_property.property) - API Access:
- Filter:
GET /admin/product_properties.json?q[property_id_eq]=123
- Filter:
- Example: Get all product-property associations for a property:javascript
const productProperties = await fetch('/admin/product_properties.json?q[property_id_eq]=123', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
PropertyType Relationships
Model Associations
PropertyType connects to the following resources:
Property[]
- Type:
has_manyviaproperty_type_id - Description: Properties of this type. Property types organize properties into categories.
- Reverse: Property belongs to PropertyType (
property.property_type) - API Access:
- Direct: Included in property type response as
propertiesarray (if present) - Filter:
GET /admin/properties.json?q[property_type_id_eq]=123
- Direct: Included in property type response as
- Example: Get all properties of a specific type:javascript
const properties = await fetch('/admin/properties.json?q[property_type_id_eq]=123', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
ProductProperty Relationships
Model Associations
ProductProperty connects to the following resources:
Product
- Type:
belongs_toviaproduct_id - Field:
product_id - Description: Associated product in this product-property association.
- Reverse: Product has many product properties (
product.product_properties) - API Access:
- Direct: Included in product property response as
product_id - Filter:
GET /admin/product_properties.json?q[product_id_eq]=123
- Direct: Included in product property response as
- Related Documentation: Products
Property
- Type:
belongs_toviaproperty_id - Field:
property_id - Description: Associated property in this product-property association.
- Reverse: Property has many product properties (
property.product_properties) - API Access:
- Direct: Included in product property response as
property_id - Filter:
GET /admin/product_properties.json?q[property_id_eq]=123
- Direct: Included in product property response as
- Related Documentation: Properties
Relationship Patterns
Creating Product with Properties
- Use Case: Create a product and associate properties with it
- Example:javascript
// First create the product const product = await fetch('/admin/products.json', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ product: { code: 'PROD-001', name: 'T-Shirt', description: 'Cotton T-Shirt' } }) }).then(r => r.json()); // Then associate properties const productProperty = await fetch('/admin/product_properties.json', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ product_property: { product_id: product.product.id, property_id: 1, // Size property kind: 'variant' } }) }).then(r => r.json());
Finding Products by Property
- Use Case: Get all products that have a specific property
- Example:javascript
const products = await fetch('/admin/products.json?q[properties_id_eq]=123', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Creating Item from Product
- Use Case: Create a sellable item from a product template
- Example:javascript
const item = await fetch('/admin/items.json', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ item: { product_id: 123, // Product template ID code: 'ITEM-001', name: 'T-Shirt - Large - Blue', price_cents: 1999 } }) }).then(r => r.json());
Key Features
- Product Templates: Define base product information that can be used to create Items
- Property Management: Organize product characteristics into types and properties
- Product-Property Associations: Link products to their properties with different kinds (property, variant, option)
- Template Support: Duplicate products, properties, and property types from templates
Products
Path: /admin/products
Overview
The Product resource represents product catalog templates. Products define base product information, properties, variants, and options that can be used to create Items (sellable product instances).
Key Features
- Product Templates: Base product definitions with code, name, description
- Properties: Product properties (characteristics)
- Variants: Product variants (different versions of the product)
- Options: Product options (customizable attributes)
- Product Properties: Association with properties through ProductProperty join table
Available Operations
List Products (GET)
Endpoint: GET /admin/products.json
Request Examples:
curl -X GET "https://your-company.erpax.com/admin/products.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"curl -X GET "https://your-company.erpax.com/admin/products.json?q[name_cont]=shirt" \
-H "Accept: application/json"JavaScript Example:
const response = await fetch('/admin/products.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"products": [
{
"id": 1,
"code": "PROD-001",
"name": "T-Shirt",
"description": "Cotton t-shirt",
"created_at": "2024-01-10T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total_pages": 1,
"total_count": 10
}
}Create Product (POST)
Endpoint: POST /admin/products.json
Request Example:
curl -X POST "https://your-company.erpax.com/admin/products.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"product": {
"code": "PROD-001",
"name": "T-Shirt",
"description": "Cotton t-shirt",
"properties": [1, 2],
"variants": [3, 4],
"options": [5]
}
}'Response (201 Created):
{
"product": {
"id": 1,
"code": "PROD-001",
"name": "T-Shirt",
"created_at": "2024-01-15T14:30:00Z"
}
}Create from Template
Endpoint: POST /admin/products.json?template=123
Request Example:
curl -X POST "https://your-company.erpax.com/admin/products.json?template=123" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"Scopes
No custom scopes are configured (uses default 'all' scope).
Filters
- code - Text filter - Filter by product code
- name - Text filter - Filter by product name
- description - Text filter - Filter by description
- product_properties_property_id_in - Select filter (multiple) - Filter by associated properties
- created_at - Date filter - Filter by creation date
- updated_at - Date filter - Filter by update date
Nested Resources
- Product Properties -
/admin/products/:id/product_properties- Manage properties associated with this product
Properties
Path: /admin/properties
Overview
The Property resource represents product characteristics such as size, color, material, or other attributes. Properties are organized by PropertyType and can be associated with Products through ProductProperty.
Key Features
- Property Types: Properties belong to PropertyTypes (e.g., Size, Color, Material)
- Kinds: Properties have different kinds (property, variant, option)
- Product Association: Properties are associated with products via ProductProperty
- Template Support: Properties can be duplicated from templates
Available Operations
List Properties (GET)
Endpoint: GET /admin/properties.json
Request Examples:
curl -X GET "https://your-company.erpax.com/admin/properties.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"curl -X GET "https://your-company.erpax.com/admin/properties.json?scope=variant" \
-H "Accept: application/json"JavaScript Example:
const response = await fetch('/admin/properties.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"properties": [
{
"id": 1,
"property_type_id": 1,
"code": "SIZE-M",
"name": "Medium",
"description": "Medium size",
"created_at": "2024-01-10T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total_pages": 1,
"total_count": 20
}
}Create Property (POST)
Endpoint: POST /admin/properties.json
Request Example:
curl -X POST "https://your-company.erpax.com/admin/properties.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"property": {
"property_type_id": 1,
"code": "SIZE-M",
"name": "Medium",
"description": "Medium size"
}
}'Response (201 Created):
{
"property": {
"id": 1,
"property_type_id": 1,
"code": "SIZE-M",
"name": "Medium",
"created_at": "2024-01-15T14:30:00Z"
}
}Scopes
- all (default) - All properties
- property - Properties of kind 'property'
- variant - Properties of kind 'variant'
- option - Properties of kind 'option'
- Additional scopes based on Property::KINDS
Filters
- property_type - Select filter - Filter by property type
- code - Text filter - Filter by property code
- name - Text filter - Filter by property name
- description - Text filter - Filter by description
- created_at - Date filter - Filter by creation date
- updated_at - Date filter - Filter by update date
Nested Resources
Properties can be nested under PropertyTypes:
- PropertyType Properties -
/admin/property_types/:id/properties- Properties of a specific property type
Property Types
Path: /admin/property_types
Overview
The PropertyType resource represents categories or types of product properties. PropertyTypes organize Properties into logical groups (e.g., Size, Color, Material, Brand).
Key Features
- Kind-Based Organization: PropertyTypes have different kinds (property, variant, option)
- Property Grouping: Properties belong to PropertyTypes
- Template Support: PropertyTypes can be duplicated from templates
Available Operations
List Property Types (GET)
Endpoint: GET /admin/property_types.json
Request Examples:
curl -X GET "https://your-company.erpax.com/admin/property_types.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"curl -X GET "https://your-company.erpax.com/admin/property_types.json?scope=variant" \
-H "Accept: application/json"JavaScript Example:
const response = await fetch('/admin/property_types.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"property_types": [
{
"id": 1,
"kind": "property",
"code": "SIZE",
"name": "Size",
"description": "Product size variations",
"created_at": "2024-01-10T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total_pages": 1,
"total_count": 5
}
}Show Property Type (GET /:id)
Endpoint: GET /admin/property_types/:id.json
Request Example:
curl -X GET "https://your-company.erpax.com/admin/property_types/1.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"JavaScript Example:
const response = await fetch('/admin/property_types/1.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"property_type": {
"id": 1,
"kind": "property",
"code": "SIZE",
"name": "Size",
"description": "Product size variations",
"created_at": "2024-01-10T10:00:00Z",
"updated_at": "2024-01-15T12:00:00Z"
}
}Create Property Type (POST)
Endpoint: POST /admin/property_types.json
Request Example:
curl -X POST "https://your-company.erpax.com/admin/property_types.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"property_type": {
"kind": "property",
"code": "SIZE",
"name": "Size",
"description": "Product size variations"
}
}'JavaScript Example:
const response = await fetch('/admin/property_types.json', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
property_type: {
kind: 'property',
code: 'SIZE',
name: 'Size',
description: 'Product size variations'
}
})
});
const data = await response.json();Response (201 Created):
{
"property_type": {
"id": 1,
"kind": "property",
"code": "SIZE",
"name": "Size",
"created_at": "2024-01-15T14:30:00Z"
}
}Update Property Type (PATCH /:id)
Endpoint: PATCH /admin/property_types/:id.json
Request Example:
curl -X PATCH "https://your-company.erpax.com/admin/property_types/1.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"property_type": {
"description": "Updated description for size variations"
}
}'JavaScript Example:
const response = await fetch('/admin/property_types/1.json', {
method: 'PATCH',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
property_type: {
description: 'Updated description for size variations'
}
})
});
const data = await response.json();Response (200 OK):
{
"property_type": {
"id": 1,
"description": "Updated description for size variations",
"updated_at": "2024-01-15T15:00:00Z"
}
}Delete Property Type (DELETE /:id)
Endpoint: DELETE /admin/property_types/:id.json
Request Example:
curl -X DELETE "https://your-company.erpax.com/admin/property_types/1.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"JavaScript Example:
const response = await fetch('/admin/property_types/1.json', {
method: 'DELETE',
credentials: 'include',
headers: { 'Accept': 'application/json' }
});Response (204 No Content):
(empty response)Scopes
- all (default) - All property types
- Additional scopes based on PropertyType::KINDS (property, variant, option, etc.)
Filters
- kind - Select filter - Filter by kind (from PropertyType::KINDS collection)
- code - Text filter - Filter by property type code
- name - Text filter - Filter by property type name
- description - Text filter - Filter by description
- created_at - Date filter - Filter by creation date
- updated_at - Date filter - Filter by update date
Nested Resources
- Properties -
/admin/property_types/:id/properties- Properties of this property type
Product Properties
Path: /admin/product_properties
Overview
The ProductProperty resource represents the association between Products and Properties. This join table allows products to have multiple properties with different kinds (property, variant, option) and positions.
Key Features
- Product-Property Association: Links products to their properties
- Kinds: Supports different property kinds (property, variant, option)
- Positioning: Properties can be ordered by position
- Nested Management: Can be managed through products at
/admin/products/:id/product_properties
Available Operations
List Product Properties (GET)
Endpoint: GET /admin/product_properties.json
Request Examples:
curl -X GET "https://your-company.erpax.com/admin/product_properties.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"curl -X GET "https://your-company.erpax.com/admin/product_properties.json?q[product_id_eq]=123" \
-H "Accept: application/json"JavaScript Example:
const response = await fetch('/admin/product_properties.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"product_properties": [
{
"id": 1,
"product_id": 123,
"property_id": 456,
"kind": "variant",
"position": 1,
"created_at": "2024-01-15T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total_pages": 1,
"total_count": 5
}
}List via Product (Nested)
Endpoint: GET /admin/products/:id/product_properties.json
Request Example:
curl -X GET "https://your-company.erpax.com/admin/products/123/product_properties.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"Show Product Property (GET /:id)
Endpoint: GET /admin/product_properties/:id.json
Request Example:
curl -X GET "https://your-company.erpax.com/admin/product_properties/1.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"JavaScript Example:
const response = await fetch('/admin/product_properties/1.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"product_property": {
"id": 1,
"product_id": 123,
"property_id": 456,
"kind": "variant",
"position": 1,
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-15T12:00:00Z"
}
}Create Product Property (POST)
Endpoint: POST /admin/product_properties.json
Request Example:
curl -X POST "https://your-company.erpax.com/admin/product_properties.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"product_property": {
"product_id": 123,
"property_id": 456,
"kind": "variant",
"position": 1
}
}'JavaScript Example:
const response = await fetch('/admin/product_properties.json', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
product_property: {
product_id: 123,
property_id: 456,
kind: 'variant',
position: 1
}
})
});
const data = await response.json();Response (201 Created):
{
"product_property": {
"id": 1,
"product_id": 123,
"property_id": 456,
"kind": "variant",
"position": 1,
"created_at": "2024-01-15T14:30:00Z"
}
}Create via Product (Nested)
Endpoint: POST /admin/products/:id/product_properties.json
Request Example:
curl -X POST "https://your-company.erpax.com/admin/products/123/product_properties.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"product_property": {
"property_id": 456,
"kind": "variant",
"position": 1
}
}'JavaScript Example:
const response = await fetch('/admin/products/123/product_properties.json', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
product_property: {
property_id: 456,
kind: 'variant',
position: 1
}
})
});
const data = await response.json();Response (201 Created):
{
"product_property": {
"id": 2,
"product_id": 123,
"property_id": 456,
"kind": "variant",
"position": 1,
"created_at": "2024-01-15T14:30:00Z"
}
}Update Product Property (PATCH /:id)
Endpoint: PATCH /admin/product_properties/:id.json
Request Example:
curl -X PATCH "https://your-company.erpax.com/admin/product_properties/1.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"product_property": {
"position": 2,
"kind": "option"
}
}'JavaScript Example:
const response = await fetch('/admin/product_properties/1.json', {
method: 'PATCH',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
product_property: {
position: 2,
kind: 'option'
}
})
});
const data = await response.json();Response (200 OK):
{
"product_property": {
"id": 1,
"position": 2,
"kind": "option",
"updated_at": "2024-01-15T15:00:00Z"
}
}Delete Product Property (DELETE /:id)
Endpoint: DELETE /admin/product_properties/:id.json
Request Example:
curl -X DELETE "https://your-company.erpax.com/admin/product_properties/1.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"JavaScript Example:
const response = await fetch('/admin/product_properties/1.json', {
method: 'DELETE',
credentials: 'include',
headers: { 'Accept': 'application/json' }
});Response (204 No Content):
(empty response)Business Rules
- Product Templates: Products serve as templates for creating Items
- Property Organization: Properties are organized by PropertyTypes
- Product-Property Association: Products can have multiple properties with different kinds
- Template Support: Products, properties, and property types can be duplicated from templates
Related Resources
- Items - Sellable product instances created from products
- Accounting - Accounting integration for products