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.