MT103ENEG em resumo
- Onde fica
- função
A103ValEstNeg(), chamada pela validação de exclusão do documento de entrada (MaCanDelF1()). - Quando dispara
- na exclusão da nota, quando o saldo do produto no armazém ficaria negativo (ou menor que a reserva) e
MV_ESTNEGnão éS. - PARAMIXB
{cAliasSD1}, o alias do item que está sendo validado.- Retorno
- usado. Tem de ser lógico:
.T.deixa a exclusão seguir,.F.(ou qualquer outro tipo) a barra. - Serve para bloquear?
- Ao contrário: o padrão já bloqueia. Este PE serve para liberar.
Consulta rápida7 seções
Sem o PE, o padrão mostra o aviso “O saldo do produto/local ficará negativo após a exclusão” e aborta. Com o PE compilado, o aviso some e quem decide é você.
Quando ele é chamado, e quando não é
O cálculo é feito item a item: o padrão parte de B2_QATU do produto e armazém e subtrai D1_QUANT de cada item da nota. Se o item veio de ordem de produção ou está em trânsito, soma de volta a quantidade do movimento correspondente na SD3. Se o resultado ficar negativo, ou menor que B2_RESERVA, entra a regra de estoque negativo:
Três saídas que o PE nunca vê:
MV_ESTNEGigual aS. O padrão tem o próprio tratamento (pergunta “Continua?” para produto sem rastro e sem localização; bloqueio para produto com rastro ou localização). O PE não entra.- Exclusão por rotina automática (
l103Autoverdadeiro). O padrão não chama o PE e não mostra mensagem. Ele reaproveita o último resultado guardado na validação: começa em.F., e só muda quando o PE é chamado para algum item. Numa nota de um item, ou quando nenhum item anterior passou pelo PE, a exclusão é barrada mesmo com o PE compilado. Numa nota de vários itens, esse resultado vem de uma chamada anterior, e não de uma avaliação do item atual. Teste esse cenário antes de contar com ele. - Produto com controle de lote e sem controle de endereço. Para esse produto o PE também não é chamado e o resultado é
.F.. O comentário no fonte diz que o produto não poderá ter lote ou localização; pelo código, o que escapa do PE é exatamente a combinação rastro sem localização.
Existe ainda o parâmetro MV_NEGATBF: se verdadeiro, todo esse bloco de verificação de saldo é pulado.
Armadilha: o retorno é a decisão inteira
O padrão faz lRet := ExecBlock(...) e só reconhece tipo lógico. Se o seu PE terminar sem Return, ou retornar Nil, número ou texto, o padrão assume .F. e bloqueia a exclusão, sem mostrar mensagem. O resultado é um PE “que não libera nada”, sem erro que aponte o motivo.
O oposto também vale: Return .T. incondicional permite excluir qualquer nota que deixaria o estoque negativo, para qualquer produto e armazém. Restrinja pela sua regra.
Como é o único ponto onde o aviso do padrão é suprimido, mostre uma mensagem quando você bloquear. Retornar .F. calado deixa o usuário sem explicação.
O que ele recebe
PARAMIXB[1] é o alias (texto) da área de trabalho do item de nota. Pode ser a própria SD1 ou uma consulta temporária, então não use SD1-> direto: leia pelo alias, como (cAlias)->D1_COD. O posicionamento é no item que gerou a validação; o PE é chamado de novo para cada item que ficar negativo.
Exemplo
A regra do exemplo: liberar a exclusão apenas quando o item está num armazém listado num parâmetro, por exemplo um armazém de consignação onde o saldo negativo é aceito.
#Include "Protheus.ch"
/*/{Protheus.doc} MT103ENEG
Chamado ao excluir a nota de entrada quando o saldo ficaria negativo
e MV_ESTNEG nao e S. Libera so para armazens listados em parametro.
@type function
@param PARAMIXB[1], character, alias do item de nota em validacao
@return logical, .T. libera a exclusao; .F. mantem o bloqueio
/*/
User Function MT103ENEG()
Local aArea := GetArea()
Local cAlias := ""
Local cLocal := ""
Local cProd := ""
Local cLiberar := ""
Local lRet := .F.
If Type("PARAMIXB") <> "A" .Or. Len(PARAMIXB) < 1 .Or. ValType(PARAMIXB[1]) <> "C"
RestArea(aArea)
Return .F.
EndIf
cAlias := PARAMIXB[1]
cLocal := (cAlias)->D1_LOCAL
cProd := AllTrim((cAlias)->D1_COD)
cLiberar := SuperGetMv("MV_XARMNEG", .F., "")
If !Empty(cLiberar) .And. cLocal $ cLiberar
lRet := .T.
Else
// O padrao nao mostra o aviso quando o PE existe: avise aqui.
Help(" ", 1, "MT103ENEG",, ;
"A exclusao deixaria o saldo do produto " + cProd + ;
" no armazem " + cLocal + " negativo.", 1, 0)
EndIf
RestArea(aArea)
Return lRetO Return .F. do início cobre o caso de PARAMIXB inesperado e mantém o comportamento seguro: bloquear. O Help só aparece no ramo em que a regra não liberou.
Parâmetros
MV_ESTNEG é o que decide se o PE entra em cena: o fonte compara o conteúdo com S. MV_XARMNEG é do exemplo (parâmetro de cliente, a criar, caractere): guarda os códigos de armazém concatenados, como 0102, e o exemplo testa com $. Funciona porque o armazém tem dois caracteres; se o seu tiver tamanho diferente, compare por outro critério.
SELECT X6_VAR, X6_TIPO, X6_DESCRIC, X6_CONTEUD
FROM SX6010
WHERE X6_VAR IN ('MV_ESTNEG', 'MV_NEGATBF', 'MV_XARMNEG')A consulta mostra o cadastro no seu ambiente. Ela não diz qual rotina lê o parâmetro; isso vem do comportamento descrito acima.
Solução de problemas
| Sintoma | Causa provável | Correção |
|---|---|---|
| PE compilado, mas a exclusão continua barrada | MV_ESTNEG é S, ou a exclusão vem por rotina automática, ou o produto tem lote e não tem endereço | Conferir os três casos; nos dois últimos o PE não é chamado |
| Exclusão barrada e sem aviso | PE devolveu Nil ou valor não lógico | Garantir Return lógico em todos os caminhos |
| Aviso do padrão sumiu e a exclusão foi barrada | PE existe e devolveu .F. sem mensagem | Exibir Help antes de devolver .F. |
Os vizinhos
Para o fim do documento de entrada depois de gravar, veja o MT103FIM. Para o mecanismo geral, veja Ponto de entrada no Protheus e PARAMIXB.
Continue por aqui
- Vídeo
DesenvolvimentoReferência técnica
F340VALOK: o ponto de entrada que barra o OK da compensação a pagar
F340VALOK roda ao clicar OK na lista de títulos da compensação a pagar, recebe a lista em PARAMIXB e, retornando .F., mantém o usuário na lista.
- Vídeo
DesenvolvimentoReferência técnica
F340VLD: o ponto de entrada que barra a compensação no Contas a Pagar
F340VLD roda ao confirmar a primeira tela da compensação a pagar (FINA340), sem PARAMIXB. Retornando .F., a tela não fecha e nenhum título chega a ser listado.
- Vídeo
DesenvolvimentoReferência técnica
F40DELPR: o ponto de entrada que troca a baixa do provisório pela exclusão
F40DELPR roda ao abrir a substituição de título provisório no Contas a Receber, sem PARAMIXB. Retornando .T., o provisório é excluído em vez de baixado.