La respuesta corta
Un producto no lleva precio. El precio vive en un registro de unión entre el producto y una lista de precios, que guarda el importe, su moneda y un ajuste de acceso que puede restringir la lista a determinados roles. Dos listas, dos filas, un producto, dos precios.
Dos cosas le sorprenderán. Crear una lista de precios no crea filas de precio para los productos que ya existen; solo ocurre a la inversa. Y la API nunca resuelve un precio a partir de una lista: una línea de producto creada sin un precio explícito queda en cero, incluso cuando el producto tiene precio en la lista por defecto.
El problema de negocio
El mismo producto no cuesta lo mismo para todo el mundo. Un distribuidor compra a un precio y un cliente directo a otro. Un contrato marco fija un precio durante un año. Una región tiene su propia lista porque el mercado admite algo distinto. Un nivel de partners recibe una estructura de descuentos que el equipo de ventas directas no debería poder ver, y mucho menos incluir en un presupuesto.
Lo que eso significa en la práctica:
- una entrada de catálogo por producto, no cuatro casi duplicados con precios distintos, que es como esto sale mal;
- varios precios por producto, cada uno perteneciente a una lista con nombre;
- que se aplique el precio correcto cuando un comercial prepara un presupuesto, sin que tenga que buscarlo;
- algunas listas visibles solo para algunas personas;
- y un registro, a posteriori, de lo que se presupuestó y sobre qué base.
Por qué falla el enfoque obvio
Duplicar el producto por cada precio
"Widget (EMEA)", "Widget (Partner)", "Widget (Contract A)". Funciona el primer día y se deteriora de inmediato: cuatro registros que mantener sincronizados cada vez que cambia una especificación, cuatro SKU donde el negocio tiene uno, e informes que no pueden responder a «¿cuánto Widget hemos vendido?» sin una tabla de correspondencias que alguien mantiene a mano.
Poner el precio en el producto como campo personalizado
Un campo personalizado por nivel (precio de lista, precio para partners, precio de contrato) pone toda la matriz de precios en un mismo formulario, visible para cualquiera que pueda ver el producto, y exige un cambio de esquema cada vez que se añade un nivel. Además, se salta por completo la mecánica de las líneas de producto, así que nada traslada el precio a un presupuesto por usted.
Suponer que el precio del producto es una propiedad del producto
No lo es, y este es el hecho estructural que conviene interiorizar. Al leer el
esquema de la entidad Product, price aparece en su lista de campos clave,
pero la entidad no tiene ningún atributo de precio. Cree un producto y el registro vuelve
con un nombre, un SKU, un símbolo de unidad, un tipo y ningún precio en ninguna parte.
El precio es un registro aparte: una unión entre el producto y una lista de precios. Todas las sorpresas del §6 se derivan de ese único hecho.
Modelo de datos
Tres entidades, una de las cuales la gente no sabe que existe.
| Entidad | Contiene |
|---|---|
| Product | La entrada de catálogo: nombre, SKU, unidad, tipo, categoría. Sin precio. |
| Lista de precios | Una lista con nombre: "List Price", "EMEA", "Partner Tier". Lleva un tipo y un indicador active. |
| Precio de la lista de precios (la unión) | El propio precio, más su moneda, más un ajuste de acceso. Una fila por cada combinación de producto × lista. |
Así, «este producto cuesta 100 en la lista por defecto y 85 en la lista EMEA» son dos registros de unión, no dos campos ni dos productos.
Fuente. Centro de ayuda de Coevera, Price lists, para la vista del administrador sobre esta misma estructura.
La unión lleva el control de acceso. Cada fila de precio tiene un ajuste de acceso con una lista opcional de roles. Ese es el mecanismo para un nivel de partners o de uso solo interno: la restricción vive en el precio, no en el producto ni en el nombre de la lista. También es fácil pasarlo por alto por completo, porque nada en el nombre de una lista de precios sugiere que haya permisos asociados un nivel por debajo.
Con qué empieza un espacio nuevo
- Una lista de precios, llamada "List Price", marcada como protegida contra el borrado: no se puede eliminar.
- Esa lista llega con su indicador de activa establecido en false, lo que sorprende a quien supone que la lista por defecto está lista para usarse.
- Una moneda, la moneda base, protegida contra el borrado.
Líneas de producto
Un producto llega a una oportunidad como línea de producto: una unión entre la oportunidad y el producto, que lleva precio, cantidad y un importe calculado. Los precios por línea de producto existen tanto en Quote como en Opportunity; una oportunidad no se limita a una única cifra resumen.
La oportunidad lleva además su propia moneda de producto, distinta de la moneda de su valor principal, y un indicador de si ese valor principal se deriva de las líneas de producto o se introduce a mano.
Cómo configurarlo
- Cree primero las listas de preciosAntes del catálogo, si puede. El orden importa; consulte el §6.
- ActívelasIncluida la lista por defecto integrada, que no llega activa.
- Cree los productosCada uno recibe automáticamente una fila de precio por cada lista que ya existe, con cero por defecto.
- Fije los preciosUna fila por producto y por lista. Es la mayor parte del trabajo y la parte que merece la pena automatizar con un script.
- Configure el acceso en las filas que deban restringirseNo en la lista, sino en las filas de precio que contiene.
- Verifique por tasa de cumplimentaciónCuente las filas de precio por lista y compárelas con el número de productos. Una lista con menos filas que productos tiene huecos, y un hueco se lee como un precio de cero.
El paso 6 existe por la asimetría descrita en el §6, y es la comprobación que detecta la forma más habitual en que esta configuración queda incompleta sin que nadie lo note.
Aplicar el precio correcto
La API no resuelve un precio a partir de una lista de precios. Verificado: una
línea de producto creada sin precio volvió con price: 0, en un producto que
tenía un precio de 100 en la lista por defecto. Ni error, ni valor por defecto, ni
lookup.
La selección de la lista de precios es una función de la interfaz. Por la vía de la API, decidir qué lista se aplica y leer el precio en ella es tarea de quien llama.
Para una integración o una importación, eso significa que la lógica de resolución le corresponde escribirla y mantenerla correcta a usted: determine la lista aplicable a partir de lo que la rija (la región de la cuenta, su nivel, una referencia de contrato), lea la fila de precio de ese producto y esa lista, y escriba el valor en la línea de producto.
Y ninguno de los campos de la línea de producto leídos a través de la API registra de qué lista procede el precio. Ninguno hace referencia a la lista de precios. Así que, una vez que existe una línea, nada en los datos leídos indica si 85 era el precio EMEA, un descuento negociado o un error al teclear. Si la base de un precio es relevante para los informes o la auditoría, captúrela usted mismo en un campo personalizado de la línea de producto en el momento de fijar el precio; después ya es tarde.
Límites y compromisos
La creación de filas de precio funciona en una sola dirección
Crear un producto crea una fila de precio para cada lista existente. Crear una lista no crea nada para los productos existentes. Verificado en ambas direcciones.
Así que la secuencia natural (construir el catálogo y después añadir una lista regional cuando el negocio se expande) deja todos los productos existentes sin precio en la nueva lista, y una fila sin precio no se distingue de un precio de cero. Añada las listas antes que los productos cuando pueda; cuando no pueda, complete las filas deliberadamente y verifique el recuento.
Los valores calculados van por detrás de la respuesta de escritura
El amount de una línea de producto se calcula como precio × cantidad, pero el
valor en la respuesta a su propia escritura está desactualizado. Justo después de fijar el
precio 85 con una cantidad de 2, la escritura devolvió amount: 0; una lectura
nueva devolvió 170. El cálculo es correcto; el eco no.
Nunca dé por bueno un campo calculado a partir de una respuesta de escritura. El mismo patrón aparece en el Blueprint 002.
Los campos de descuento se pueden leer pero no escribir
La línea de producto expone un valor de descuento y un porcentaje de descuento, y la API rechaza los intentos de escribir cualquiera de los dos: los notifica como atributos que la entidad no tiene. Parecen ser derivados y no configurables, así que un descuento tiene que expresarse ajustando el precio y no registrando un descuento.
Sin verificar: el cálculo acumulado del valor de la oportunidad
Con el indicador de cálculo automático de la oportunidad establecido en true y una línea de producto cuyo importe se calcula correctamente, el valor principal de la oportunidad se queda en cero a lo largo de lecturas repetidas y de una modificación deliberada del registro. El resultado es el mismo con el indicador establecido en la creación, antes de que exista ninguna línea de producto: el importe de la línea se calcula como 1000 y el valor de la oportunidad sigue en cero.
No está establecido si se trata de un defecto: la explicación que queda, no probada aquí, es que el cálculo acumulado lo hace la interfaz y no el servidor. Lo que sí está establecido es que ninguno de los dos órdenes produce un valor en el servidor, así que una integración no puede confiar en que las líneas de producto determinen el valor de la oportunidad: fije el valor explícitamente si lo necesita, y confirme el comportamiento de la interfaz antes de suponer lo contrario.
Varias monedas
Cada fila de precio lleva su propia moneda, así que una lista puede estar expresada en una moneda distinta de otra. Lo que no es nativo es conservar el tipo de cambio que se aplicaba en un momento dado: un historial del tipo de cambio en la fecha de la transacción tiene que gestionarse mediante automatización si el negocio lo necesita. No lo hemos verificado en un espacio con varias monedas; se recoge a partir de un análisis previo y no de la observación.
Verificación
- Cuente las filas de precio por lista frente al número de productos. Es la comprobación más valiosa aquí, porque un producto sin precio en una lista tiene exactamente el mismo aspecto que un producto con precio cero.
- Lea los precios en los registros de unión, no en el producto: en el producto no hay nada que leer.
- Cree una línea de producto de principio a fin y confirme que el precio que queda es el que pretendía, sobre todo si es una integración la que hace la resolución.
- Vuelva a leer los importes calculados tras un tiempo de asentamiento. Nunca a partir de la respuesta de escritura.
- Pruebe las restricciones de acceso como usuario restringido, no como administrador; es la misma disciplina que la comprobación del bloqueo del registro en el Blueprint 004. Un administrador no puede ver la restricción en funcionamiento.
- Confirme que la lista por defecto está activa antes de preguntarse por qué nada tiene precio.
Qué indicaría una regresión: líneas de producto que quedan en cero, lo que significa que se omitió el paso de resolución; una lista de precios cuyo número de filas cae por debajo del número de productos tras añadir productos al catálogo; o precios presupuestados que ya no coinciden con ninguna lista, lo que significa que alguien ha estado editando las líneas de producto directamente.
Preguntas frecuentes
¿Cómo se asignan a un mismo producto precios distintos para distintas regiones o segmentos de clientes?
Con listas de precios. En Coevera CRM un producto no lleva ningún precio: el precio vive en un registro de unión entre el producto y una lista de precios, que guarda el importe y su moneda. Crear una segunda lista de precios y una segunda fila de precio para el mismo producto le da a ese producto dos precios, uno por lista. El registro de unión lleva además un ajuste de acceso, de modo que una lista puede restringirse a determinados roles; así es como un nivel de precios para partners o de uso solo interno se mantiene fuera del alcance del resto del equipo de ventas.
¿Por qué mi producto no muestra ningún precio después de crear una nueva lista de precios?
Porque la creación automática de filas de precio funciona en una sola dirección. Crear un producto genera una fila de precio para cada lista de precios que ya existe, con cero por defecto. Crear una lista de precios no genera filas para los productos que ya existen. Así que añadir una lista de precios regional o de contrato después de haber llenado el catálogo deja a todos los productos existentes sin precio en esa lista hasta que las filas se crean explícitamente, una por producto.
¿Aplica automáticamente la API de un CRM el precio de la lista de precios al añadir un producto a una oportunidad?
En Coevera, no. Crear una línea de producto a través de la API sin indicar un precio produce una línea con precio cero, incluso cuando el producto tiene un precio en la lista por defecto. La selección de la lista de precios es una función de la interfaz y no una regla de resolución en el servidor, así que cualquier integración que cree líneas de producto debe decidir qué lista se aplica e indicar el precio por sí misma. Además, ninguno de los campos de la línea de producto leídos a través de la API hace referencia a la lista de precios de la que procede, de modo que el origen de un precio no queda registrado en ellos.
¿Pueden tanto los presupuestos como las oportunidades llevar precios por línea de producto?
Sí. Los precios por línea de producto están disponibles tanto en los registros Quote como en los Opportunity de Coevera, así que una oportunidad no se limita a un único valor resumen. La oportunidad lleva su propia moneda de producto junto a la moneda de su valor principal, y un indicador que controla si ese valor principal se deriva de las líneas de producto en lugar de introducirse directamente.