Produto (Loja)

Integração Básica do RUB — entidade obrigatória, de contexto Loja. Na API pública é representada pela tag Produtos por Loja e pelos schemas ProductStore (envio) e ProductStoreResponse (retorno), que transportam também as Embalagens Loja (preços).

O que é o Produto (Loja)

O Produto — chamado aqui de Produto (Loja) para distingui-lo do Produto Empresa — é o vínculo de um produto com uma loja e o conjunto de informações que variam por loja: se o item está ativo naquela unidade, qual o seu custo, qual a sua vida útil, se ele deriva de outro produto.

Se o Produto Empresa responde "o que é o produto", o Produto (Loja) responde "como ele se comporta nesta loja":

  • Ativo? — Se ATIVO = 0, o produto não faz parte do sortimento da loja: o RUB não gera tarefas de reposição nem auditoria para ele, embora ainda o reconheça se um código for lido.
  • Custo — Base para valorizar rupturas, perdas e ajustes de inventário em reais; para peso variável, é o custo por grama.
  • Vida útil (Shelf Life) — Tempo entre fabricação e vencimento; alimenta as rotinas de controle de validade e de produtos próximos ao vencimento.
  • Código de preço — Dígito verificador usado na etiqueta de preço da loja; permite que o RUB valide, ao ler a etiqueta, se ela corresponde ao preço vigente.
  • Produto pai — Para produtos derivados (porcionados, fracionados, kits), aponta para o produto de origem, permitindo que o RUB relacione o estoque do derivado com o do pai.

Sem o Produto (Loja), o Produto Empresa é apenas um cadastro: é o vínculo com a loja que "liga" o produto na operação. Um produto que existe na empresa mas não tem vínculo com a loja 30001 simplesmente não existe para a operação da loja 30001.

Sortimento por loja

graph TD
    PE["Produto Empresa 4482<br/>ARROZ TIPO 1 5KG"]
    PE --> L1["Loja 30001<br/>ativo = 1<br/>custo = 18,90<br/>vida útil = 365"]
    PE --> L2["Loja 30002<br/>ativo = 1<br/>custo = 19,10<br/>vida útil = 365"]
    PE --> L3["Loja 30003<br/>ativo = 0"]

O mesmo SKU pode ter custos diferentes (logística regional), estar ativo em algumas lojas e inativo em outras (formatos de loja distintos: hipermercado × loja de vizinhança).

Produtos derivados

Um produto derivado é aquele produzido na loja a partir de outro: a peça de queijo (pai) que é fatiada e vendida como "queijo fatiado" (derivado); o contrafilé inteiro (pai) que vira bife (derivado); o kit promocional composto por itens avulsos. O campo CODIGO_PAI registra essa relação, e as razões de ajuste de estoque entre pai e derivado são detalhadas na integração complementar de Produto Associado (associated_products na API).

Modelo de dados

CampoTipoObrigatórioDescrição
ID_LOJAINTEIROSimCódigo de identificação da Loja.
CODIGOTEXTO(32)SimCódigo de identificação do Produto (PLU, SKU) — o mesmo do Produto Empresa.
CUSTONUMERICO(14, 6)NãoCusto do Produto. Para produtos de peso variável, considerar o custo da grama.
CODIGO_PRECOTEXTO(20)NãoDígito verificador calculado que será usado nas etiquetas de preço.
CODIGO_PAITEXTO(32)NãoIdentificação do Produto Pai, em casos de Produtos derivados.
ATIVOINTEIRONãoIndica se o Produto está ativo na Loja (0-Não / 1-Sim).
VIDA_UTILINTEIRONãoVida útil do Produto, tempo entre fabricação e vencimento (Shelf Life), em dias.

Chave e identidade

A chave é composta: ID_LOJA + CODIGO. Um mesmo CODIGO aparece uma vez para cada loja em que o produto existe. Reenviar o par atualiza os demais campos.

Relacionamentos

graph LR
    PROD["Produto (Loja)<br/>ID_LOJA, CODIGO<br/>CUSTO, ATIVO, VIDA_UTIL, CODIGO_PRECO"]
    PROD -->|CODIGO| PE["Produto Empresa"]
    PROD -->|ID_LOJA| LOJA["Loja"]
    PROD -.->|CODIGO_PAI| PROD
    EMBL["Embalagem Loja<br/>(preços)"] -->|ID_LOJA + PRODUTO| PROD
    EST["Estoque"] -->|ID_LOJA + PRODUTO| PROD
    MOV["Movimento"] -->|ID_LOJA + PRODUTO| PROD
  • Um Produto (Loja) pertence a um Produto Empresa e a uma Loja.
  • Possui uma ou mais Embalagens Loja (preços), um Estoque (eventualmente detalhado por Local) e zero ou mais Movimentos.
  • Pode apontar para um Produto pai na mesma loja.

Equivalência na API

