15 KiB
Story 3.2: Ler Acréscimo do PostgreSQL no Sync de Consulta
Status: done
Story
Como representante de vendas, quero que pedidos históricos sincronizados do ERP cheguem ao app com o acréscimo correto gravado, para que a consulta exiba os valores reais praticados mesmo em pedidos que não foram criados neste dispositivo.
Acceptance Criteria
-
Dado que
Global.sistema == SISTEMA_GERENTEegerente.pedidospossuiacrep = 3.0eacrev = 105.00para um pedido QuandoPedidoPGSQL.selectAllPedConsultaler o registro Então o VOPedidoretornado temvlAcrescimo = 105.00 -
Dado que
Global.sistema == SISTEMA_SIGesig.pedidospossuitx_acrescimo = 3.0etotal = 3500.00para um pedido QuandoPedidoPGSQL.selectAllPedConsultaler o registro Então o VOPedidoretornado temvlAcrescimocalculado como3500.00 × 3.0 / 100 = 105.00 -
Dado que a coluna de acréscimo não existe no PostgreSQL ou está
NULLQuandoselectAllPedConsultafor executado Então o VO recebevlAcrescimo = 0.0, sem erro, sem crash -
Dado que
PedidoConsultaDB.saveAllrecebe os VOs retornados Quando gravar empedido_consultaEntãopedido_consulta.vl_acrescimoreflete o valor lido do PG
Escopo desta história
SIM:
- Adicionar
COALESCE(a.acrev, 0.0) as acrevao SELECT Gerente emselectAllPedConsulta() - Reutilizar
hasColunaAcrescimoSig()(já existe na classe) antes do SELECT SIG - Adicionar
COALESCE(a.tx_acrescimo, 0.0) as tx_acrescimocondicionalmente ao SELECT SIG quando coluna existir - Ler e setar
ped.setVlAcrescimo(...)no loop de ResultSet (acrevdireto para Gerente;total × tx_acrescimo / 100para SIG)
NÃO cobre:
PedidoConsultaDB— já grava e lêvl_acrescimo(Stories 2.3/2.4 já fizeram isso — não modificar)- MD5 de
pedido_consultaincluindovl_acrescimo— Story 3.3 - DDL server-side — responsabilidade do DBA; app tolera ausência
Pré-condições verificadas
PedidoConsultaDB.insert()— já incluivl_acrescimona lista de colunas e lêped.getVlAcrescimo()na linha 147. Nenhuma mudança necessária.PedidoConsultaDB.updateErp()— já atualizavl_acrescimo = ped.getVlAcrescimo()na linha 183. Nenhuma mudança necessária.PedidoConsultaDB.selectFull()— já lêa.vl_acrescimo(índice 66) e chamapedido.setVlAcrescimo(c.getDouble(66))na linha 296. Nenhuma mudança necessária.hasColunaAcrescimoSig()— método privado já existe emPedidoPGSQL.java(linhas 1186–1203); pode ser reutilizado emselectAllPedConsulta()diretamente.- Gerente —
acrep/acrevjá existem: Confirmado em Story 3.1 — colunas estavam na lista do INSERT desde antes do Epic 3; safe para adicionar ao SELECT sem tolerância. - SIG —
tx_acrescimopode não existir: DDL pode estar pendente; mesma tolerância aplicada em Story 3.1. Pedido.setVlAcrescimo(double)— getter/setter adicionados em Story 2.3; disponíveis no VO.new Pedido()—vlAcrescimodefault é0.0(primitivo double); AC 3 satisfeito automaticamente quando não setado.- ResultSet em
selectAllPedConsulta()usa acesso por nome (rs.getString("num_ped_sar"), etc.); adicionar colunas nomeadas ao SELECT é seguro e não desloca índices. dbVersaopermanece 43 — sem alteração de schema SQLite.
Tasks / Subtasks
-
Task 1: Declarar variável de controle SIG antes do if-else de queries (AC: 2, 3)
- 1.1 — Em
PedidoPGSQL.java, dentro deselectAllPedConsulta(), logo antes do blocoif (Global.sistema.equals(Global.SISTEMA_GERENTE)){(linha 619), adicionar:boolean temAcrescSigConsulta = false;Variável acessível em ambos os branches e no loop de ResultSet.
falsecomo default garante AC 3 para SIG sem DDL.
- 1.1 — Em
-
Task 2: Adicionar
acrevao SELECT Gerente (AC: 1, 3)- 2.1 — No branch Gerente (linhas 624–643), alterar a linha que termina com
a.total:// ANTES: sql.append(" a.ped_flex, a.descv, a.descp, a.total"); //13-16 // DEPOIS: sql.append(" a.ped_flex, a.descv, a.descp, a.total, COALESCE(a.acrev, 0.0) as acrev"); //13-17COALESCEgarante que registros históricos comacrev = NULLretornem0.0— AC 3.acrepnão é necessário para vlAcrescimo; apenasacrev(o valor calculado) é lido.
- 2.1 — No branch Gerente (linhas 624–643), alterar a linha que termina com
-
Task 3: Checar coluna e adicionar
tx_acrescimoao SELECT SIG condicionalmente (AC: 2, 3)- 3.1 — No branch SIG (linha ~645, início do
else), ANTES de construir osql, adicionar:temAcrescSigConsulta = hasColunaAcrescimoSig();Reutiliza o método privado existente (linhas 1186–1203). Executa UMA VEZ por chamada a
selectAllPedConsulta, antes do loop de ResultSet. - 3.2 — No SELECT SIG, após
a.total(linha ~658), adicionar condicionalmente:// ANTES: sql.append(" a.ped_flex, a.descv, a.descp, a.total"); //13-16 // DEPOIS: sql.append(" a.ped_flex, a.descv, a.descp, a.total"); //13-16 if (temAcrescSigConsulta) { sql.append(", COALESCE(a.tx_acrescimo, 0.0) as tx_acrescimo"); //17 }
- 3.1 — No branch SIG (linha ~645, início do
-
Task 4: Setar
vlAcrescimono VO no loop de ResultSet (AC: 1, 2, 3, 4)- 4.1 — Após
ped.setTotal(rs.getDouble("total"))(linha 730), adicionar:if (Global.sistema.equals(Global.SISTEMA_GERENTE)) { ped.setVlAcrescimo(rs.getDouble("acrev")); } else if (temAcrescSigConsulta) { ped.setVlAcrescimo(rs.getDouble("total") * rs.getDouble("tx_acrescimo") / 100.0); } // else: vlAcrescimo = 0.0 (default de new Pedido() — AC 3 para SIG sem DDL)Para Gerente:
acrevé o valor congelado no ERP (taxa aplicada na época do pedido). Para SIG: fórmula especificada no AC 2 —total × tx_acrescimo / 100. Se SIG sem DDL:temAcrescSigConsulta = false→ nenhum setter chamado →vlAcrescimo = 0.0.
- 4.1 — Após
Dev Notes
Mapa de campos por sistema
| Sistema | Coluna PG para vlAcrescimo | Existência garantida? | Fórmula no app |
|---|---|---|---|
Gerente (gerente.pedidos) |
acrev |
Sim — col já existia antes do Epic 3 | vlAcrescimo = rs.getDouble("acrev") |
SIG (sig.pedidos) |
tx_acrescimo |
Não — DDL pode estar pendente | vlAcrescimo = total × tx_acrescimo / 100.0 |
Por que Gerente usa acrev (não acrep)
acrep é a taxa percentual (ex: 2.5). acrev é o valor calculado (ex: R$ 87,50). Pedido.vlAcrescimo armazena o valor monetário, não a taxa. Portanto apenas acrev é necessário no SELECT Gerente.
Por que SIG calcula o valor em vez de armazená-lo
SIG armazena só a taxa (tx_acrescimo). O valor é derivado server-side usando a fórmula total × tx_acrescimo / 100. Esta é a mesma assimetria documentada em Story 3.1 e nos pré-requisitos do Epic 3 — intencional, não é bug.
Reuso de hasColunaAcrescimoSig()
O método privado já existe em PedidoPGSQL.java (linhas 1186–1203). Foi criado em Story 3.1 para o INSERT; aqui é reutilizado no SELECT. Não duplicar lógica — chamar o mesmo método.
PedidoConsultaDB — NENHUMA MUDANÇA NECESSÁRIA
PedidoConsultaDB.insert() (linha 147): sql.append(ped.getVlAcrescimo() + ");") — já grava.
PedidoConsultaDB.updateErp() (linha 183): sql.append(" vl_acrescimo = " + ped.getVlAcrescimo()) — já atualiza.
PedidoConsultaDB.selectFull() (linha 296): pedido.setVlAcrescimo(c.getDouble(66)) — já lê.
A Story 2.4 já preparou tudo. Story 3.2 apenas popula o campo vlAcrescimo no VO antes de saveAll ser chamado.
Fluxo completo (para referência)
ComunicaActivity.onPostExecute()
→ PedidoPGSQL.selectAllPedConsulta() ← MUDANÇA AQUI: ler acrev/tx_acrescimo
→ rs → Pedido VO com vlAcrescimo preenchido
→ PedidoConsultaDB.saveAll() ← SEM MUDANÇA: já grava vl_acrescimo
→ insert() ou updateErp()
→ pedido_consulta.vl_acrescimo = valor lido do PG
→ BrowsePedidoConsulta / selectFull() ← SEM MUDANÇA: já lê vl_acrescimo
Arquivo a modificar
| Arquivo | Caminho | O que muda |
|---|---|---|
PedidoPGSQL.java |
src/br/com/jcsinformatica/sarandroid/postgres/ |
selectAllPedConsulta(): SELECT Gerente + temAcrescSigConsulta + SELECT SIG condicional + setter no loop |
NÃO modificar:
PedidoConsultaDB.java— já completo (Stories 2.3/2.4)Pedido.java— VO completo (Story 2.3)DatabaseHelper.java— schema SQLite não muda
Regras críticas do projeto (aplicáveis)
- Sem Kotlin — somente Java puro
- Sem Gradle — projeto Eclipse ADT
- Sem JARs novos — nenhuma dependência adicional
- Sem testes automatizados — validação manual via dispositivo/emulador
ConnectionManager.closeAll(st, rs)— já chamado ao final deselectAllPedConsulta()(linha 751); não alterar- ResultSet por nome — padrão em
selectAllPedConsulta(); não usar índices posicionais
Inteligência de histórias anteriores
- Story 3.1:
hasColunaAcrescimoSig()criada aqui — reutilizar sem duplicar.insert()Gerente usaacrep/acrev(já existem);insertSig()usatx_acrescimocom tolerância. Mesmos princípios aqui, mas para leitura. - Story 2.4:
BrowsePedidoConsultaeselectFull()já usamvlAcrescimodo VO. Esta story fecha o ciclo: antes só os pedidos criados localmente tinhamvlAcrescimo; agora também os históricos do PG. - Story 2.3:
Pedido.vlAcrescimo(double, default0.0) ePedidoConsultaDBtotalmente preparados. - Story 1.2: Padrão de tolerância a coluna ausente —
try-catchemFormaPagamentoPGSQL. Aqui usamos a abordagem mais robusta dehasColunaAcrescimoSig()(já criada em Story 3.1), que condiciona a construção do SQL em vez de tentar e falhar.
Verificação manual após implementação
-
Gerente — pedido com acréscimo gravado no PG:
- Garantir que um pedido em
gerente.pedidostenhaacrev > 0(enviar via Story 3.1 ou inserir diretamente) - Executar sync (ComunicaActivity); verificar em
pedido_consultavia logcat queINSERT PEDIDO CONSULTAcontémvl_acrescimo = <valor>correspondente aoacrevdo PG
- Garantir que um pedido em
-
Gerente — pedido histórico com
acrev = NULLou 0:- Verificar que
vlAcrescimo = 0.0no VO — sem crash
- Verificar que
-
SIG com DDL aplicado:
- Pedido em
sig.pedidoscomtx_acrescimo = 3.0,total = 3500.00 - Sync →
vl_acrescimo = 105.00empedido_consulta
- Pedido em
-
SIG sem DDL (coluna ausente):
- Com
tx_acrescimoausente emsig.pedidos - Sync deve concluir sem exceção;
vl_acrescimo = 0.0nos pedidos sincronizados
- Com
-
Log para debug:
Log.d("INSERT PEDIDO CONSULTA", sql.toString())— verificarvl_acrescimono SQL de insertLog.d("SQL PEDIDO CONSULTA = ", sql.toString())— verificar seacrevoutx_acrescimoestá no SELECT
Git intelligence (commits recentes)
f2cf45dStory 2.4:pedido_consulta.vl_acrescimo+ guardstatus >= STATUS_ENVIADOem consulta3ff26a7Story 2.3:Pedido.vlAcrescimo+PedidoDB+PedidoConsultaDBpreparados- Story 3.1 (não commitada):
PedidoPGSQL.insert/insertSig/save/hasColunaAcrescimoSig— padrões a seguir
References
- Epics:
_bmad-output/planning-artifacts/epics.md#story-32-ler-acrescimo-do-postgresql-no-sync-de-consulta - FR15: Leitura inbound do acréscimo do PG na sync de consulta
- FR16: Sync tolera ausência das colunas de acréscimo no PostgreSQL
PedidoPGSQL.java:603–752— métodoselectAllPedConsulta()completoPedidoPGSQL.java:1186–1203—hasColunaAcrescimoSig()a reutilizarPedidoConsultaDB.java:98–151—insert()(linha 147:vl_acrescimojá gravado)PedidoConsultaDB.java:153–196—updateErp()(linha 183:vl_acrescimojá atualizado)PedidoConsultaDB.java:198–305—selectFull()(linha 296:vl_acrescimojá lido)- Memory:
project_pg_sync_acrescimo_schema.md— assimetria Gerente vs SIG
Dev Agent Record
Agent Model Used
claude-sonnet-4-6 (create-story workflow)
Debug Log References
N/A — projeto sem infraestrutura de testes automatizados; validação manual via dispositivo/emulador conforme roteiro em "Verificação manual após implementação".
Completion Notes List
- Story 3.2 implementada em 2026-04-16.
- Task 1:
boolean temAcrescSigConsulta = falsedeclarada antes do if-else Gerente/SIG emselectAllPedConsulta()(linha 619). Acessível em ambos os branches e no loop de ResultSet. - Task 2 — Gerente SELECT:
COALESCE(a.acrev, 0.0) as acrevadicionado ao SELECT (linha 630).COALESCEprotege contra registros históricos comacrev = NULL.acrepnão incluído — apenas o valor calculado (acrev) é necessário paravlAcrescimo. - Task 3 — SIG SELECT:
temAcrescSigConsulta = hasColunaAcrescimoSig()chamado UMA VEZ antes de construir o SQL (linha 653). SELECT SIG inclui condicionalmenteCOALESCE(a.tx_acrescimo, 0.0) as tx_acrescimoquando coluna existe (linhas 661–663). Reutiliza o método privado criado em Story 3.1 — sem duplicação de lógica. - Task 4 — vlAcrescimo no loop: Após
ped.setTotal(...)(linhas 736–740): Gerente →setVlAcrescimo(rs.getDouble("acrev")); SIG com DDL →setVlAcrescimo(total × tx_acrescimo / 100.0); SIG sem DDL → sem setter,vlAcrescimo = 0.0(default primitivo). AC 1, 2, 3 e 4 satisfeitos. PedidoConsultaDBnão modificado —insert(),updateErp()eselectFull()já manipulamvl_acrescimodesde Stories 2.3/2.4.dbVersaopermanece 43 — sem alteração de schema SQLite.- Sem testes automatizados: projeto não possui infraestrutura (conforme CLAUDE.md). Validação manual necessária — roteiro em "Verificação manual após implementação".
- Nenhum import adicionado — todas as classes já importadas.
File List
src/br/com/jcsinformatica/sarandroid/postgres/PedidoPGSQL.java
Review Findings
- [Review][Defer]
hasColunaAcrescimoSig()chamado duas vezes por sessão de sync — uma vez emsave()(Story 3.1) e uma vez emselectAllPedConsulta()(Story 3.2). Durante uma janela de DDL migration, os dois resultados podem divergir, fazendo insert comtx_acrescimomas read sem (ou vice-versa). Em produção, DDL deve ocorrer fora da janela de sync; risco é teórico. — deferred, pré-existente ao escopo de 3.2
Change Log
- 2026-04-16: Story 3.2 criada pelo create-story workflow.
- 2026-04-16: Story 3.2 implementada.
PedidoPGSQL.selectAllPedConsulta(): SELECT Gerente agora incluiCOALESCE(a.acrev, 0.0) as acrev; SELECT SIG inclui condicionalmenteCOALESCE(a.tx_acrescimo, 0.0) as tx_acrescimo(viahasColunaAcrescimoSig()reutilizado de Story 3.1); loop de ResultSet setaPedido.vlAcrescimocom o valor lido do PG (acrevdireto para Gerente;total × tx_acrescimo / 100para SIG). Tolerância completa à ausência de DDL no SIG.