Stock Level Integration

Integração de Stock Level no CSuite Pricing

📋 Visão Geral

Foi implementada uma solução completa para calcular e armazenar métricas de estoque (stock_level) na tabela product_classification, permitindo que o sistema determine automaticamente se um produto tem estoque "normal" ou "high" baseado em análise de vendas e estoque.

🎯 Objetivo

Em vez de calcular stock_level dinamicamente a cada requisição, o sistema agora:
1. Calcula métricas de estoque durante a sincronização mensal
2. Armazena na tabela product_classification para acesso rápido
3. Atualiza a view vw_pricing_catalog_active para incluir essas métricas
4. Busca automaticamente quando não fornecido no payload

📊 Métricas Calculadas

1. stock_level (ENUM: 'low' | 'normal' | 'high')

2. days_supply (DECIMAL)

3. turn_rate_12m (DECIMAL)

4. stock_qty (INT)

🔧 Implementação

1. Alteração da Tabela product_classification

Script: csuite-pricing/sql/add_stock_metrics_to_product_classification.sql

ALTER TABLE csuite_pricing.product_classification
ADD COLUMN stock_level ENUM('low', 'normal', 'high') NULL,
ADD COLUMN days_supply DECIMAL(10,2) NULL,
ADD COLUMN turn_rate_12m DECIMAL(10,4) NULL,
ADD COLUMN stock_qty INT NULL;

2. Atualização da Procedure sp_sync_product_classification_from_inventory

Arquivo: csuite-pricing/sql/sp_sync_product_classification_from_inventory.sql

A procedure agora:
- Calcula days_supply e turn_rate_12m durante a sincronização
- Determina stock_level baseado em days_supply > 90
- Armazena stock_qty (estoque atual)
- Atualiza todos os produtos (A, B, C, D, E)

3. Atualização da View vw_pricing_catalog_active

Script: csuite-pricing/sql/update_vw_pricing_catalog_active_with_stock_level.sql

A view agora inclui:
- stock_level
- days_supply
- turn_rate_12m
- stock_qty

4. Atualização do Repository

Arquivo: agents/pricing/repository.py

A função get_stock_level() agora:
- Busca primeiro da tabela product_classification (já calculado)
- Faz fallback para core.core_inventory se não houver classificação
- Retorna "high" ou "normal" automaticamente

📈 Como Usar

No Payload (Opcional)

Você pode ainda enviar stock_level no payload para sobrescrever:

{
  "org_id": 1,
  "brand_id": 1,
  "customer_id": 707560,
  "sku_id": 1678973,
  "sku_qty": 10,
  "order_value": 31000,
  "payment_term": "standard",
  "stock_level": "high"  // Opcional - sobrescreve cálculo automático
}

Busca Automática

Se não enviar stock_level, o sistema busca automaticamente:

  1. Prioridade 1: Tabela product_classification (já calculado pela procedure)
  2. Prioridade 2: Tabela core.core_inventory (fallback simples)
  3. Prioridade 3: Default "normal"

🔄 Fluxo de Sincronização

  1. Mensalmente: Executar sp_sync_product_classification_from_inventory(1)
  2. A procedure calcula:
  3. Vendas dos últimos 12 meses
  4. Estoque atual
  5. days_supply = estoque / vendas_diárias_médias
  6. turn_rate_12m = vendas_12m / estoque
  7. stock_level = "high" se days_supply > 90, senão "normal"
  8. Armazena na tabela product_classification
  9. View atualizada automaticamente reflete os novos valores

📊 Exemplo de Dados

SELECT 
    sku_id,
    machine_curve,
    stock_level,
    days_supply,
    turn_rate_12m,
    stock_qty
FROM csuite_pricing.product_classification
WHERE is_active = 1
LIMIT 10;

Resultado esperado:

sku_id    | machine_curve | stock_level | days_supply | turn_rate_12m | stock_qty
----------|---------------|-------------|-------------|---------------|----------
1678973   | A             | high        | 120.5       | 3.04          | 417
123456    | B             | normal      | 45.2        | 8.07          | 23
789012    | C             | normal      | 30.1        | 12.14         | 5

🎯 Benefícios

  1. Performance: Cálculo feito uma vez por mês, não a cada requisição
  2. Precisão: Baseado em análise de 12 meses de vendas
  3. Consistência: Todos os produtos usam a mesma lógica
  4. Rastreabilidade: Métricas armazenadas para auditoria
  5. Flexibilidade: Ainda permite sobrescrever via payload

🔍 Monitoramento

Para verificar a distribuição de stock_level:

SELECT 
    stock_level,
    COUNT(*) as total,
    AVG(days_supply) as avg_days_supply,
    AVG(turn_rate_12m) as avg_turn_rate
FROM csuite_pricing.product_classification
WHERE is_active = 1
GROUP BY stock_level;

📝 Notas Importantes

🔊 Text-to-Speech

1.0x
1.0
Pronto para reproduzir