ConceitoCampo na API (ProductStore)TipoObrigatórioObservação
ID_LOJAstoreintegerSimCódigo de integração da loja (não o rubCode).
CODIGOproductstringSim
ATIVOactivebooleanNão
CUSTOcostnumberNão
CODIGO_PRECOprice_codestringNão
CODIGO_PAIparent_codestring—Presente no retorno (ProductStoreResponse).
VIDA_UTILshelf_lifeinteger—Presente no retorno (ProductStoreResponse).
Embalagem Lojaprices[]StorePrice[]Nãoquantity, unit_price, package_price, active, store_codes[].
—associated_products[]AssociatedProduct[]NãoIntegração complementar (kits, porcionados, derivados).
—propertiesobjectNãoPropriedades extras (chave/valor). Consulte Propriedades Extras.

Exemplos de uso

Cenário 1 — Ativando um produto em uma loja

O produto 4482 passa a ser vendido na loja 30001. O ERP cria o vínculo com custo e preços:

POST /empresa/api/rest/product-store/v1
{
  "store": 30001,
  "product": "4482",
  "active": true,
  "cost": 18.90,
  "price_code": "7",
  "prices": [
    { "quantity": 1, "unit_price": 24.99, "package_price": 24.99, "active": true },
    { "quantity": 6, "unit_price": 23.99, "package_price": 143.94, "active": true }
  ]
}

O retorno (ProductStoreResponse) confirma o vínculo e traz também parent_code e shelf_life, quando existentes.

Cenário 2 — Alterando apenas o custo

A loja 30001 recebeu uma nova remessa com custo diferente. Usando a rota com identificadores no path, apenas os campos enviados são aplicados:

POST /empresa/api/rest/product-store/v1/30001/4482
{ "cost": 19.35 }

Preços, active e demais campos permanecem inalterados.

Cenário 3 — Retirando um produto do sortimento

A loja 30003 deixa de vender o produto. Em vez de apagar o vínculo, ele é inativado — o histórico de vendas, auditorias e estoque permanece disponível:

POST /empresa/api/rest/product-store/v1/30003/4482
{ "active": false }

A partir daí o RUB deixa de gerar tarefas de reposição e auditoria para o 4482 na loja 30003.

Cenário 4 — Produto de peso variável

Para a mussarela fatiada (produto 7301, variable: true), o custo é informado por grama e o preço, por quilo, é expresso na embalagem de 1000 g:

POST /empresa/api/rest/product-store/v1
{
  "store": 30001,
  "product": "7301",
  "active": true,
  "cost": 0.0289,
  "prices": [
    { "quantity": 1000, "unit_price": 0.0499, "package_price": 49.90, "active": true }
  ]
}

Cenário 5 — Carga inicial do sortimento (CSV massivo)

Na carga inicial, o vínculo de todos os produtos com todas as lojas é enviado em CSV (Content-Type: text/csv), uma linha por par loja × produto. Os preços vão em arquivo separado (veja Embalagem Loja):

POST /empresa/api/rest/product-store/v1
Content-Type: text/csv

"store";"product";"active";"cost";"price_code"
"30001";"4482";"true";"18.90";"7"
"30002";"4482";"true";"19.10";"7"
"30003";"4482";"false";"";""
"30001";"7301";"true";"0.0289";""

Cenário 6 — Consulta do sortimento de uma loja

GET /empresa/api/rest/product-store/v1?store=30001&page=1&pageSize=100  → vínculos da loja 30001
GET /empresa/api/rest/product-store/v1/30001/4482                       → um vínculo específico (404 se não existir)

Cenário 7 — Uso operacional

Com os vínculos ativos e custos informados, a loja passa a ter, por exemplo:

  • Ruptura valorizada: o RUB multiplica a quantidade estimada em falta pelo cost para apontar quanto a loja está deixando de vender por categoria.
  • Auditoria de validade: com shelf_life, o RUB estima o vencimento de lotes recebidos e prioriza a checagem dos produtos com vida útil curta.
  • Etiqueta de preço: ao ler a etiqueta, o dígito price_code é comparado com o esperado; divergência gera tarefa de troca de etiqueta.

Boas práticas

  • Crie o vínculo para todas as lojas em que o produto é comercializado, inclusive com active: false para as que não o vendem — isso torna o sortimento explícito.
  • Use o código de integração da loja (store), o mesmo enviado no cadastro de Lojas (/empresa/api/rest/store), e não o código interno do RUB.
  • Envie cost sempre que ele mudar; é a base da valorização financeira dos indicadores.
  • Para peso variável, confira a unidade do custo (grama) antes de integrar; um custo por quilo informado como grama infla os valores em 1000×.
  • Prefira inativar (active: false) a excluir o vínculo.

Referência na API

O contrato técnico completo dos endpoints de Produtos por Loja (parâmetros de rota, schemas JSON 1:1, formatos de importação massiva CSV e exemplos de requisição/resposta) encontra-se documentado no Swagger oficial: