La oferta de un Good en una Branch: es lo que un comercio realmente lista y
vende. Mientras el Good define qué es el producto, el BranchGood agrega el
precio de venta, el stock y la disponibilidad de esa sucursal, además del precio
personalizado según el cliente que consulta (ver BranchPriceList). Al asociar un Good
a un Branch se copian en cascada sus propiedades (GoodProperty) con sus valores por
defecto.
min_price_e2 — precio de venta del producto (× 100) en la moneda local del comercio. El
nombre quedó así por retro-compatibilidad: no es un precio mínimo. Cuando un admin edita
el precio de venta, edita este atributo.custom_data (solo lectura) — objeto con los distintos precios ya calculados, incluido el
monto formateado:
display_price — precio a mostrar (visual).list_price — precio original; mostrar tachado si difiere de display_price (suele indicar descuento).price_e2 — precio efectivo para sumar al carrito.unit_ — monto por unidad (p. ej. el precio por Kg en productos por peso).extras_ — monto mínimo según los extras obligatorios del producto.currency — moneda local del comercio.conversion — los mismos montos convertidos a otra moneda. Se elige con el header
X-Currency: <ISO> (debe ser una moneda soportada por la Company); por defecto, la moneda local.real_prices — precios reales en la moneda local del comercio, para uso del administrador.quantity_real — inventario disponible, o null si es ilimitado.has_stock_for_selling — false si el stock no alcanza para vender.available — lo habilitó/deshabilitó un administrador.available_for_selling — false si available es false o no hay stock. Para mostrar
un producto agotado, evaluar available_for_selling === false.unit_config)Configuración para vender por fracción/peso:
enabled — si la configuración de unidad está activa.display_mode — cómo mostrarla en pantalla.fraction — unidades de división por cada unidad de stock. Ej. 1000 = 1 unidad equivale a
1000 Gr; cada venta de 1000 reduce el stock en 1.min_quantity / max_quantity / step_quantity — mínimo, máximo e incremento a vender, en fraction.unit_name — la unidad que representa fraction (ej. Gr). Nota: la unidad "grande" (Kg)
va en Good.unit; quedaría Good.unit = 'Kg', unit_name = 'Gr', fraction = 1000.weight_per_unit — peso estimado por unidad (ej. una manzana ≈ 205 Gr). Sirve para armar
interfaces de venta por unidad en productos por peso; se puede usar aun con enabled = false.weight_per_unit (atributo del BranchGood) equivale a ese unit_config.weight_per_unit.
notes_enabled — pedir instrucciones especiales (opcionales) al ordenar.tags — etiquetas del producto; $Hot es una etiqueta gestionada por el sistema para los
más vendidos 🔥.promo_id / promo_info — promoción activa sobre este producto en la sucursal (mismo formato
de promo_info que en Branch).featured_good_config / featured_in_order — configuración y orden del producto cuando está destacado.discount_info — detalle del descuento aplicado.list_order — orden del producto dentro de su categoría en la sucursal.tax / sale_tax — cálculo de impuestos (AmountWithTax) sobre el
precio de lista y sobre el precio de venta. price_before_tax_e2 / price_after_tax_e2 y
applied_tax_e2 son los montos resultantes.| Atributo | Tipo | Descripción |
|---|---|---|
id |
int |
|
min_price_e2 |
int |
Precio de venta del producto en la moneda local del comercio (× 100). No es un precio mínimo (nombre por retro-compatibilidad) |
rating_e2 |
int |
Rating del producto en la sucursal (× 100) |
rating_sum |
int |
Suma de calificaciones recibidas |
rating_count |
int |
Cantidad de calificaciones recibidas |
available |
bool |
El administrador habilitó el producto para la venta |
provider_fee_e2 |
int |
Comisión del proveedor por vender este producto, monto fijo (× 100) |
provider_fee_prc |
float |
Comisión del proveedor, porcentaje (fracción 0–1) |
created_at |
datetime\|null |
|
updated_at |
datetime\|null |
|
branch_id |
int |
Sucursal que ofrece el producto |
good_id |
int |
{@link Good} ofertado |
branch_group_id |
int\|null |
Comercio (marca) de la sucursal |
eta |
string\|null |
Tiempo estimado de preparación del producto en esta sucursal |
promo_id |
int\|null |
{@link Coupon} de la promoción activa sobre este producto |
promo_info |
string\|null |
Etiqueta de la promoción (ver formato en {@link Branch}) |
last_sync_id |
int\|null |
Referencia de la última sincronización de catálogo |
quantity_real |
float\|null |
Inventario disponible; null = ilimitado |
extras_price_e2 |
int\|null |
Monto mínimo por los extras obligatorios (× 100) |
list_order |
int |
Orden del producto dentro de su categoría en la sucursal |
computed |
array |
Caché interno de valores derivados (oculto) |
featured_good_config |
FeaturedGoodConfig\|null |
Configuración del producto cuando está destacado |
discount_info |
DiscountInfo\|null |
Detalle del descuento aplicado |
materials_stock |
float\|null |
Stock derivado de los insumos del producto |
tax |
AmountWithTax |
Cálculo de impuestos sobre el precio de lista |
sale_tax |
AmountWithTax |
Cálculo de impuestos sobre el precio de venta |
allLogs |
ApiLog> |
|
applied_tax_e2 |
int |
Impuesto aplicado al precio de venta (× 100) |
available_for_selling |
bool |
El producto se puede comprar (habilitado y con stock) |
barcodes |
array\|null |
Códigos de barras del producto |
base_unit_sale_price_e2 |
int |
Precio de venta por unidad base, sin extras (× 100) |
branch |
Branch |
|
branchGoodProperties |
BranchGoodProperty> |
Propiedades/variantes del producto en la sucursal |
branchGroup |
BranchGroup\|null |
|
calculated_eta |
int\|null |
ETA calculado del producto (minutos) |
categories |
Category> |
Categorías del producto en la sucursal |
custom_data |
array |
Precios ya calculados del producto (ver "Precio") |
featured_in_order |
int\|null |
Orden del producto cuando está destacado |
details |
mixed |
Descripción larga (heredado del {@link Good}) |
eta_config |
EtaConfig\|null |
Configuración de ETA (heredado del {@link Good}) |
good_type_id |
mixed |
{@link GoodType} (heredado del {@link Good}) |
limit_type |
mixed |
Ventana del límite de compra (heredado del {@link Good}) |
max_quantity |
mixed |
Límite de compra por cliente (heredado del {@link Good}) |
name |
mixed |
Nombre del producto (heredado del {@link Good}) |
notes_enabled |
mixed |
Pedir instrucciones especiales al ordenar (heredado del {@link Good}) |
picture_urls |
mixed |
Imágenes horizontales (heredado del {@link Good}) |
short_details |
mixed |
Descripción corta (heredado del {@link Good}) |
sku |
mixed |
Código SKU (heredado del {@link Good}) |
tags |
array\|null |
Etiquetas del producto; $Hot = más vendidos, gestionada por el sistema |
type |
mixed |
Bitmask de tipo (heredado del {@link Good}) |
unit |
mixed |
Unidad de venta (heredado del {@link Good}) |
vertical_picture_urls |
mixed |
Imágenes verticales (heredado del {@link Good}) |
weight_per_unit |
string\|null |
Peso estimado por unidad (= unit_config.weight_per_unit) |
good |
Good |
|
goodCategories |
GoodCategory> |
|
goodProperties |
GoodProperty> |
|
has_fixed_stock |
bool |
El producto maneja stock fijo (quantity_real no es null) |
has_stock_for_selling |
bool |
Hay stock suficiente para vender |
is_combo |
bool\|null |
El producto es un combo (heredado del {@link Good}) |
is_service |
bool |
El producto es un servicio (heredado del {@link Good}) |
label |
string\|null |
Etiqueta destacada del producto (heredado del {@link Good}) |
logs |
ApiLog> |
|
materials |
GoodMaterial> |
|
presentation |
string\|null |
Texto de presentación para mostrar (heredado del {@link Good}) |
price_after_tax |
Money |
Precio de venta con impuesto incluido |
price_after_tax_e2 |
int |
Precio de venta con impuesto, monto (× 100) |
price_before_tax |
Money |
Precio de venta sin impuesto |
price_before_tax_e2 |
int |
Precio de venta sin impuesto, monto (× 100) |
promo |
Coupon\|null |
Cupón de la promoción activa |
properties |
Property> |
|
quantity |
int\|null |
Cantidad disponible en unidades de stock |
quantity_real_available |
float\|null |
Inventario realmente disponible (descuenta reservas); null = ilimitado |
sales |
OrderedGood> |
Ventas del producto en la sucursal |
unit_config |
SellingUnit\|null |
Configuración de venta por peso/fracción (ver "Unidad de venta") |
{
"id": 92,
"min_price_e2": 1200,
"rating_e2": 0,
"rating_sum": 0,
"rating_count": 0,
"available": false,
"provider_fee_e2": 0,
"provider_fee_prc": 0,
"created_at": "2020-04-20 20:37:52",
"updated_at": "2025-08-20 15:02:58",
"branch_id": 22,
"good_id": 105,
"branch_group_id": 42,
"eta": null,
"promo_id": null,
"promo_info": null,
"last_sync_id": 639,
"quantity_real": 0,
"extras_price_e2": 0,
"list_order": 65535,
"featured_good_config": null,
"good_type_id": null,
"sku": null,
"type": 0,
"name": "Prueba2",
"unit": "und",
"presentation": "per_unit",
"max_quantity": null,
"limit_type": null,
"details": "Aaaa",
"short_details": "n/a",
"picture_urls": [
"http://127.0.0.1:8000/storage/static/default/product_category_logo.png"
],
"vertical_picture_urls": [
"http://127.0.0.1:8000/storage/static/default/product_category_logo_portrait.jpg"
],
"notes_enabled": true,
"custom_data": {
"list_price_e2": 1200,
"display_price_e2": 1200,
"price_e2": 1200,
"extras_list_price_e2": 0,
"extras_display_price_e2": 0,
"extras_price_e2": 0,
"client_id": null,
"branch_price_list_id": 426,
"currency": {
"id": 476,
"enabled": true,
"iso": "USD",
"symbol": "$",
"conversion_factor": 1,
"related_iso": "USD",
"decimals_count": 2,
"format": "0.00$",
"decimal_point": ".",
"use_thousands_separator": true,
"thousands_separator": ",",
"is_local": true,
"is_international": true,
"created_at": "2021-07-15 19:22:15",
"updated_at": "2025-11-25 13:45:57",
"company_id": 116,
"is_custom": false,
"branch_id": 22,
"auto_sync": true,
"auto_sync_provider": "legacy",
"use_conversion": false,
"available": true,
"related_iso_expected": "USD",
"related_iso_error": false
},
"conversion": {
"list_price_e2": 1200,
"display_price_e2": 1200,
"price_e2": 1200,
"extras_list_price_e2": 0,
"extras_display_price_e2": 0,
"extras_price_e2": 0,
"currency": {
"id": 476,
"enabled": true,
"iso": "USD",
"symbol": "$",
"conversion_factor": 1,
"related_iso": "USD",
"decimals_count": 2,
"format": "0.00$",
"decimal_point": ".",
"use_thousands_separator": true,
"thousands_separator": ",",
"is_local": true,
"is_international": true,
"created_at": "2021-07-15 19:22:15",
"updated_at": "2025-11-25 13:45:57",
"company_id": 116,
"is_custom": false,
"branch_id": 22,
"auto_sync": true,
"auto_sync_provider": "legacy",
"use_conversion": false,
"available": true,
"related_iso_expected": "USD",
"related_iso_error": false
},
"list_price": "12.00$",
"display_price": "12.00$"
},
"real_prices": {
"list_price_e2": 1200,
"display_price_e2": 1200,
"price_e2": 1200,
"extras_list_price_e2": 0,
"extras_display_price_e2": 0,
"extras_price_e2": 0
},
"list_price": "12.00$",
"display_price": "12.00$",
"unit_list_price": "12.00$",
"unit_display_price": "12.00$"
},
"quantity_real_available": 0,
"quantity": 0,
"unit_config": null,
"weight_per_unit": null,
"has_stock_for_selling": false,
"available_for_selling": false,
"calculated_eta": null,
"eta_config": null,
"tags": [],
"is_service": false,
"is_combo": false,
"barcodes": [],
"label": null,
"discount_info": null,
"featured_in_order": null
}
Asocia un Good con un Branch. Cuando un BranchGood es insertado, el API automáticamente asocia las GoodProperties del producto asociado y crea los registros de BranchProperty para manejar el stock y precios.
{info} Si no se especifica algún atributo, se usa el valor del Good. En caso de
min_price_e2se utiliza el atributoprice_e2del Good.{warning} Endpoint deprecado. Gestionar el catálogo desde el
branch_group(marca).
| Método | URI | Cabeceras |
|---|---|---|
| PUT | /companies/{companyId}/branches/{branchId}/goods/{goodId} |
Authorization |
{
"eta": "string|max:32",
"min_price_e2": "integer|min:0",
"provider_fee_e2": "integer",
"provider_fee_prc": "numeric|between:0.0000,1.0000",
"quantity": "integer",
"quantity_real": "numeric",
"list_order": "integer",
"featured_good_config": {
"is_enabled": "nullable|boolean",
"in_order": "nullable|integer|min:1",
"blocks": [
{
"day_sunday": "nullable|boolean",
"day_monday": "nullable|boolean",
"day_tuesday": "nullable|boolean",
"day_wednesday": "nullable|boolean",
"day_thursday": "nullable|boolean",
"day_friday": "nullable|boolean",
"day_saturday": "nullable|boolean",
"hour_beg": {
"nullable": true,
"string": true,
"regex": "/^([0-1][0-9]|2[0-3]):[0-5][0-9]$/"
},
"hour_end": {
"nullable": true,
"string": true,
"regex": "/^([0-1][0-9]|2[0-3]):[0-5][0-9]$/"
}
}
]
}
}
{info} Soporta: Paginación Filters Carga dinámica
Listar productos de una sucursal
Lista los BranchGood de la sucursal: productos con precio, stock y disponibilidad.
El header X-Currency: <ISO> convierte los montos.
| Método | URI | Cabeceras |
|---|---|---|
| GET | /companies/{companyId}/branches/{branchId}/branch-goods |
N/A |
a la Branch actual, esa Category no se mostrará.
{info} Soporta: Paginación Filters
| Método | URI | Cabeceras |
|---|---|---|
| GET | /companies/{companyId}/branches/{branchId}/branch-goods/categories |
N/A |
{info} Soporta: Paginación Filters Carga dinámica
Listar productos de una categoría en una sucursal
Lista los BranchGood de la sucursal que pertenecen a la Category indicada, con precio y stock.
| Método | URI | Cabeceras |
|---|---|---|
| GET | /companies/{companyId}/branches/{branchId}/categories/{categoryId}/branch-goods |
N/A |
{info} Soporta: Carga dinámica
Mostrar producto de sucursal
Devuelve el BranchGood por su id: producto con precio, stock y disponibilidad de
esa sucursal. El header X-Currency: <ISO> convierte los montos de custom_data.
| Método | URI | Cabeceras |
|---|---|---|
| GET | /companies/{companyId}/branch-goods/{branchGoodId} |
N/A |
good_id{info} Soporta: Carga dinámica
Devuelve el BranchGood de la sucursal para el Good indicado.
| Método | URI | Cabeceras |
|---|---|---|
| GET | /companies/{companyId}/branches/{branchId}/goods/{goodId} |
N/A |
Actualizar producto de sucursal
Actualiza el BranchGood: precio de venta (min_price_e2), stock (quantity_real),
ETA, orden en la lista, promoción, etc. Cambiar el tipo del Good subyacente tiene
las mismas restricciones que en el endpoint de productos.
| Método | URI | Cabeceras |
|---|---|---|
| PATCH | /companies/{companyId}/branch-goods/{branchGoodId} |
Authorization |
{
"eta": "string|max:32",
"min_price_e2": "integer|min:0",
"provider_fee_e2": "integer",
"provider_fee_prc": "numeric|between:0.0000,1.0000",
"quantity": "integer",
"quantity_real": "numeric",
"list_order": "integer",
"featured_good_config": {
"is_enabled": "nullable|boolean",
"in_order": "nullable|integer|min:1",
"blocks": [
{
"day_sunday": "nullable|boolean",
"day_monday": "nullable|boolean",
"day_tuesday": "nullable|boolean",
"day_wednesday": "nullable|boolean",
"day_thursday": "nullable|boolean",
"day_friday": "nullable|boolean",
"day_saturday": "nullable|boolean",
"hour_beg": {
"nullable": true,
"string": true,
"regex": "/^([0-1][0-9]|2[0-3]):[0-5][0-9]$/"
},
"hour_end": {
"nullable": true,
"string": true,
"regex": "/^([0-1][0-9]|2[0-3]):[0-5][0-9]$/"
}
}
]
}
}
good_id (deprecado){warning} Endpoint deprecado. Usar
PATCH branch-goods/{branchGoodId}.
Actualiza el BranchGood de la sucursal para el Good indicado.
| Método | URI | Cabeceras |
|---|---|---|
| PATCH | /companies/{companyId}/branches/{branchId}/goods/{goodId} |
Authorization |
{
"eta": "string|max:32",
"min_price_e2": "integer|min:0",
"provider_fee_e2": "integer",
"provider_fee_prc": "numeric|between:0.0000,1.0000",
"quantity": "integer",
"quantity_real": "numeric",
"list_order": "integer",
"featured_good_config": {
"is_enabled": "nullable|boolean",
"in_order": "nullable|integer|min:1",
"blocks": [
{
"day_sunday": "nullable|boolean",
"day_monday": "nullable|boolean",
"day_tuesday": "nullable|boolean",
"day_wednesday": "nullable|boolean",
"day_thursday": "nullable|boolean",
"day_friday": "nullable|boolean",
"day_saturday": "nullable|boolean",
"hour_beg": {
"nullable": true,
"string": true,
"regex": "/^([0-1][0-9]|2[0-3]):[0-5][0-9]$/"
},
"hour_end": {
"nullable": true,
"string": true,
"regex": "/^([0-1][0-9]|2[0-3]):[0-5][0-9]$/"
}
}
]
}
}
Desvincula un Good de un Branch. Cuando un BranchGood es eliminado, el API automáticamente elimina los GoodProperties del producto desvinculado y elimina los registros huérfanos de BranchProperty.
| Método | URI | Cabeceras |
|---|---|---|
| DELETE | /companies/{companyId}/branches/{branchId}/goods/{goodId} |
Authorization |
Ejecuta una acción sobre varios BranchGood a la vez (campo ids). El parámetro de
ruta action acepta: set-available, set-unavailable, update, delete. Cada
BranchGood se procesa como si se llamara al endpoint individual; la respuesta detalla el
resultado por ítem. Los errores de negocio son los del endpoint de la acción elegida.
| Método | URI | Cabeceras |
|---|---|---|
| POST | /companies/{companyId}/branch-goods/batch-action/{action} |
Authorization |
{
"ids": [
"integer|min:1"
],
"payload": ""
}
{info} Soporta: Paginación Filters Carga dinámica
Búsqueda global de BranchGood por texto (search) en toda la company, con precio y
stock por sucursal.
| Método | URI | Cabeceras |
|---|---|---|
| GET | /companies/{companyId}/branch-goods/search |
N/A |
{
"q": "required|string",
"paginate": "nullable|boolean",
"results_mode": "string|in:goods,branch",
"limit": "nullable|integer",
"latitude_e6": "nullable|integer|between:-90000000,90000000",
"longitude_e6": "nullable|integer|between:-180000000,180000000",
"client_id": "nullable|integer",
"category_id": "nullable|integer"
}
Marca el BranchGood como disponible para la venta (available = true). Requiere
stock y al menos una categoría asignada.
| Método | URI | Cabeceras |
|---|---|---|
| POST | /companies/{companyId}/branch-goods/{branchGoodId}/set-available |
Authorization |
| Código | HTTP | Cuándo ocurre |
|---|---|---|
EA211 |
400 | El producto ya está disponible. |
EA212 |
400 | El producto no tiene stock. |
EA213 |
400 | El producto no tiene ninguna categoría asignada. |
Marca el BranchGood como no disponible para la venta (available = false).
| Método | URI | Cabeceras |
|---|---|---|
| POST | /companies/{companyId}/branch-goods/{branchGoodId}/set-unavailable |
Authorization |
| Código | HTTP | Cuándo ocurre |
|---|---|---|
EA210 |
400 | El producto no está disponible. |
idDesvincula el BranchGood (por su id) de la sucursal: elimina sus
GoodProperty y los BranchProperty huérfanos. Si la sucursal queda inválida
para operar, se oculta automáticamente.
| Método | URI | Cabeceras |
|---|---|---|
| DELETE | /companies/{companyId}/branch-goods/{branchGoodId} |
Authorization |
{info} Soporta: Paginación Filters Carga dinámica
Devuelve los BranchGood destacados de la sucursal, según su featured_good_config.
| Método | URI | Cabeceras |
|---|---|---|
| GET | /companies/{companyId}/branches/{branchId}/branch-goods/featured |
N/A |
{info} Soporta: Paginación Filters Carga dinámica
Búsqueda por texto (search) entre los BranchGood de la sucursal.
| Método | URI | Cabeceras |
|---|---|---|
| GET | /companies/{companyId}/branches/{branchId}/branch-goods/search |
N/A |
{
"q": "required|string",
"paginate": "nullable|boolean",
"results_mode": "string|in:goods,branch",
"limit": "nullable|integer",
"latitude_e6": "nullable|integer|between:-90000000,90000000",
"longitude_e6": "nullable|integer|between:-180000000,180000000",
"client_id": "nullable|integer",
"category_id": "nullable|integer"
}
allLogs HasMany ApiLogbranch BelongsTo BranchbranchGoodProperties HasMany BranchGoodPropertybranchGroup BelongsTo BranchGroupcategories HasMany Categorygood BelongsTo GoodgoodCategories HasMany GoodCategorygoodProperties HasMany GoodPropertylogs HasMany ApiLogmaterials HasMany GoodMaterialpromo BelongsTo Couponproperties HasMany Propertysales HasMany OrderedGood