No artigo de hoje, será demonstrado a utilização da função a468NFatura para faturar um pedido para o Mercosul (no lugar da clássica MaPvlNfs).
O grande Fernando Vernier ( LinkedIn ), gentilmente montou um exemplo de como faturar pedidos de venda, usando a função a468NFatura.
A lógica da rotina, é a seguinte:
- É utilizado o ponto de entrada M468ASER para definir a Série da NF
- Na função customizada GeraNFPer, recebe por parâmetro o número do pedido de venda que será faturado
- Nisso é feito uma busca pelo pedido e depois posiciona nas liberações na SC9
- É montado um array com os parâmetros necessários da rotina
- Por fim é acionado a função a468NFatura e gerado as informações
Abaixo o código fonte conforme a lógica descrita acima:
//Bibiliotecas
#Include "TOTVS.ch"
#Include "TopConn.ch"
/*/{Protheus.doc} GeraNFPer
Função para faturar a NF para o Mercosul
@type function
@version 12.1.2210
@author Fernando Vernier
@since 07/07/2024
@param cNumPed, Caractere, Numero do pedido
@param cSerieNF, Caractere, Serie da NF que será gerada
@param lRemisso, Lógico, Define se irá gerar remisso (se vier como .T.)
@return cNFSaida, Caractere, Número da Nota Fiscal
@example
cNota := u_GeraNFPer("000002", .F.)
Alert("Nota gerada foi: " + cNota)
@obs É necessário ter esses campos e parâmetros na base:
C5_TIPOREM - tamanho 1 - caractere
C5_DOCGER - tamanho 1 - caractere
F2_TABELA - igual o C5_TABELA
F2_NATUREZ - igual ao C5_NATUREZ
D2_GERANF - tamanho 1 - caractere
E4_BXTITAV - tamanho 1 - caractere
MV_FACTAUT - caractere (testes feitos com S)
MV_CONTNF - caractere (testes feitos com -vazio-)
MV_SEQESPE - lógico (testes feitos com .F.)
Foi usado o P.E. M468ASER ( https://tdn.totvs.com/pages/releaseview.action?pageId=6784231 ) para pegar a Série
/*/
User Function GeraNFPer(cNumPed, lRemisso)
Local aArea := FWGetArea()
Local aAreaSC5 := SC5->(FWGetArea())
Local aAreaSC9 := SC9->(FWGetArea())
Local cQuery := ""
Local aRecnos := {}
Local cNFAlias := "SD2"
//Parâmetros que vem na função
Default cNumPed := ""
Default lRemisso := .F.
//Geração do Remisso
Private nIndex := 0
Private cMarca := " "
//Arrays de Controle
Private aRegSC9 := {}
Private aParams := {}
//Variável de Retorno
Private cNFSaida := ""
//Outras variáveis de Controle / Processamento
Private lMSAuto := .T.
Private lReajuste := .F.
Private lConvRem := GetNewPar("MV_CONVREM",.F.)
Private aTamSx3Prc := TamSx3("D2_PRCVEN")
Private aTamSx3Tot := TamSx3("D2_TOTAL",.F.)
Private nMoedaOrig := 1
Private nTaxamoeda := 0
Private lInverte := .F.
//Abre as tabelas padrões que serão usadas
DbSelectArea("SC5")
SC5->(DbSetOrder(1)) // C5_FILIAL + C5_NUM
DbSelectArea("SC9")
SC9->(DbSetOrder(1)) // C9_FILIAL + C9_PEDIDO + C9_ITEM + C9_SEQUEN + C9_PRODUTO + C9_BLEST + C9_BLCRED
//Obtém informações do pedido
cQuery := "SELECT SC5.R_E_C_N_O_ RECNOSC5 " + CRLF
cQuery += "FROM " + RetSqlName("SC5") + " SC5 (NOLOCK) " + CRLF
cQuery += "WHERE " + CRLF
cQuery += "SC5.C5_FILIAL = '"+FWxFilial("SC5")+"' AND " + CRLF
cQuery += " SC5.D_E_L_E_T_ = '' " + CRLF
cQuery += " AND C5_NUM = '" +cNumPed + "' " + CRLF
TcQuery cQuery New Alias "QRY_SC5"
//Se houver dados na query
If ! QRY_SC5->(EoF())
//Posiciona no pedido
nRecnoSC5 := QRY_SC5->RECNOSC5
SC5->(DbGoTo(nRecnoSC5))
//Se conseguir posicionar na liberação
If SC9->(DbSeek(FWxFilial("SC9")+SC5->C5_NUM))
//Enquanto houver itens liberados, adiciona no array de registros
While SC9->(!EoF()) .AND. SC9->C9_FILIAL == FWxFilial("SC9") .And. SC9->C9_PEDIDO == SC5->C5_NUM
aAdd(aRegSC9, SC9->(RecNo()))
SC9->(DbSkip())
EndDo
EndIf
//Se for gerar Remisso
If lRemisso
//Aciona a geração
aParams := {2, 2, 2, 2, 1, 1}
aReturn := A462ANGera(nIndex, cMarca, .T., aRegSC9, , aParams)
//Busca informações do Remisso gerado
cQuery := "SELECT D2_DOC, D2_SERIE, R_E_C_N_O_ AS RECNO FROM " + RetSqlName("SD2") + CRLF
cQuery += " WHERE D_E_L_E_T_ = ' ' AND D2_FILIAL = " +FWxFilial("SD2") + CRLF
cQuery += " AND D2_DOC = '"+aReturn[1,2]+"' AND D2_SERIE = '"+aReturn[1,1]+"' " + CRLF
TCQuery cQuery New Alias "QRY_SD2"
//Percorre os itens da NF e adiicona no Array
While !QRY_SD2->(EoF())
aAdd( aRecnos, QRY_SD2->RECNO)
QRY_SD2->(DbSkip())
EndDo
QRY_SD2->(DbCloseArea())
//Define o alias usado como o da SD2
cNFAlias := "SD2"
//Pega as informações da SC9 e define o alias usado
Else
aRecnos := aClone(aRegSC9)
cNFAlias := "SC9"
EndIf
//Seta as perguntas em memória
aParams := { ;
SC5->C5_NUM,; // MV_PAR01 -> Do Pedido
SC5->C5_NUM,; // MV_PAR02 -> Ate Pedido
SC5->C5_CLIENTE,; // MV_PAR03 -> Do Cliente
SC5->C5_CLIENTE,; // MV_PAR04 -> Ate Cliente
SC5->C5_LOJACLI,; // MV_PAR05 -> Da Filial
SC5->C5_LOJACLI,; // MV_PAR06 -> Ate Filial
"",; // MV_PAR07 -> Do Grupo
"ZZZZ",; // MV_PAR08 -> Ate Grupo
"",; // MV_PAR09 -> Do Agregador
"ZZZZ",; // MV_PAR10 -> Ate Agregador
2,; // MV_PAR11 -> Mostra Lanç.Contab
2,; // MV_PAR12 -> Aglut. Lançamentos
2,; // MV_PAR13 -> Lanç.Contab.On-Line
1,; // MV_PAR14 -> Trazer Pedidos Marc
2,; // MV_PAR15 -> Atualiza Vinculo
5,; // MV_PAR16 -> Aglutina Por
10,; // MV_PAR17 -> Valor Minimo
2,; // MV_PAR18 -> Fatura Pro-Forma
" ",; // MV_PAR19 -> Transportadora De
"ZZZZZZ",; // MV_PAR20 -> Transportadora Ate
2,; // MV_PAR21 -> Reajusta na mesma nota
1,; // MV_PAR22 -> Fatura Pedido pela
1,; // MV_PAR23 -> Fatura pela Moeda
1,; // MV_PAR24 -> Contabiliza por
1 ; // MV_PAR25 -> Tipo Pedido (1 - Normal / 2 - Beneficiamento)
}
//Aciona a geração dos dados
Begin Transaction
aReturn := a468NFatura(cNFAlias, aParams, aRecnos, Nil)
End Transaction
//Se não for Remisso, pega do C5_NOTA
If ! lRemisso
cNFSaida := SC5->C5_NOTA
//Senão pega da resposta do a468NFatura
Else
cNFSaida := aReturn[1,2]
EndIf
EndIf
QRY_SC5->(DbCloseArea())
FWRestArea(aAreaSC9)
FWRestArea(aAreaSC5)
FWRestArea(aArea)
Return cNFSaida
User Function M468ASER()
Local aArea := FWGetArea()
Local cSerieNF := "1"
FWRestArea(aArea)
Return cSerieNF
Bom pessoal, por hoje é só.
Abraços e até a próxima.