# `PhoenixKitEcommerce.Product`
[🔗](https://github.com/BeamLabEU/phoenix_kit_ecommerce/blob/v0.1.8/lib/phoenix_kit_ecommerce/schemas/product.ex#L1)

Product schema for e-commerce shop.

Supports both physical and digital products with JSONB flexibility.

## Fields

- `title` - Product title (required)
- `slug` - URL-friendly identifier (unique)
- `description` - Short description
- `body_html` - Full rich text description
- `status` - draft | active | archived
- `product_type` - physical | digital
- `vendor` - Brand/manufacturer
- `tags` - JSONB array of tags
- `price` - Base price (required)
- `compare_at_price` - Original price for discounts
- `cost_per_item` - Cost for profit calculation
- `currency` - ISO currency code (default: USD)
- `taxable` - Subject to tax
- `weight_grams` - Weight for shipping
- `requires_shipping` - Needs physical delivery
- `made_to_order` - Always available regardless of inventory
- `images` - JSONB array of image objects
- `featured_image` - Main image URL
- `seo_title` - SEO title
- `seo_description` - SEO description
- `file_uuid` - Storage file reference (digital products)
- `download_limit` - Max downloads (digital)
- `download_expiry_days` - Days until download expires
- `metadata` - JSONB for custom fields

# `t`

```elixir
@type t() :: %PhoenixKitEcommerce.Product{
  __meta__: term(),
  body_html: term(),
  category: term(),
  category_uuid: term(),
  compare_at_price: term(),
  cost_per_item: term(),
  created_by_user: term(),
  created_by_uuid: term(),
  currency: term(),
  description: term(),
  download_expiry_days: term(),
  download_limit: term(),
  featured_image: term(),
  featured_image_uuid: term(),
  file_uuid: term(),
  image_uuids: term(),
  images: term(),
  inserted_at: term(),
  made_to_order: term(),
  metadata: term(),
  price: term(),
  product_type: term(),
  requires_shipping: term(),
  seo_description: term(),
  seo_title: term(),
  slug: term(),
  status: term(),
  tags: term(),
  taxable: term(),
  title: term(),
  updated_at: term(),
  uuid: term(),
  vendor: term(),
  weight_grams: term()
}
```

# `active?`

Returns true if product is active.

# `changeset`

Changeset for product creation and updates.

# `digital?`

Returns true if product is digital.

# `discount_percentage`

Calculates discount percentage.

# `display_price`

Returns the display price (compare_at_price if set, otherwise price).

# `localized_fields`

Returns the list of localized field names.

# `on_sale?`

Returns true if product has a discount (compare_at_price > price).

# `physical?`

Returns true if product is physical.

# `requires_shipping?`

Returns true if product requires shipping.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
