17 KiB
stepsCompleted, inputDocuments
| stepsCompleted | inputDocuments | |||||
|---|---|---|---|---|---|---|
|
|
SARAndroid - Epic Breakdown
Overview
Este documento apresenta o epic e histórias para a funcionalidade de Acréscimo Financeiro no Pedido, decompondo os requisitos do PRD em histórias implementáveis para o agente desenvolvedor.
Requirements Inventory
Functional Requirements
FR1: O sistema sincroniza gestao.formapag.acresc (PostgreSQL) para formapag.tx_acrescimo (SQLite) durante a comunicação
FR2: O sistema trata tx_acrescimo = NULL como 0.0, sem erro ou interrupção
FR3: O sistema migra o schema SQLite de v40 para v41, adicionando tx_acrescimo REAL DEFAULT 0 na tabela formapag
FR4: A migração preserva todos os registros existentes de formas de pagamento
FR5: O representante visualiza o valor do acréscimo financeiro em campo dedicado no pedido, sempre visível
FR6: O sistema calcula o acréscimo ao selecionar forma de pagamento: acrescimo = subtotal × (tx_acrescimo / 100)
FR7: O sistema recalcula o acréscimo automaticamente ao trocar a forma de pagamento
FR8: O campo acréscimo exibe R$ 0,00 quando tx_acrescimo = 0 ou NULL
FR9: O total do pedido reflete subtotal + acrescimo
FR10: O sistema grava o valor calculado do acréscimo no registro do pedido ao fechar
FR11: O sistema grava o total com acréscimo no registro do pedido ao fechar
FR12: O representante visualiza o total com acréscimo em pedidos fechados que possuem o campo gravado
FR13: O sistema exibe pedidos sem campo de acréscimo sem alteração ou erro
FR14: Ao enviar pedido ao ERP (PedidoPGSQL.insert), o app grava a taxa (% acréscimo) e o valor calculado nos campos corretos conforme o sistema (Gerente: gerente.pedidos.acrep + acrev; SIG: sig.pedidos.tx_acrescimo)
FR15: Ao sincronizar pedidos de consulta do ERP (PedidoPGSQL.selectAllPedConsulta), o app lê o acréscimo dos campos corretos conforme o sistema e popula Pedido.vlAcrescimo (para SIG, calcula vlAcrescimo = total × tx_acrescimo / 100 server-side não grava valor)
FR16: Sync tolera ausência das colunas de acréscimo no PostgreSQL (DDL server-side pode preceder ou seguir o deploy do app sem interromper a comunicação)
FR17: MD5 de pedido_consulta inclui vl_acrescimo no cálculo de hash, garantindo que mudanças isoladas de acréscimo disparem re-sync
NonFunctional Requirements
NFR1: Recálculo do acréscimo ao trocar forma de pagamento: < 100ms (operação aritmética em memória, sem I/O)
NFR2: Leitura de tx_acrescimo do SQLite executada em thread background, sem impacto na responsividade da UI
NFR3: tx_acrescimo = NULL nunca causa NullPointerException — tratamento defensivo obrigatório em todo ponto de acesso
NFR4: Migração v40→v41 idempotente: múltiplas execuções de onUpgrade() não corrompem dados
NFR5: Sync tolera ausência da coluna acresc no PostgreSQL (schemas antigos) sem interromper a comunicação
NFR6: Após sync bem-sucedido, tx_acrescimo reflete acresc para 100% das formas de pagamento ativas
Additional Requirements
- Migração implementada em
DatabaseHelper.onUpgrade()com guardif (oldVersion < 41) dbVersaoincrementado para 41 emDatabaseHelper- Nenhuma dependência nova — sem JARs adicionais em
libs/ - Toda leitura SQLite em thread background (regra absoluta do projeto)
tx_acrescimo = NULLtratado como0.0em todo ponto de acesso- Valor do acréscimo gravado no pedido no fechamento (não recalculado na consulta)
- ⚠️ Verificar antes da implementação se tabela
pedidojá possui campo para acréscimo calculado
UX Design Requirements
Sem documento UX — feature brownfield sem nova tela. Requisitos de UI derivados do PRD:
- Campo acréscimo sempre visível na tela de edição do pedido (R$ 0,00 quando zero)
- Recálculo disparado automaticamente na seleção/troca da forma de pagamento
- Total do pedido atualizado na mesma interação
FR Coverage Map
| FR | Epic | Descrição |
|---|---|---|
| FR1 | Epic 1 | Sync gestao.formapag.acresc → formapag.tx_acrescimo |
| FR2 | Epic 1 | Tolerância a NULL no SQLite |
| FR3 | Epic 1 | Migração schema v40→v41 |
| FR4 | Epic 1 | Preservação de registros na migração |
| FR5 | Epic 2 | Campo acréscimo sempre visível no pedido |
| FR6 | Epic 2 | Cálculo ao selecionar forma de pagamento |
| FR7 | Epic 2 | Recálculo ao trocar forma de pagamento |
| FR8 | Epic 2 | Exibir R$ 0,00 quando sem acréscimo |
| FR9 | Epic 2 | Total = subtotal + acréscimo |
| FR10 | Epic 2 | Gravar acréscimo calculado no pedido |
| FR11 | Epic 2 | Gravar total com acréscimo no pedido |
| FR12 | Epic 2 | Consulta: exibir total com acréscimo se existir |
| FR13 | Epic 2 | Consulta: pedidos antigos sem alteração |
| FR14 | Epic 3 | Envio outbound do acréscimo ao PG (Gerente: acrep+acrev; SIG: tx_acrescimo) |
| FR15 | Epic 3 | Leitura inbound do acréscimo do PG na sync de consulta |
| FR16 | Epic 3 | Tolerância a ausência das colunas de acréscimo no PG |
| FR17 | Epic 3 | MD5 de pedido_consulta incluindo vl_acrescimo |
Epic List
Epic 1: Disponibilizar Taxa de Acréscimo no Dispositivo
O sistema armazena a taxa de acréscimo de cada forma de pagamento localmente, sincronizada do ERP, pronta para uso offline. FRs cobertos: FR1, FR2, FR3, FR4
Epic 2: Acréscimo Financeiro no Pedido
O representante visualiza e utiliza o acréscimo financeiro ao criar pedidos, com cálculo automático ao selecionar a forma de pagamento, total correto e histórico preservado na consulta. FRs cobertos: FR5, FR6, FR7, FR8, FR9, FR10, FR11, FR12, FR13
Epic 3: Sync Bidirecional do Acréscimo entre App e ERP
O acréscimo calculado localmente é enviado ao PostgreSQL ao fechar o pedido, e pedidos históricos sincronizados do ERP trazem o acréscimo de volta ao SQLite — tornando a feature end-to-end funcional em Gerente e SIG. FRs cobertos: FR14, FR15, FR16, FR17
Epic 1: Disponibilizar Taxa de Acréscimo no Dispositivo
O sistema armazena a taxa de acréscimo de cada forma de pagamento localmente no SQLite, sincronizada do ERP, pronta para uso offline.
Story 1.1: Migração do Schema SQLite para Suporte a Acréscimo
Como desenvolvedor do sistema,
quero migrar o schema SQLite de v40 para v41 adicionando tx_acrescimo na tabela formapag,
para que as taxas de acréscimo possam ser armazenadas localmente sem afetar dados existentes.
Acceptance Criteria:
Dado que o app está sendo atualizado em um dispositivo com schema SQLite v40
Quando DatabaseHelper.onUpgrade() for executado
Então a coluna tx_acrescimo REAL DEFAULT 0 é adicionada à tabela formapag
E todos os registros existentes de formas de pagamento são preservados com tx_acrescimo = 0
Dado que onUpgrade() é chamado com oldVersion >= 41
Quando o bloco de migração v41 for avaliado
Então a migração é ignorada (guard if (oldVersion < 41)) sem erro
Dado que dbVersao em DatabaseHelper
Quando a migração for aplicada
Então dbVersao = 41
Story 1.2: Sincronização da Taxa de Acréscimo do ERP
Como representante de vendas, quero que a taxa de acréscimo de cada forma de pagamento seja sincronizada do ERP para o app durante a comunicação, para que os cálculos de acréscimo usem sempre os valores atualizados do servidor.
Acceptance Criteria:
Dado que gestao.formapag no PostgreSQL possui a coluna acresc com valores preenchidos
Quando a ComunicaActivity executar o sync de formas de pagamento
Então o valor de acresc é gravado em formapag.tx_acrescimo no SQLite para cada forma de pagamento
Dado que gestao.formapag no PostgreSQL não possui a coluna acresc (schema antigo)
Quando o sync de formas de pagamento for executado
Então a comunicação continua sem erro e tx_acrescimo permanece com o valor anterior (ou 0)
Dado que o VO FormaPagamento é carregado após o sync
Quando FormaPagamentoDB preencher o objeto
Então o campo tx_acrescimo está acessível no VO, com valor 0.0 quando NULL no banco
Epic 2: Acréscimo Financeiro no Pedido
O representante visualiza e utiliza o acréscimo financeiro ao criar pedidos, com cálculo automático ao selecionar a forma de pagamento, total correto e histórico preservado na consulta.
Story 2.1: Exibir Campo de Acréscimo na Tela do Pedido
Como representante de vendas, quero ver um campo de acréscimo sempre visível na tela do pedido, para que eu saiba em todo momento se há acréscimo aplicado, mesmo que seja zero.
Acceptance Criteria:
Dado que estou na tela de edição do pedido (UpdatePedidoActivity)
Quando a tela for exibida
Então um campo "Acréscimo" é visível mostrando R$ 0,00 por padrão
Dado que nenhuma forma de pagamento foi selecionada ou a selecionada tem tx_acrescimo = 0
Quando o campo acréscimo for exibido
Então mostra "R$ 0,00" — nunca fica oculto ou em branco
Story 2.2: Calcular Acréscimo ao Selecionar Forma de Pagamento
Como representante de vendas, quero que o acréscimo seja calculado e exibido automaticamente ao selecionar a forma de pagamento, para que eu veja o valor real do pedido sem precisar calcular manualmente.
Acceptance Criteria:
Dado que estou editando um pedido com subtotal R$ 3.500,00
Quando selecionar "Boleto 30/60/90" com tx_acrescimo = 2.5
Então o campo "Acréscimo" exibe R$ 87,50 e o total exibe R$ 3.587,50
Dado que já selecionei "Boleto 30/60/90" (2,5%) e troco para "Dinheiro" (tx_acrescimo = 0)
Quando a forma de pagamento for alterada
Então o campo "Acréscimo" retorna a R$ 0,00 e o total retorna a R$ 3.500,00
Dado que a forma de pagamento selecionada tem tx_acrescimo = NULL
Quando o cálculo for executado
Então acréscimo = R$ 0,00, sem crash ou NullPointerException
Dado que o cálculo é disparado Quando a troca de forma de pagamento ocorrer Então o recálculo conclui em menos de 100ms (aritmética em memória)
Story 2.3: Persistir Acréscimo ao Fechar o Pedido
Como sistema, quero gravar o valor do acréscimo calculado e o total com acréscimo no registro do pedido ao fechar, para que o valor histórico seja preservado independente de alterações futuras na taxa.
⚠️ Pré-condição de implementação: Verificar se a tabela
pedidono SQLite já possui colunas para acréscimo e total-com-acréscimo. Se não existirem, esta história inclui a adição dessas colunas na migração (incrementardbVersaoconforme necessário).
Acceptance Criteria:
Dado que um pedido foi editado com acréscimo R$ 87,50 e total R$ 3.587,50 Quando o pedido for salvo/fechado Então o valor do acréscimo (87,50) está gravado no registro do pedido no SQLite
Dado que um pedido foi salvo com acréscimo Quando a taxa de acréscimo da forma de pagamento for alterada no ERP e sincronizada Então o valor gravado no pedido antigo permanece inalterado
Dado que um pedido é criado com forma de pagamento sem acréscimo Quando o pedido for salvo Então o acréscimo gravado é 0,00
Story 2.4: Exibir Acréscimo na Consulta de Pedidos
Como representante de vendas, quero ver o total correto (com acréscimo) na consulta de pedidos já fechados, para que o histórico reflita os valores reais praticados.
Acceptance Criteria:
Dado que consulto um pedido fechado que possui acréscimo gravado Quando a tela de consulta exibir o pedido Então o valor total exibido inclui o acréscimo registrado no pedido
Dado que consulto um pedido fechado criado antes desta funcionalidade (sem campo de acréscimo) Quando a tela de consulta exibir o pedido Então o pedido é exibido normalmente sem erro, sem tentativa de recalcular acréscimo
Epic 3: Sync Bidirecional do Acréscimo entre App e ERP
O acréscimo calculado localmente é enviado ao PostgreSQL ao fechar o pedido, e pedidos históricos sincronizados do ERP trazem o acréscimo de volta ao SQLite. Torna a feature end-to-end funcional em ambos os sistemas (Gerente e SIG), fechando as Jornadas 3 e 4 do PRD para pedidos que trafegam pelo ERP.
Pré-condições server-side (DDL no PostgreSQL)
Estas alterações no PostgreSQL podem ser executadas antes, durante ou depois do deploy do app — o código trata a ausência das colunas (FR16). Recomenda-se executar ANTES do deploy para que o primeiro sync já carregue dados completos.
Sistema Gerente:
ALTER TABLE gerente.pedidos ADD COLUMN acrep REAL DEFAULT 0; -- % de acréscimo
ALTER TABLE gerente.pedidos ADD COLUMN acrev REAL DEFAULT 0; -- valor calculado do acréscimo
Sistema SIG:
ALTER TABLE sig.pedidos ADD COLUMN tx_acrescimo REAL DEFAULT 0; -- % de acréscimo (valor é derivado server-side)
Assimetria Gerente vs SIG
- Gerente armazena taxa + valor → histórico congelado no ERP mesmo se a taxa em
formapagmudar depois - SIG armazena só a taxa → valor é sempre calculado server-side; histórico reflete a taxa vigente no pedido no momento do envio
Esta assimetria é uma característica dos schemas de destino e deve ser respeitada — não é uma inconsistência a corrigir.
Story 3.1: Enviar Acréscimo ao PostgreSQL ao Salvar Pedido
Como sistema, quero enviar a taxa e o valor do acréscimo ao PostgreSQL quando um pedido for sincronizado para o ERP, para que o valor praticado localmente seja registrado no sistema central e fique disponível para relatórios do escritório.
Acceptance Criteria:
Dado que Global.sistema == SISTEMA_GERENTE e um pedido com vl_acrescimo = 87.50 (calculado sobre taxa 2,5%) é enviado via PedidoPGSQL.insert
Quando o INSERT em gerente.pedidos for executado
Então a coluna acrep contém 2.5 (taxa da forma de pagamento) e acrev contém 87.50 (valor calculado)
Dado que Global.sistema == SISTEMA_SIG e o mesmo pedido é enviado
Quando o INSERT em sig.pedidos for executado
Então a coluna tx_acrescimo contém 2.5 (só a taxa; o valor é derivado server-side)
Dado que um pedido sem acréscimo (forma de pagamento com tx_acrescimo = 0) é enviado
Quando o INSERT for executado em qualquer dos dois sistemas
Então o campo correspondente recebe 0.0 sem erro
Dado que a coluna de acréscimo ainda não existe no PostgreSQL (schema antigo)
Quando o INSERT tentar gravar o campo
Então a comunicação falha de forma graciosa (registra no gestao.log e segue) OU o INSERT é construído condicionalmente sem o campo quando o DBA ainda não aplicou o DDL — decisão de design a resolver na implementação
Story 3.2: Ler Acréscimo do PostgreSQL no Sync de Consulta
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_GERENTE e gerente.pedidos possui acrep = 3.0 e acrev = 105.00 para um pedido
Quando PedidoPGSQL.selectAllPedConsulta ler o registro
Então o VO Pedido retornado tem vlAcrescimo = 105.00
Dado que Global.sistema == SISTEMA_SIG e sig.pedidos possui tx_acrescimo = 3.0 e total = 3500.00 para um pedido
Quando PedidoPGSQL.selectAllPedConsulta ler o registro
Então o VO Pedido retornado tem vlAcrescimo calculado como 3500.00 × 3.0 / 100 = 105.00
Dado que a coluna de acréscimo não existe no PostgreSQL ou está NULL
Quando selectAllPedConsulta for executado
Então o VO recebe vlAcrescimo = 0.0, sem erro, sem crash
Dado que PedidoConsultaDB.saveAll recebe os VOs retornados
Quando gravar em pedido_consulta
Então pedido_consulta.vl_acrescimo reflete o valor lido do PG (via Story 2.4 que já aceita o campo)
Story 3.3: Incluir vl_acrescimo no MD5 de Change-Detection
Como sistema,
quero que mudanças isoladas de vl_acrescimo num pedido disparem re-sync do registro local,
para que ajustes de acréscimo no ERP (reabertura, correção manual server-side) sejam propagados ao dispositivo.
Acceptance Criteria:
Dado que um pedido já sincronizado no SQLite tem vl_acrescimo = 87.50
Quando o ERP alterar só o vl_acrescimo do registro (ex: correção do escritório) e recalcular o MD5
Então o MD5 recebido muda, e PedidoConsultaDB.saveAll detecta a divergência e dispara updateErp
Dado que o MD5 do PG inclui vl_acrescimo (ou acrev / tx_acrescimo × total) no hash
Quando o app calcular o MD5 local para comparação
Então o cálculo reflete o mesmo campo — evitando loop de "está diferente" / "está igual" entre as duas direções
Dado que pedidos pré-Epic 3 no ERP têm acrep/acrev/tx_acrescimo com valor default (0)
Quando o primeiro sync após o deploy rodar
Então esses pedidos aparecem como "atualizados" (MD5 mudou devido ao novo campo), mas o vl_acrescimo gravado é 0.0 — comportamento aceitável