
_Créditos das imagens: ChatGPT
## 📚 ReadStackParameters: quando o contexto existe, mas o Protheus não entrega
Quem trabalha com **Pontos de Entrada no Protheus** já entendeu uma verdade inconveniente:
👉 o sistema **sabe tudo**, mas **entrega pouco contexto**.
E foi exatamente desse abismo que nasceu o **ReadStackParameters**.
### O problema real : contexto
No Protheus, os Pontos de Entrada foram criados para **estender o sistema sem quebrar o contrato**. Beleza na teoria.
Na prática, muitos PEs:
* São executados **dentro de loops**
* Operam **item a item**
* Dependem de cálculos **já realizados pelo core**
* Mas recebem **parâmetros insuficientes**
O resultado? Código redundante, recalculando o que **já foi calculado**.
### O caso crítico: MT150GRV no MATA150
No **MATA150 (Atualização de Cotação)**, o PE `MT150GRV` é executado **para cada item**, durante a gravação.
Neste contexto, considerando que preciso obter os impostos (por item), devidamente calculados e em memória, para armazená-los em tabela proprietária para composição de preços. Mas...
Ele recebe basicamente:
* `nOPCx` → Inclusão, Alteração ou Exclusão
Só isso.
O problema é óbvio:
* `nOPCx` diz **o que o usuário escolheu**
* Mas não diz **qual item está sendo processado**
A variável que resolve isso — `nX`, índice do loop — é:
* Local
* Interna
* Não exposta
* Não passada ao PE
Mas o sistema **já calculou os impostos por item**.
Eles estão em memória.
O contexto existe.
Mesmo assim, o desenvolvedor é forçado a:
* Recalcular impostos
* Reexecutar rotinas fiscais complexas
* Lidar com erros de arredondamento
* Repassar parâmetros sensíveis manualmente
Tudo isso **sem necessidade técnica real**.
---
## Por que o ReadStackParameters foi criado
O **ReadStackParameters** nasce como uma resposta pragmática a essa pergunta incômoda:
> *Se o Protheus já tem a informação na stack, por que eu não posso lê-la?*
A ideia não é hackear.
Não é quebrar encapsulamento.
Não é mutar variáveis internas.
👉 É **ler contexto**.
### O que o ReadStackParameters faz
* Permite acessar **variáveis locais, static, etc, de funções em níveis superiores da stack**
* Atua de forma **somente leitura**
* Não altera fluxo, estado ou comportamento do core
* Apenas **recupera informações já existentes**
Ou seja:
Ele **restaura/expõe o contexto perdido** quando o PE é chamado.
No caso do MT150GRV:
* Com `nX`, é possível acessar os impostos já apurados por item
* Evita recálculo
* Evita inconsistências
* Mantém integridade fiscal
* Reduz complexidade e risco
```xBase
//Obtenho a posição do Item que está sendo gravado. Deveria vir como parâmetro do PE U_MT150GRV
//Utilizo StackParameters():ReadStackParameters para obter a informação de nX, local em A150Grava, (que representa o item a ser gravado).
nXA150GRAVA:=dna.tech.StackParameters():ReadStackParameters("A150GRAVA","NX","LOCAL")
//Obtem o Imposto de PIS à partir das informações já calculadas pelo sistema padrão
//Valor do PIS
_nValPIS:=MaFisRet(nXA150GRAVA,"IT_VALPS2")
//Base de calculo do PIS
_nBasePIS:=MaFisRet(nXA150GRAVA,"IT_BASEPS2")
//Aliquota de calculo do PIS
_nAliqPIS:=MaFisRet(nXA150GRAVA,"IT_ALIQPS2")
//Obtem o Imposto de COFINS à partir das informações já calculadas pelo sistema padrão
//Valor do COFINS
_nValCOF:=MaFisRet(nXA150GRAVA,"IT_VALCF2")
//Base de calculo do COFINS
_nBaseCOF:=MaFisRet(nXA150GRAVA,"IT_BASECF2")
//Aliquota de calculo do COFINS
_nAliqCOF:=MaFisRet(nXA150GRAVA,"IT_ALIQCF2")
```
---
## O problema não é o PE. É o contrato incompleto.
O erro não está em existir um PE dentro de um loop.
O erro está em **não fornecer o contexto mínimo de execução**.
Hoje, o contrato implícito é:
> “Aqui está um gancho. Se vire.”
Isso força soluções:
* Invasivas
* Repetitivas
* Difíceis de manter
* Altamente acopladas
O **ReadStackParameters** é um sintoma claro de que:
> O modelo atual de extensibilidade está incompleto.
---
## Como isso deveria ser resolvido “by TOTVS”
A solução ideal **não é** cada cliente criar sua própria versão de leitura de stack.
A solução ideal seria a TOTVS fornecer algo como:
### 1️⃣ Uma API oficial de contexto de execução
Algo conceitualmente assim:
* Leitura **somente leitura**
* Escopo controlado
* Sem acesso arbitrário
* Com garantia de estabilidade
Exemplo conceitual:
* `FWExecutionContext():Get("MATA150","A150Grava","nX")`
* `FWExecutionContext():Get("MATA150","A150Grava","aImpostos")`
* `FWExecutionContext():Has("MATA150","A150Grava","nItem")`
Nada de mutação.
Nada de side effects.
---
### 2️⃣ Contrato explícito de execução do PE
Documentar claramente:
* Se o PE roda em loop
* Se roda por item
* Se há contexto acumulado
* Quais variáveis são relevantes naquele momento
Isso transforma o PE de “gancho cego” em **extensão consciente**.
---
### 3️⃣ Compatibilidade com legado (sem quebrar nada)
* Não precisa alterar PEs existentes
* Não precisa mudar assinatura
* Apenas **expõe contexto existente**
Ou seja:
Zero impacto retroativo, ganho arquitetural imediato.
---
## ReadStackParameters não é gambiarra. É um pedido de socorro.
Quando um desenvolvedor cria algo como o ReadStackParameters, ele não está tentando burlar o sistema.
Ele está dizendo:
> “O Protheus sabe o que eu preciso.
> Só não me deixa acessar.”
Isso é um sinal claro de maturidade do ecossistema — e também de um ponto que precisa evoluir.
---
## Conclusão
* O Protheus **já calcula**
* O Protheus **já sabe**
* O Protheus **já tem em memória**
O que falta é **entregar o contexto**.
O **ReadStackParameters** existe porque:
* O contrato dos PEs é insuficiente
* A extensibilidade perde contexto
* O desenvolvedor precisa de previsibilidade e precisão
Uma solução oficial da TOTVS, segura e somente leitura, não seria apenas bem-vinda —
seria um **salto de qualidade arquitetural** no modelo de extensibilidade do Protheus.
---
#ReadStackParameters, #Protheus, #PontosDeEntrada, #Extensibilidade, #ArquiteturaDeSoftware, #ContextoDeExecucao, #AdvPL, #TLPP, #ERP, #BoasPraticas
Torne-se um Sponsor:
🥊(дави)={0.5x[(Налдо)+(Алине)]}🥊
Comentários
Postar um comentário