Skip to content

/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_many through ProductProperty join 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 properties array (if present)
    • Filter: GET /admin/products.json?q[properties_id_eq]=123 (products with specific property)
  • 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_many via product_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
  • 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_many via product_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
  • 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_to via property_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
  • 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_many through ProductProperty join 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)
  • Related Documentation: Products
ProductProperty[]
  • Type: has_many via property_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
  • 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_many via property_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 properties array (if present)
    • Filter: GET /admin/properties.json?q[property_type_id_eq]=123
  • 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_to via product_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
  • Related Documentation: Products
Property
  • Type: belongs_to via property_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
  • 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:

bash
curl -X GET "https://your-company.erpax.com/admin/products.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"
bash
curl -X GET "https://your-company.erpax.com/admin/products.json?q[name_cont]=shirt" \
  -H "Accept: application/json"

JavaScript Example:

javascript
const response = await fetch('/admin/products.json', {
  credentials: 'include',
  headers: { 'Accept': 'application/json' }
});
const data = await response.json();

Response (200 OK):

json
{
  "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:

bash
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):

json
{
  "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:

bash
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:

bash
curl -X GET "https://your-company.erpax.com/admin/properties.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"
bash
curl -X GET "https://your-company.erpax.com/admin/properties.json?scope=variant" \
  -H "Accept: application/json"

JavaScript Example:

javascript
const response = await fetch('/admin/properties.json', {
  credentials: 'include',
  headers: { 'Accept': 'application/json' }
});
const data = await response.json();

Response (200 OK):

json
{
  "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:

bash
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):

json
{
  "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:

bash
curl -X GET "https://your-company.erpax.com/admin/property_types.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"
bash
curl -X GET "https://your-company.erpax.com/admin/property_types.json?scope=variant" \
  -H "Accept: application/json"

JavaScript Example:

javascript
const response = await fetch('/admin/property_types.json', {
  credentials: 'include',
  headers: { 'Accept': 'application/json' }
});
const data = await response.json();

Response (200 OK):

json
{
  "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:

bash
curl -X GET "https://your-company.erpax.com/admin/property_types/1.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"

JavaScript Example:

javascript
const response = await fetch('/admin/property_types/1.json', {
  credentials: 'include',
  headers: { 'Accept': 'application/json' }
});
const data = await response.json();

Response (200 OK):

json
{
  "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:

bash
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:

javascript
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):

json
{
  "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:

bash
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:

javascript
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):

json
{
  "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:

bash
curl -X DELETE "https://your-company.erpax.com/admin/property_types/1.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"

JavaScript Example:

javascript
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:

bash
curl -X GET "https://your-company.erpax.com/admin/product_properties.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"
bash
curl -X GET "https://your-company.erpax.com/admin/product_properties.json?q[product_id_eq]=123" \
  -H "Accept: application/json"

JavaScript Example:

javascript
const response = await fetch('/admin/product_properties.json', {
  credentials: 'include',
  headers: { 'Accept': 'application/json' }
});
const data = await response.json();

Response (200 OK):

json
{
  "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:

bash
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:

bash
curl -X GET "https://your-company.erpax.com/admin/product_properties/1.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"

JavaScript Example:

javascript
const response = await fetch('/admin/product_properties/1.json', {
  credentials: 'include',
  headers: { 'Accept': 'application/json' }
});
const data = await response.json();

Response (200 OK):

json
{
  "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:

bash
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:

javascript
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):

json
{
  "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:

bash
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:

javascript
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):

json
{
  "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:

bash
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:

javascript
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):

json
{
  "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:

bash
curl -X DELETE "https://your-company.erpax.com/admin/product_properties/1.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"

JavaScript Example:

javascript
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
  • Items - Sellable product instances created from products
  • Accounting - Accounting integration for products

Released under an open source license.