Ir para conteúdo
Fórum Script Brasil
  • 0

Importação de Notas - PDF


Irroration

Pergunta

Pessoal,  

Preciso de algum método ou ferramenta que seja capaz de fazer uma importação parametrizada de  notas em PDF.

O Objetivo é importadas dados de notas ficais para Excel, Access, SQL, PHP

As notas tem um padrão e estou a procura de uma forma de importar isso.

Alguém conhece ou poderia me direcionar?

Grande Abraço.

Link para o comentário
Compartilhar em outros sites

1 resposta a esta questão

Posts Recomendados

  • 0

Todas as notas fiscais são feitas no formato XML. O Excel é um excelente aplicativo que consegue importar o XML no formato CSV e assim você consegue montar a memória de cálculo para diferença de alíquota de ICMS ou ICMS Substituição Tributária no caso das compras fora do estado de São Paulo.

Eu já uso o PHP que tem uma boa ferramenta para importar o XML para a memória do computador (eu já uso uma tabela provisória do MySQL), comparo o novo custo do produto com o velho e atualizo, e em seguida uso todas as informações para dar entrada no estoque.

Nem sempre o fornecedor manda o arquivo XML, nesse caso eu peço para o meu irmão tirar uma foto da chave do DANFE, e com essa chave eu vou no portal da Nota Fiscal Eletrônica e peço para fazer o download do arquivo (o portal só autoriza a consulta plena ou o download com o certificado digital da empresa que consta na Nota Fiscal Eletrônica).

Estamos em 2025, esse é um mundo totalmente diferente. No meu tempo, a gente ajuntava todas as notas para encaminhar para a contabilidade para fazer a escrituração, apuração e imprimir os livros fiscais. Hoje não. A Contabilidade tem um esquema que consegue puxar todos os xml com o CNJP do cliente. Não sei que mágica é essa, tudo o que sei é que existe uma empresa por trás disso, como eles conseguem fazer esse serviço, isso é um mistério para mim.

O que eu mando para a contabilidade são os xml que eu criei para vender.

Se você tem PHP, aqui está um código parcial que eu fiz (eu criei um query builder baseado no PDO->query()) e roteador bem simples que passa pelo arquivo index com a sintaxe ?classe.método.argumento):

 

arquivo nf.php
<?php

class NF {

    function atualiza() {
        $previa=(new Conn)->select("* from tbnf");
        extract($_SESSION['vetor']);
        return view('nfView',['previa'=>$previa,'nNF' => $nNF,'xNome' => $xNome,
            'codp' => $codp,'vNF' => $vNF,'difAliqICMS' => $difAliqICMS, 'soma'=>$soma,'st'=>$st]);
    }

    function CFOP() { return view('nfArquivo',['action'=>'?NF.CFOPselecionado']); }

    function CFOPatualizar() {
        $cfop = $_POST['cfop'];
        $codprod = $_POST['codprod'];
        (new Conn)->update("tbprod set cfop='$cfop' where codprod = $codprod");
    }

