Função para Faturar Pedidos de Venda (Mercosul)

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:

  1. É utilizado o ponto de entrada M468ASER para definir a Série da NF
  2. Na função customizada GeraNFPer, recebe por parâmetro o número do pedido de venda que será faturado
  3. Nisso é feito uma busca pelo pedido e depois posiciona nas liberações na SC9
  4. É montado um array com os parâmetros necessários da rotina
  5. 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.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

Deixe uma resposta

Terminal de Informação