R/baixa-nfp.R

#' Baixa dados da Nota Fiscal Paulista
#'
#' \code{baixa_nfp()} precisa como argumentos o CPF e a senha do usuario
#' que funcionem ao acessar o site da nota fiscal paulista
#'
#' @seealso \url{https://www.nfp.fazenda.sp.gov.br/login.aspx}
#' @export
#' @keywords NFP
#' @param cpf Numero do cpf em forma de string, somente com os numeros
#' @param senha Senha em forma de string
#' @examples
#' 
#' ## NOT RUN
#' dados_nfp <- baixa_nfp('12345678900', 'senha')
#' ## NOT RUN
baixar_nfp <- function(cpf, senha) {
  cpf <- gsub('[^0-9]', '', cpf)
  url_login <- 'https://www.nfp.fazenda.sp.gov.br/login.aspx'
  # login
  r_login <- httr::GET(url_login)
  dados <- list('__EVENTTARGET' = '',
                '__EVENTARGUMENT' = '',
                '__VIEWSTATE' = pegar_viewstate(r_login),
                '__EVENTVALIDATION' = pegar_eventval(r_login),
                'ctl00$ddlTipoUsuario' = '#rdBtnNaoContribuinte',
                'ctl00$UserNameAcessivel' = 'Digite o Usuário',
                'ctl00$PasswordAcessivel' = 'x',
                'ctl00$ConteudoPagina$Login1$rblTipo' = 'rdBtnNaoContribuinte',
                'ctl00$ConteudoPagina$Login1$UserName' = cpf,
                'ctl00$ConteudoPagina$Login1$Password' = senha,
                'ctl00$ConteudoPagina$Login1$Login' = 'Acessar')
  r_logado <- httr::POST(url_login, body = dados)
  # pega os periodos disponiveis
  r_logado <- verificar_pagina_inicial(r_logado)
  # nao sei pq precisa rodar duas vezes, mas assim funciona...
  r_logado <- verificar_pagina_inicial(r_logado)
  p <- r_logado %>%
    httr::content('text') %>%
    xml2::read_html() %>%
    rvest::html_nodes('p') %>%
    rvest::html_text()
  cond <- stringr::str_detect(p, 'Ocorreu uma falha')
  if(any(cond)) {
    p <- p[cond]
    stop(p)
  }
  periodos <- httr::content(r_logado, 'text') %>% 
    xml2::read_html() %>% 
    rvest::html_nodes(xpath = '//*[@id="rblPeriodo"]//input[@type="radio"]') %>%
    rvest::html_attr('value')
  d <- data.frame(periodo = periodos, stringsAsFactors = FALSE) %>%
    dplyr::group_by(periodo) %>%
    dplyr::do(pegar_periodo(.$periodo, r_logado)) %>%
    dplyr::ungroup()
  gc(verbose=FALSE)
  return(d)
}

#' Verifica o saldo da Nota Fiscal Paulista
#'
#' \code{baixa_nfp()} precisa como argumentos o CPF e a senha do usuario
#' que funcionem ao acessar o site da nota fiscal paulista
#'
#' @seealso \url{https://www.nfp.fazenda.sp.gov.br/login.aspx}
#' @export
#' @keywords NFP
#' @param cpf Numero do cpf em forma de string, somente com os numeros
#' @param senha Senha em forma de string
#' @examples
#' 
#' ## NOT RUN
#' saldo <- verificar_saldo('12345678900', 'senha')
#' ## NOT RUN
verificar_saldo <- function(cpf, senha) {
  cpf <- gsub('[^0-9]', '', cpf)
  url_login <- 'https://www.nfp.fazenda.sp.gov.br/login.aspx'
  # login
  r_login <- httr::GET(url_login)
  dados <- list('__EVENTTARGET' = '',
                '__EVENTARGUMENT' = '',
                '__VIEWSTATE' = pegar_viewstate(r_login),
                '__EVENTVALIDATION' = pegar_eventval(r_login),
                'ctl00$ddlTipoUsuario' = '#rdBtnNaoContribuinte',
                'ctl00$UserNameAcessivel' = 'Digite o Usuário',
                'ctl00$PasswordAcessivel' = 'x',
                'ctl00$ConteudoPagina$Login1$rblTipo' = 'rdBtnNaoContribuinte',
                'ctl00$ConteudoPagina$Login1$UserName' = cpf,
                'ctl00$ConteudoPagina$Login1$Password' = senha,
                'ctl00$ConteudoPagina$Login1$Login' = 'Acessar')
  r_logado <- httr::POST(url_login, body = dados)
  # pega os periodos disponiveis
  r_logado <- verificar_pagina_inicial(r_logado)
  # nao sei pq precisa rodar duas vezes, mas assim funciona...
  r_logado <- verificar_pagina_inicial(r_logado)
  p <- r_logado %>%
    httr::content('text') %>%
    xml2::read_html() %>%
    rvest::html_nodes('p') %>%
    rvest::html_text()
  cond <- stringr::str_detect(p, 'Ocorreu uma falha')
  if(any(cond)) {
    p <- p[cond]
    stop(p)
  }
  p <- gsub('[^0-9,]', '', p[stringr::str_detect(p, 'Saldo Disp')])
  p <- as.numeric(gsub(',', '.', gsub('\\.', '', p)))
  p
}


