MaLibDoFat
Funcao interna do FATXFUN que libera itens de pedido de venda, avaliando credito e estoque, e gera os registros de bloqueio na tabela SC9.
Assinatura: MaLibDoFat(nRecSC6, nQtdLib, @lCredito, @lEstoque, lAmarrarOP, lAvEst, lLiber, lTransf) -> nQtdLiberada
Retorna: Numeric
MaLibDoFat e a funcao usada pelo Faturamento (e tambem pelo Loja, via LOJA701C) para gerar os registros de liberacao na tabela SC9 a partir de um item de pedido de venda (SC6). Ela avalia credito do cliente e disponibilidade de estoque, preenche os campos de bloqueio (C9_BLCRED) e retorna a quantidade que de fato foi liberada.
Fica no fonte padrao FATXFUN.PRX, junto com MaAvalSC6. Nao tem pagina dedicada de Protheus.doc no TDN — a TOTVS trata como funcao interna do FATXFUN. A assinatura abaixo foi derivada do codigo real publicado em Pontos de Entrada e Documentos Tecnicos oficiais da TOTVS.
Sintaxe
nQtdLib := MaLibDoFat( ;
SC6->(RecNo()), ; // 1) RecNo do item SC6 a liberar
nQtdLib, ; // 2) Quantidade que se deseja liberar
@lCredito, ; // 3) [REF] retorna .T. se gerou bloqueio de credito
@lEstoque, ; // 4) [REF] retorna .T. se gerou bloqueio de estoque
.F., ; // 5) lAmarrarOP - amarra Ordem de Producao gerada
lAvEst, ; // 6) Avalia estoque (depende de MV_ESTNEG)
lLiber, ; // 7) .T. = efetua liberacao; .F. = simula
lTransf ; // 8) .T. se for transferencia entre filiais
)
Exemplo pratico (do Ponto de Entrada VX001APV)
// Antes da gravacao do pedido, libera os itens manualmente
SC6->(dbSetOrder(1))
SC6->(dbSeek(xFilial("SC6") + cNumPed + "01"))
While !SC6->(Eof()) .And. ;
SC6->C6_FILIAL == xFilial("SC6") .And. ;
SC6->C6_NUM == cNumPed
// So libera se ainda nao existe registro na SC9
SC9->(dbSetOrder(1))
If !SC9->(dbSeek(xFilial("SC9") + cNumPed + SC6->C6_ITEM))
lCredito := .T.
lEstoque := .T.
lLiber := .T.
lTransf := .F.
lAvEst := If(GetMV("MV_ESTNEG") == "S", .F., .T.)
nQtdLib := SC6->C6_QTDVEN
nQtdLib := MaLibDoFat( ;
SC6->(RecNo()), nQtdLib, ;
@lCredito, @lEstoque, ;
.F., lAvEst, lLiber, lTransf )
// Apos a chamada:
// lCredito = .T. se gerou bloqueio de credito
// lEstoque = .T. se gerou bloqueio de estoque
// nQtdLib = quantidade efetivamente liberada
EndIf
SC6->(dbSkip())
EndDo
Quando usar
- Customizacoes que liberam pedido fora do MATA450/MATA460 — quando precisa simular o caminho oficial de liberacao a partir de um PE ou rotina batch.
- Integracoes que recebem pedido externo (marketplace, EDI) e precisam gerar SC9 sem passar pela tela.
- Pre-validacao de credito antes de gravar o pedido — chamando com
lLiber = .F., voce avalia sem efetivar a SC9. - Venda com entrega no Loja (TIPO 3) — fluxo padrao do
LOJA701C. - Reprocessar liberacao apos alterar limite de credito de um cliente.
Bloqueios gravados em C9_BLCRED
| Codigo | Significado |
|---|---|
| (vazio) | Sem bloqueio de credito |
| 01 | Bloqueio por valor (limite de credito insuficiente) |
| 02 | Bloqueio por falta de estoque (com MV_BLQCRED = T) |
| 04 | Bloqueio por vencimento do limite (A1_VENCLC vencido) |
| 09 | Liberacao manual rejeitada pelo usuario na rotina MATA456 |
Pegadinhas
- Posicione SC6 corretamente antes — a funcao usa
RecNo()da SC6, entao a area precisa estar selecionada e no item certo. Esquecer isso libera o item errado. lLiber = .F.faz simulacao — util pra testar se um pedido vai bloquear sem efetivar a SC9. Vale chamar primeiro com.F.pra avaliar antes de decidir.MV_ESTNEGcontrolalAvEst. Se o cliente permite estoque negativo, passa.F.(nao avalia). Senao,.T.(avalia e bloqueia se nao tem saldo).- A funcao altera a SC9. Se rodar em loop sem critério, gera registros duplicados — sempre cheque com
dbSeek(xFilial+NumPed+Item)antes. - Retorno menor que o solicitado indica liberacao parcial (saldo de estoque insuficiente, por exemplo). Cheque se o retorno bate com
SC6->C6_QTDVEN. - Use dentro de transacao (
Begin Transaction) quando combinada com outras gravacoes — se quebrar no meio, a SC9 pode ficar inconsistente com SC5/SC6.
Onde a funcao e chamada (no padrao)
| Fluxo | Programa |
|---|---|
| Liberacao manual via MATA450 / MATA460 | Rotinas de Liberacao de Credito e Estoque |
| Venda com entrega no Loja (TIPO 3) | LOJA701C, Lj7Pedido, Lj7GeraEnt |
| Inclusao/alteracao de pedido via ExecAuto | MATA410 (apos gravar SC6, antes de gerar NF) |
| Concessionarias DMS | PE VX001APV — Antecede gravacao de pedido |
Pontos de Entrada relacionados
M460LIB— durante liberacao de pedido (MATA460)M410LiOk— confirmacao de gravacao do pedido (MATA410)VX001APV— antecede gravacao do pedido (DMS - Concessionarias)
Fontes oficiais (TDN)
- VX001APV - Antecede gravacao de pedido de venda (codigo real chamando MaLibDoFat)
- TVOUXJ - DT Bloqueio de credito venda entrega retaguarda (cita MaLibDoFat em FATXFUN)
- Bloqueios gravados na Tabela SC9 (Liberacao dos Pedidos de Venda)
Parâmetros
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
nRecSC6 | Numeric | sim | RecNo do item SC6 (item do pedido de venda) que sera liberado. A area SC6 deve estar selecionada e posicionada. |
nQtdLib | Numeric | sim | Quantidade que se deseja liberar (geralmente SC6->C6_QTDVEN). |
@lCredito | Logical | sim | Passado por referencia. Retorna .T. se a liberacao gerou bloqueio de credito. |
@lEstoque | Logical | sim | Passado por referencia. Retorna .T. se a liberacao gerou bloqueio de estoque. |
lAmarrarOP | Logical | sim | Indica se deve amarrar Ordem de Producao gerada ao item liberado. Tipicamente .F. |
lAvEst | Logical | sim | Avalia estoque. Quando MV_ESTNEG = S, passa .F. (nao avalia, permite negativo); senao .T. |
lLiber | Logical | sim | .T. para efetivar a liberacao (cria registros na SC9). .F. apenas simula. |
lTransf | Logical | sim | .T. se a operacao for transferencia entre filiais; .F. para venda comum. |
Exemplos
Liberar todos os itens de um pedido manualmente
SC6->(dbSetOrder(1))
SC6->(dbSeek(xFilial("SC6") + cNumPed))
While !SC6->(Eof()) .And. SC6->C6_NUM == cNumPed
SC9->(dbSetOrder(1))
If !SC9->(dbSeek(xFilial("SC9") + cNumPed + SC6->C6_ITEM))
lCred := .T. ; lEst := .T.
lAvEst := If(GetMV("MV_ESTNEG") == "S", .F., .T.)
nQtd := SC6->C6_QTDVEN
nLib := MaLibDoFat(SC6->(RecNo()), nQtd, @lCred, @lEst, .F., lAvEst, .T., .F.)
If lCred ; ConOut("Item bloqueado por credito") ; EndIf
If nLib < nQtd ; ConOut("Liberacao parcial: " + cValToChar(nLib)) ; EndIf
EndIf
SC6->(dbSkip())
EndDoSimular liberacao (sem gravar SC9) pra avaliar credito antes
// lLiber = .F. faz simulacao - util pra decidir se grava o pedido
lCred := .T. ; lEst := .T. ; lAvEst := .T.
nLibSim := MaLibDoFat( ;
SC6->(RecNo()), SC6->C6_QTDVEN, ;
@lCred, @lEst, .F., lAvEst, /*lLiber=*/ .F., .F. )
If lCred .Or. lEst
MsgAlert("Pedido vai bloquear. Confirma gravar mesmo assim?")
EndIf