    function CFOPselecionado() {
        (new Conn)->delete("tbnf");
        (new Conn)->exec("alter table tbnf auto_increment = 1");
        $nfe=simplexml_load_file($_FILES['arquivo']['tmp_name']);
        $itens=$nfe->NFe->infNFe->det;
        $nNF = (float)$nfe->NFe->infNFe->ide->nNF;
        $xNome = (string)$nfe->NFe->infNFe->emit->xNome;
        $nome = explode(" ", $xNome)[0];        
        $codp = (new Conn)->select("codp from tbpessoa where pessoa like '%$nome%'")[0]->codp;
        foreach ($itens as $item){
            // no campo codforn uso a primeira letra para identificar o fornecedor
            $codforn = (string)$item->prod->cProd;
            $criterio= strtolower($nome[0].$codforn);
            $consulta = (new Conn)->select("* from tbprod where codforn like '%$criterio%' ");
            $codprod = 'null';
            if (count($consulta) == 1) {
                $codprod = $consulta[0]->codprod;
            } 
            if (count($consulta) > 1) {
                $consulta2 = (new Conn)->select("* from tbprod where codforn like '%$criterio' ");
                if(count($consulta2) == 1){
                    $codprod = $consulta2[0]->codprod;
                    $consulta = $consulta2;
                } else {
                    echo "existem vários produtos com codforn com o critério $criterio";
                    foreach($consulta as $c) {
                        echo "<br>".$c->codprod." ".$c->prod;
                    }
                    exit;
                }
            }
            if (count($consulta)==0) {
                echo "nenhum produto encontrado com o critério $criterio";
                exit;
            }
            $produto = substr((string)$item->prod->xProd,0,79);
            $cfop = (string)$item->prod->CFOP;
            if($cfop==6101 || $cfop==6102 || $cfop==5101) {
                $cfop=5102;
            }
            if($cfop==6401 || $cfop==6402 || $cfop==6403 || $cfop==5401) {
                $cfop=5405;
            } 
            $class=($cfop == $consulta[0]->cfop) ? "w-[50px] text-right" : 
                "w-[50px] text-red-500 text-right";
            $ncm = (string)$item->prod->NCM;
            $class2=($ncm == $consulta[0]->cf) ? "w-[100px] text-right" : 
                "w-[100px] text-red-500 text-right";
            (new Conn)->insert("tbnf (codforn,codprod,prod,cfop,codp,ncm,class,class2) 
                values ($codforn,$codprod,'$produto','$cfop',$codp,'$ncm','$class','$class2')");
        }
        $previa=(new Conn)->select("* from tbnf");
        return view('nfCFOPview',['previa'=>$previa,'nNF' => $nNF,'xNome' => $xNome,
            'codp' => $codp]);
    }

    function custo() {
        $custoAtual = $_POST['custoAtual'];
        $codprod = $_POST['codprod'];
        $margem=(new Conn)->select("marg from tbprod where codprod=$codprod")[0]->marg;
        $venda=pvenda($custoAtual,$margem);
        $class="class=text-end";
        (new Conn)->update("tbnf set custoanterior=$custoAtual, class='$class' where codprod=$codprod");
        (new Conn)->update("tbprod set custo=$custoAtual, 
            venda=$venda where codprod = $codprod");
    }
    

    function incluir() {
        $lcto=$_POST['lcto'];
        $verifica=count((new Conn)->select("* from tbhistprod where lcto=$lcto"));
        if($verifica){
            $mensagem="<h1>Nota já lançada. <a href=?NF.atualiza>Voltar</a></h1>";
            return view('mensagemView',['mensagem'=>$mensagem]);
        }
        $dia=(new Conn)->select("dia from tbdiario where lcto=$lcto")[0]->dia;
        $matriz=(new Conn)->select("* from tbnf");
        foreach($matriz as $vetor) {
            (new Conn)->insert("tbhistprod (codprod,dia,qt,custototal,codp,lcto)
                values ('$vetor->codprod','$dia',$vetor->qt,$vetor->custototal,$vetor->codp,$lcto)");
        }
        return header("location:?Diario.inicio.$dia");
    }

    function inicio() { return view('nfArquivo',['action'=>'?NF.selecionada']); }

    function qt() {
        $qt=$_POST['qt'];
        $id=$_POST['id'];
        $previa=(new Conn)->select("* from tbnf where id=$id")[0];
        $novoClass=$previa->class;
        $custoAtual=intval($previa->custototal/$qt*100)/100;
        if($custoAtual!==$previa->custoanterior) {
            $novoClass="class=\"text-danger text-end\"";
        }
        (new Conn)->update("tbnf set class='$novoClass', custoatual=$custoAtual,
            qt=$qt where id=$id");
        return $this->atualiza();
    }

    function selecionada() {
        (new Conn)->delete("tbnf");
        (new Conn)->exec("alter table tbnf auto_increment = 1");
        $nfe=simplexml_load_file($_FILES['arquivo']['tmp_name']);
        $itens=$nfe->NFe->infNFe->det;
        $difAliqICMS=0;
        $st=0;
        $aliquotaInterna=0.18;
        foreach ($itens as $item) {
            if ((float)$item->prod->CFOP == 6102 || (float)$item->prod->CFOP ==6101) {
                $vBC = (float)$item->imposto->ICMS->ICMS10->vBC;
                $vBC = $vBC ? $vBC : (float)$item->imposto->ICMS->ICMS00->vBC;
                $vICMS = (float)$item->imposto->ICMS->ICMS10->vICMS;
                $vICMS = $vICMS ? $vICMS : (float)$item->imposto->ICMS->ICMS00->vICMS;
                if((float)$item->prod->NCM == 40169300) {
                    $st += round($vBC*(1.4)*$aliquotaInterna-$vICMS+0.00001,2); // anel de vedação
                } else {
                    $difAliqICMS += round(($vBC * $aliquotaInterna - $vICMS+0.00001),2);
                }
            }
        }
        $vNF = (float)$nfe->NFe->infNFe->total->ICMSTot->vNF;
        $nNF = (float)$nfe->NFe->infNFe->ide->nNF;
        $xNome = (string)$nfe->NFe->infNFe->emit->xNome;
        $nome = explode(" ", $xNome)[0];        
        $codp = (new Conn)->select("codp from tbpessoa where pessoa like '%$nome%'")[0]->codp;
        $soma=0;
        foreach ($itens as $item){
            // no campo codforn uso a primeira letra para identificar o fornecedor
            $codforn = (string)$item->prod->cProd;
            $criterio= strtolower($nome[0].$codforn);
            $consulta = (new Conn)->select("* from tbprod where codforn like '%$criterio%' ");
            $codprod = 'null';
            if (count($consulta) == 1) {
                $codprod = $consulta[0]->codprod;
            } 
            if (count($consulta) > 1) {
                echo "existem vários produtos com codforn com o critério $criterio";
                foreach($consulta as $c) {
                    echo "<br>".$c->codprod." ".$c->prod;
                }
                exit;
            }
            if (count($consulta)==0) {
                echo "nenhum produto encontrado com o critério $criterio";
                exit;
            }
            $produto = substr((string)$item->prod->xProd,0,79);
            $quantidade = (string)$item->prod->qCom;
            if (is_numeric($codprod)) {
                $produtoDobrado = [506, 507, 508, 509, 510, 519, 1768, 1770, 1772];
                if (in_array($codprod, $produtoDobrado)) {
                    $quantidade = 2 * $quantidade;
                }
                $produtox5=[1798];
                if (in_array($codprod,$produtox5 )) {
                    $quantidade = 5 * $quantidade;
                }
                $produtoX10 = [2192, 2190,1782,2456];
                if (in_array($codprod, $produtoX10)) {
                    $quantidade = 10 * $quantidade;
                }
                $produtox12 = [2403,2406,2496,2497,2498,2499];
                if (in_array($codprod, $produtox12)) {
                    $quantidade = 12 * $quantidade;
                }
                $produtox24 = [2493,2405,2494,2495,2409];
                if (in_array($codprod, $produtox24)) {
                    $quantidade = 24 * $quantidade;
                }
            }
            $vICMSST1 = ((float)$item->imposto->ICMS->ICMS10->vICMSST) ?
                (float)$item->imposto->ICMS->ICMS10->vICMSST : null;
            $vICMSST2 = ((float)$item->imposto->ICMS->ICMSSN202->vICMSST) ?
                (float)$item->imposto->ICMS->ICMSSN202->vICMSST : null;
            $vICMSST = $vICMSST1 ? $vICMSST1 : $vICMSST2;
            $difAliq = 0;
            if ((float)$item->prod->CFOP == 6102 || (float)$item->prod->CFOP == 6101){
                $vBC = (float)$item->imposto->ICMS->ICMS10->vBC;
                $vBC = $vBC ? $vBC : (float)$item->imposto->ICMS->ICMS00->vBC;
                $vICMS = (float)$item->imposto->ICMS->ICMS10->vICMS;
                $vICMS = $vICMS ? $vICMS : (float)$item->imposto->ICMS->ICMS00->vICMS;
                if((float)$item->prod->NCM == 40169300) {
                    $difAliq = round($vBC * 1.4 * $aliquotaInterna -$vICMS+0.00001,2); // usando variável $difAliq como st
                } else {
                    $difAliq = round(($vBC * $aliquotaInterna - $vICMS+0.00001),2);
                }
            }
            $vIPI = (float)$item->imposto->IPI->IPITrib->vIPI ? 
                (float)$item->imposto->IPI->IPITrib->vIPI : 0;
            $vProd = (string)$item->prod->vProd;
            $valorTotal = $vProd + $vICMSST + $difAliq + $vIPI;
            $soma += $valorTotal;
            $class = "class=text-end";
            $custoAtual=0;
            $custoAnterior=0;
            if (is_numeric($codprod)) {
                $custoAtual = intval($valorTotal / $quantidade * 100) / 100;
                $consulta = (new Conn)->select("custo from tbprod where codprod=$codprod");
                $custoAnterior = $consulta[0]->custo;
                if (abs($custoAnterior - $custoAtual) > 0.02) {
                    $class = "class=\"text-end text-danger\"";
                }
            }
            $produto=str_replace("'","''",$produto);
            (new Conn)->insert("tbnf (codforn,codprod,prod,qt,custoatual,
                custoanterior,class,custototal,codp,cfop,class2) 
                values ('$codforn',$codprod,'$produto',$quantidade,$custoAtual,
                $custoAnterior,'$class',$valorTotal,$codp,'5405','text-right')");
        }
        $previa=(new Conn)->select("* from tbnf");
        $_SESSION['vetor']=['nNF' => $nNF,'xNome' => $xNome,
            'codp' => $codp,'vNF' => $vNF,'difAliqICMS' => $difAliqICMS, 'soma'=>$soma,'st'=>$st];
        return view('nfView',['previa'=>$previa,'nNF' => $nNF,'xNome' => $xNome,
            'codp' => $codp,'vNF' => $vNF,'difAliqICMS' => $difAliqICMS, 'soma'=>$soma,'st'=>$st]);
    }

    function verXML(){
        return view('nfArquivo',['action'=>'?NF.xml']);
    }

    function xml(){
        $nfe=simplexml_load_file($_FILES['arquivo']['tmp_name']);
        return imprime($nfe);
    }
}

arquivo nfArquivo.php
<?php require 'menuView.php' ?>
<script>btmenu.innerHTML="Nota do Fornecedor";document.title="Nota do Fornecedor"</script>
<div class=mb-3>
<form method=post enctype="multipart/form-data" action="<?=$action?>">
    <label for=arquivo class=form-label>Escolha o arquivo XML</label>
    <input type=file name=arquivo class=form-control id=formfile required onchange=submit()>
</form>
</div>

arquivo nfCFOPview.php
<?php include('menuView.php'); ?>
<script>
    btMenu.innerHTML='NF Fornecedor CFOP';document.title="NF Fornecedor CFOP"
    function getCsrfToken() { 
        return document.querySelector('meta[name="csrf-token"]').getAttribute('content'); 
    }
    function atualizar(cfop, codprod) {
        var xmlhttp = new XMLHttpRequest();
        var url = "nfCFOPatualizar";
        var formData = new FormData();
        formData.append('cfop', cfop);
        formData.append('codprod', codprod);
        formData.append('_token', getCsrfToken());
        xmlhttp.open("POST", url, true);
        
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {
                console.log("Estado da requisição: " + xmlhttp.readyState);
                if (xmlhttp.status == 200) {
                    location.reload();
                } else {
                    alert("Erro na requisição: " + xmlhttp.status);
                }
            }
        }; 
        xmlhttp.send(formData);
    }
</script>
<div class="flex">
    <div class="w-[50px] text-right">Cforn</div>
    <div class="w-[50px] text-right">Cod</div>
    <div class="w-[448px] ml-2">Produto</div>
    <div class="w-[50px] text-right">CFOP</div>
    <div class="w-[100px] text-right">NCM</div>
</div>
<?php foreach($previa as $p): ?>
    <div class="flex odd:bg-gray-200">
        <div class="w-[50px] text-right"><?=$p->codforn?></div>
        <div class="w-[50px] text-right"><?=$p->codprod?></div>
        <div class="w-[448px] ml-2 truncate"><?=$p->prod?></div>
        <div class="<?=$p->class?>" onclick="atualizar(<?=$p->cfop?>,<?=$p->codprod?>)">
            <?=$p->cfop?>
        </div>
        <div class="<?=$p->class2?>"><?=$p->ncm?></div>
    </div>
<?php endforeach; ?>

arquivo nfView.php
<?php include('menuView.php'); ?>
<script>
    btMenu.innerHTML='NF Fornecedor';document.title="NF Fornecedor"
    function atualizar(custoAtual, custoAnterior, codprod) {
    var confirma = confirm("Atualizar?\ncusto atual: " + custoAtual + "\ncusto anterior: " + custoAnterior);
    if (confirma) {
        var xmlhttp = new XMLHttpRequest();
        var url = "?NF.custo";
        var formData = new FormData();
        formData.append('custoAtual', custoAtual);
        formData.append('codprod', codprod);

        xmlhttp.open("POST", url, true);
        
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {
                console.log("Estado da requisição: " + xmlhttp.readyState);
                if (xmlhttp.status == 200) {
                    // console.log("Status da resposta: " + xmlhttp.status);
                    // alert("Resposta do servidor: " + xmlhttp.responseText);
                    location.replace("?NF.atualiza");
                } else {
                    alert("Erro na requisição: " + xmlhttp.status);
                }
            }
        }; 
        xmlhttp.send(formData);
      	
    }
}


</script>
<table class='table table-striped table-sm'>
<tr class=fw-semibold><td colspan=3>NF <?=$nNF." ".substr($xNome,0,10)." codp ".$codp?><td><td><td class=text-end><?=dec($vNF)?>
<?php if($difAliqICMS!==0 || $st!==0): ?>
    <tr class=fw-semibold><td><td><td>Diferença de Alíquota de ICMS<td><td><td class=text-end><?=dec($difAliqICMS)?>
    <tr class=fw-semibold><td><td><td>Substituição Tributária<td><td><td class=text-end><?=dec($st)?>
    <tr class=fw-semibold><td><td><td>Total a conferir<td><td><td class=text-end><?=dec($difAliqICMS+$vNF+$st)?>
<?php endif; ?>
</table>
<table class="table table-striped table-sm">
    <th style="max-width:50px">Cforn
    <th style="width:50px text-end">Cod
    <th style="width:330px">Produto
    <th class=text-end>Qt
    <th class=text-end>Custo
    <th class=text-end>Total
<?php foreach($previa as $p): ?>
    <tr><td style="max-width:80px" class=text-end><?=$p->codforn?>
        <td style="max-width:50px" class=text-end><?=$p->codprod?>
        <td style="max-width:330px" class="overflow-hidden" ><?=$p->prod?>
        <td>
            <form method=post action=?NF.qt>
                <input name=qt value='<?=$p->qt?>' class="inv text-end" size='1' onchange=submit()>
                <input type=hidden name=id value='<?=$p->id?>'>
            </form>
        <td <?=$p->class?> onclick="atualizar(<?=$p->custoatual?>,<?=$p->custoanterior?>,<?=$p->codprod?>)"><?=dec($p->custoatual)?>
        <td class=text-end><?=dec($p->custototal)?>
<?php endforeach; ?>
<tr class=fw-semibold><td><td><td>Total dos itens<td><td></td><td class=text-end><?=dec($soma)?>
</table>
<div>
Enviar tudo para o banco de dados
<form action=?NF.incluir method=post>
    <input name=lcto placeholder="Número do Lançamento" required>
    <input type=submit>
</form>
</div>

 

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652k
×
×
  • Criar Novo...