pegar_periodo <- function(periodo, r) {
  url_consulta <- 'https://www.nfp.fazenda.sp.gov.br/ConsultaNF/ConsultaNF.aspx'
  url_export <- 'https://www.nfp.fazenda.sp.gov.br/ConsultaUsuario/ConsultaListaNF2.aspx'
  dados_consulta <- list('__VIEWSTATE' = pegar_viewstate(r),
                         '__EVENTTARGET' = '',
                         '__EVENTARGUMENT' = '',
                         '__EVENTVALIDATION' = pegar_eventval(r),
                         'ctl00$ConteudoPagina$rblPeriodo' = periodo,
                         'ctl00$ConteudoPagina$btnConsultarNFSemestre' = 'Consultar')
  r_consulta <- httr::POST(url_consulta, body = dados_consulta)
  # exportar para excel
  dados_export <- list('__EVENTTARGET' = '',
                       '__EVENTARGUMENT' = '',
                       '__LASTFOCUS' = '',
                       '__VIEWSTATE' = pegar_viewstate(r_consulta),
                       '__EVENTVALIDATION' = pegar_eventval(r_consulta),
                       'ctl00$ConteudoPagina$txtGdocRejeicao' = '',
                       'ctl00$ConteudoPagina$gdvConsulta$ctl23$ddlPages' = '1',
                       'ctl00$ConteudoPagina$btnExportar' = 'Exportar')
  r_export <- httr::POST(url_export, body = dados_export)
  tmp <- tempfile()
  writeBin(httr::content(r_export), tmp)
  tab <- suppressWarnings(
    read.delim(tmp, fileEncoding = 'Unicode', stringsAsFactors = FALSE)
  )
  # trabalhar com a base
  if(nrow(tab) > 0) {
    tab <- tab %>%
      dplyr::tbl_df() %>%
      dplyr::select(cnpj=`CNPJ.emit.`, 
                    estabelecimento=`Emitente`, 
                    numero=`No.`, 
                    data_emissao=`Data.Emissão`,
                    valor_nf=`Valor.NF`, 
                    data_reg=`Data.Registro`, 
                    creditos=`Créditos`) %>%
      dplyr::filter(!is.na(valor_nf)) %>%
      dplyr::mutate(valor_nf = as.numeric(gsub(',', '.', gsub('\\.', '', valor_nf))),
                    creditos = ifelse(creditos %in% '-', NA, creditos),
                    creditos = as.numeric(gsub(',', '.', gsub('\\.', '', creditos))),
                    data_reg = as.Date(lubridate::dmy(data_reg)),
                    data_emissao = as.Date(lubridate::dmy(data_emissao))) %>%
      dplyr::arrange(data_emissao)
    return(tab)      
  } else {
    return(data.frame())
  }
}

pegar_viewstate <- function(r) {
  pegar_coisa(r, '#__VIEWSTATE')
}

pegar_eventval <- function(r) {
  pegar_coisa(r, '#__EVENTVALIDATION')
}

pegar_coisa <- function(r, x) {
  httr::content(r, 'text') %>%
    xml2::read_html() %>%
    rvest::html_node(x) %>%
    rvest::html_attr('value')
}

verificar_pagina_inicial <- function(r) {
  h <- httr::content(r, 'text')
  radio <- h %>% 
    xml2::read_html() %>% 
    rvest::html_nodes(xpath = '//*[@id="rblPeriodo"]//input[@type="radio"]')
  if(length(radio) > 0) {
    return(r)
  } else {
    dados_continuar <- list('__VIEWSTATE' = pegar_viewstate(r),
                            '__EVENTVALIDATION' = pegar_eventval(r),
                            'ctl00$ConteudoPagina$btnContinuar' = 'Continuar')
    r_new <- httr::POST('https://www.nfp.fazenda.sp.gov.br/Inicio.aspx',
                        body = dados_continuar)
    return(r_new)
  }
}
jtrecenti/NFP documentation built on May 20, 2019, 3:15 a.m.