Bem-vindo ao Projeto SATHub

This project is about SAT-CF-e which is a system for autorization and transmission of fiscal documents, developed by Finance Secretary of state of São Paulo, Brazil. This entire project, variables, methods and class names, as well as documentation, are written in brazilian portuguese.

Refer to the official web site for more information (in brazilian portuguese only).

Nota

This documentation is a work in progress

Nota

Esta documentação é um trabalho em andamento

Este projeto está relacionado à tecnologia SAT-CF-e para autorização e transmissão de documentos CF-e (Cupons Fiscais eletrônicos).

SATHub é um projeto open-source baseado em Flask e Flask-RESTful para prover uma API que possibilita que múltiplos pontos-de-venda (PDV) possam compartilhar um único equipamento SAT. Por se tratar de uma API RESTful, qualquer aplicação de ponto-de-venda pode invocar funções SAT, desde que seja capaz de fazer requisições HTTP simples.

Também fornece um frontend web leve para tornar possível o acesso às funções do equipamento SAT a partir de um navegador com suporte à HTML5.

Capturas de tela da aplicação SATHub.

Este projeto integra os projetos SATCFe e SATcomum para fornecer uma API RESTful. Se o seu projeto já for baseado no projeto SATCFe, basta configurar o acesso ao servidor SATHub e instanciar satcfe.ClienteSATHub ao invés de instanciar satcfe.ClienteSATLocal.

Projetos Relacionados

Este projeto é apenas uma parte de um total de cinco projetos que compõem uma solução compreensível para a tecnologia SAT-CF-e em linguagem Python, disponíveis para integração nas aplicações de ponto-de-venda. São eles:

  • Projeto SATComum

    Mantém o código que é compartilhado pelos outros projetos relacionados, tais como validação, formatação e valores constantes.

  • Projeto SATCFe

    Fornece acesso ao equipamento SAT diretamente ou através de uma API RESTful, quando o equipamento SAT é compartilhado com mais de um ponto-de-venda.

  • Projeto SATExtrato

    Impressão dos extratos do CF-e-SAT. Este projeto é capaz de imprimir extratos de documentos de venda ou de cancelamento diretamente a partir dos documentos XML que os representam. A impressão tem um alto grau de compatibilidade com mini-impressoras (conhecidas como impressoras não-fiscais) já que é baseada na tecnologia Epson© ESC/POS® através do projeto PyESCPOS.

  • Projeto PyESCPOS

    Implementa o suporte à tecnologia Epson© ESC/POS® compatível com a imensa maioria das mini-impressoras disponíveis no mercado.

Participe

Participe deste projeto ou de qualquer um dos projetos relacionados. Se você for capaz de contribuir com código, excelente! Faça um clone do repositório, modifique o que acha que deve e faça o pull-request. Teremos prazer em aceitar o seu código.

Se você não quer (ou não pode) programar, também pode contribuir com documentação. Ou ainda, se você vir algo errado ou achar que algo não está certo, conte pra gente.

Siga-nos no Github ou no Twitter.

Conteúdo

Ambiente de Desenvolvimento

Durante o desenvolvimento do seu aplicativo, ou durante o desenvolvimento do próprio projeto SATHub é OK executar a aplicação através do servidor HTTP embutido no Flask (na verdade, neste último caso é até desejável).

Executando em Linux

Em ambientes Linux, principalmente no Ubuntu e outras distribuições onde o interpretador Python está sempre presente, é simples. Basta criar um ambiente virtual, instalar os requisitos e executar runserver.py:

$ sudo apt-get install python-virtualenv virtualenvwrapper
$ mkvirtualenv sathub
(sathub) $ git clone https://github.com/base4sistemas/sathub.git
(sathub) $ cd sathub
(sathub) $ pip install -r requirements.txt
(sathub) $ python runserver.py

Instalando em Windows 8.1

Caso queira experimentar SATHub em Windows, o roteiro não é exatamente curto mas é bem simples. O primeiro passo é instalar o Python 2.7 e todas as demais dependências para que seja possível executar o servidor SATHub em modo de desenvolvimento.

  1. Baixe o arquivo MSI para sua arquitetura neste link. Procure o link Latest Python 2 Release e então localize o link para para o pacote Windows x86 MSI installer ou Windows x86-64 MSI installer se a arquitetura do seu sistema for 64 bits. Faça a instalação normalmente como qualquer outro pacote MSI, aceitando as opções pré-definidas.

  2. Para ter acesso aos binários, será preciso incluir o caminho em Path. Tecle Win+X e escolha a opção Sistema.

  3. No diálogo Sistema escolha a opção Configurações avançadas do sistema.

  4. No diálogo Propriedades do Sistema, guia Avançado, clique no botão Variáveis de Ambiente.

  5. Na lista de Variáveis do Sistema localize a variável Path, selecione-a e clique em Editar e inclua (não apague o valor já existente) o seguinte trecho no início do campo Valor:

    C:\Python27;C:\Python27\Scripts;
    

    Se você instalou o Python em um caminho diferente, adapte os valores.

  6. Abra o Windows PowerShell: mova o cursor para o canto superior direito, clique na opção Pesquisar e escreva powershell. A primeira opção encontrada deverá ser Windows PowerShell, clique nela.

  7. Digite o seguinte comando no terminal:

    PS C:\Users\User> python --version
    Python 2.7.10
    

    Se obtiver um erro, revise os passos.

Com o Python instalado será preciso instalar as dependências para execução do SATHub em modo de desenvolvimento. Ainda no Windows PowerShell:

PS C:\Users\User> pip install virtualenv
PS C:\Users\User> virtualenv sat
PS C:\Users\User> .\sat\Scripts\activate.ps1
(sat) PS C:\Users\User> pip install flask
(sat) PS C:\Users\User> pip install flask-restful
(sat) PS C:\Users\User> pip install unidecode
(sat) PS C:\Users\User> pip install requests
(sat) PS C:\Users\User> pip install satcomum
(sat) PS C:\Users\User> pip install satcfe

Faça o download dos fontes do projeto SATHub (ou clone o projeto se você possui o Git instalado) e descompacte o arquivo em um diretório de sua preferência, digamos C:\workdir.

(sat) PS C:\Users\User> cd \workdir\sathub-master\
(sat) PS C:\workdir\sathub-master> python runserver.py

Se lhe for apresentando o diálogo de restrição de acesso do Firewall do Windows, permita o acesso para o aplicativo. Você deverá ver uma saída como essa (aparentemente com informação duplicada, isso é normal em desenvolvimento):

SATHub versao 0.1
[-] Debug esta LIGADO
[-] Caminho para DLL: sat.dll
[-] Convencao de chamada para DLL: Windows "stdcall"
** DLL NAO ENCONTRADA **

 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
[-] Debug esta LIGADO
[-] Caminho para DLL: sat.dll
[-] Convencao de chamada para DLL: Windows "stdcall"
** DLL NAO ENCONTRADA **

Neste ponto o servidor está em execução, mas há um problema. Note a mensagem que diz DLL NAO ENCONTRADA. Interrompa o servidor teclando Ctrl+C. Note que após a primeira execução foi criado um arquivo chamado conf.json. Abra esse arquivo com um editor de textos e coloque o caminho completo para a DLL do seu equipamento SAT. O arquivo deverá ficar mais ou menos assim:

{
    "debug": true,
    "codigo_ativacao": "123456789",
    "convencao_chamada": 2,
    "caminho_dll": "C:/SAT/SAT.DLL"
}

Note que o caminho para a DLL é especificado usando barras no padrão Unix (/ forward slahes), mesmo no Windows, ao invés de usar contra-barras.

Se o seu código de ativação for diferente, altere-o também. A convenção de chamada 2 significa Windows Standard calls (ou apenas Windows StdCall). Se sua DLL usar a convenção de chamadas de C (Standard C calls) altere a propriedade convencao_chamada para 1.

Execute o servidor novamente com python runserver.py. Você deverá ver a seguinte saída.

SATHub versao 0.1
[-] Debug esta LIGADO
[-] Caminho para DLL: C:\SAT\SAT.DLL
[-] Convencao de chamada para DLL: Windows "stdcall"

 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
[-] Debug esta LIGADO
[-] Caminho para DLL: C:\SAT\SAT.DLL
[-] Convencao de chamada para DLL: Windows "stdcall"

Acessando a API via PowerShell

Neste ponto o servidor está em execução, o caminho para a DLL do equipamento SAT foi configurado e está tudo OK. Podemos então fazer algumas chamadas à API do SATHub para vê-lo em ação. Abra outra janela do PowerShell e digite:

PS C:\Users\User> Invoke-RestMethod -Uri http://localhost:5000/hub/v1/consultarsat -Method POST -Body "numero_caixa=1"

Na janela do terminal PowerShell em que o servidor está em execução você verá o acesso à URI, o método de acesso e o código de resposta, 200 OK, entre outras informações:

127.0.0.1 - - [20/Jun/2015 10:25:48] "POST /hub/v1/consultarsat HTTP/1.1" 200 -

No terminal em que o comando Invoke-RestMethod foi executado você terá o seguinte resultado (se tudo correr bem):

funcao                    retorno
------                    -------
ConsultarSAT              101341|08000|SAT em operação||

O equivalente em um terminal Linux, usando curl, é o seguinte (acessando a máquina Windows 8.1 em que o SATHub está executando, como no exemplo acima):

$ curl --data "numero_caixa=1" http://10.0.0.115:5000/hub/v1/consultarsat
{
    "funcao": "ConsultarSAT",
    "retorno": "101363|08000|SAT em opera\u00e7\u00e3o||"
}

Se você tiver outras máquinas Windows em uma rede local, ou estiver usando máquinas virtuais, você poderá acessar um único equipamento SAT a partir de qualquer uma delas.

Acessando a API em C#

Os exemplos abaixo mostram como é simples acessar a API RESTful de SATHub através de outras linguagens muito comumente usadas neste campo de aplicações. Neste exemplo, usando C# (testado com MonoDevelop):

// (!) baseado em http://stackoverflow.com/a/4015346/550237
using System;
using System.Collections.Specialized;
using System.Net;
using System.Text;

public class ExemploSATHub
{
    static public void Main()
    {
        Console.WriteLine(ConsultarSAT());
    }

    private static string ConsultarSAT()
    {
        var payload = new NameValueCollection();
        payload["numero_caixa"] = "1";

        var client = new WebClient();
        var response = client.UploadValues(
                "http://10.0.0.115:5000/hub/v1/consultarsat", payload);

        return Encoding.Default.GetString(response);
    }
}

O resultado é o seguinte:

$ msc exemplo.cs
$ mono exemplo.exe
{
    "funcao": "ConsultarSAT",
    "retorno": "100914|08000|SAT em opera\u00e7\u00e3o||"
}

Executando smoke tests

Certas funções SAT são difíceis de serem executadas contra um equipamento SAT real ou até mesmo contra o emulador desenvolvido pela Secretária da Fazenda, como por exemplo, AtualizarSoftwareSAT ou CancelarUltimaVenda. Por esse motivo foi desenvolvido um mockup da biblioteca SAT, que implementa todas as funções que a biblioteca SAT implementa, mas não acessa nenhum equipamento. As funções apenas recebem os parâmetros esperados e devolvem uma resposta muito parecida com uma resposta de sucesso. Desse modo, o mockup da biblioteca SAT torna trivial executar testes simples para verificar o comportamento da API.

Para executar os smoke tests será necessário compilar o mockup da biblioteca SAT que está em sathub/test/mockup/. Você irá precisar de um compilador GCC ou outro capaz de compilar o código. Tipicamente, em um ambiente Linux, basta invocar make para produzir o arquivo libmockupsat.so.

Configure o SATHub apontando para o mockup da biblioteca SAT (normalmente, a convenção de chamada será Standard C, equivalente a 1):

{
    "debug": true,
    "codigo_ativacao": "123456789",
    "convencao_chamada": 1,
    "caminho_dll": "~/sathub/test/mockup/libmockupsat.so"
}

Para executar os testes é necessário instalar o framework para testes de APIs RESTful PyRestTest e suas dependências:

(sat)$ pip install pyresttest pyyaml pycurl jsonschema

Abra uma janela de terminal e execute o servidor SATHub:

(sat)$ python runserver.py

Abra uma outra janela do terminal e vá até o diretório onde está o arquivo YAML que descreve os testes e execute-os com PyRestTest:

(sat)$ cd ~/sathub/test/tests
(sat)$ resttest.py http://localhost:5000 smoke.yaml
Test Group Metodos SAT-CF-e SUCCEEDED: 14/14 Tests Passed!

Considerações

Via de regra, é recomendado que se mantenha um olho na legislação vigente a respeito da tecnologia SAT-CF-e e das implicações dessa legislação na tecnologia de suporte empregrada. Atualmente não há nada regulamentando o acesso compartilhado ao equipamento SAT. Tudo o que se tem é que essa possibilidade tem sido aventada desde os primórdios do projeto.

Sendo assim, apenas use o bom senso ao compartilhar o acesso ao equipamento SAT e evite compartilhar muitos pontos-de-venda em único equipamento. Considere balancear o número de pontos-de-venda e tenha sempre uma folga para redirecionar em caso de pane em um equipamento, por exemplo.

Instalação em Produção

Em um ambiente de produção, onde 2 ou mais pontos-de-venda compartilham pelo menos um equipamento SAT, a instalação requer um servidor HTTP mais robusto do que o servidor de testes que acompanha o Flask. A maneira mais simples de prover o compartilhamento do equipamento SAT parte de um PC comum que irá atuar como um host Ubuntu Linux 14.04 server e um equipamento SAT conectado à ele.

Nota

Você deverá instalar as bibliotecas para Linux fornecidas pelo fabricante do seu equipamento SAT. Normalmente este processo significa apenas copiar os arquivos e dependências em um local específico, onde a aplicação SATHub terá permissão de leitura.

Neste exemplo, consideramos que a biblioteca e suas dependências estão disponíveis em /opt/tanca/, e que o host tem uma arquitetura de 64 bit, embora isso não tenha qualquer relevância prática.

O artigo de referência para este tópico é o excelente Kickstarting Flask disponível no Blog Real Python.

Recomendamos que você faça um teste antes em uma máquina VirtualBox, instalando uma imagem ISO do Ubuntu Linux 14.04 server, configurando a placa de rede da máquina virtual para o modo Bridge. Durante a instalação do sistema, defina o nome da máquina virtual como sathub1 e o usuário como sathub. Quando a instalação terminar, a máquina virtual será reiniciada. Faça o login e verifique o endereço IP que foi atribuído para a interface eth0, com o comando ifconfig (por exemplo 10.0.0.107).

Os comandos a seguir deverão ser digitados no terminal da máquina virtual:

$ sudo apt-get install -y python-dev python-pip nginx gunicorn git supervisor
$ sudo mkdir /home/www && cd /home/www
$ sudo git clone https://github.com/base4sistemas/sathub.git
$ cd sathub

Agora que o projeto SATHub já está instalado, é preciso configurá-lo, indicando o caminho completo para a biblioteca SAT e, principalmente, o usuário e a senha para acesso às funções SAT através do frontend web. Você não vai querer que qualquer pessoa com acesso ao servidor SATHub seja capaz de trocar o código de ativação do equipamento, ou bloqueá-lo, por exemplo.

$ sudo vim conf.json
{
    "debug": false,
    "caminho_dll": "/opt/tanca/libsat64.so",
    "convencao_chamada": 1,
    "codigo_ativacao": "12345678",
    "usuario": "sathub",
    "senha": "sathub"
}

Note que a convenção de chamada 1 significa Standard C. Use 2 se a convenção de chamada for Windows “stdcall”. Em produção debug deverá ser sempre false.

Agora é preciso instalar as dependências do SATHub:

$ sudo pip install -r requirements.txt

Para configuração do Nginx (servidor HTTP), iremos iniciá-lo e depois remover suas configurações padrão, para substituirmos pela nossa configuração:

$ sudo /etc/init.d/nginx start
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo touch /etc/nginx/sites-available/sathub
$ sudo ln -s /etc/nginx/sites-available/sathub /etc/nginx/sites-enabled/sathub
$ sudo vim /etc/nginx/sites-enabled/sathub

As configurações do Nginx para o SATHub são:

server {
    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location /static {
        alias  /home/www/sathub/sathub/static/;
    }
}

Renicie o servidor Nginx e inicie servidor de aplicações gunicorn:

$ sudo /etc/init.d/nginx restart
$ cd /home/www/sathub
$ sudo gunicorn sathub:app -b localhost:8000

Abra um navegador na máquina hospedeira e acesse o IP da máquina virtual. Você deverá ver a página inicial do SATHub.

Página inicial do front-end web

Faça login na página com o nome de usuário e senha que você configurou, acesse a opção Consultar SAT, e clique no botão Configurações, para que você possa conferir o status das configurações do SATHub, como na imagem abaixo:

Trecho da interface em que as configurações podem ser conferidas

Agora, para garantir que o servidor de aplicações seja iniciado quando a máquina reiniciar, vamos instalar o controlador de processos Supervisor. Se o servidor de aplicações ainda estiver executando, interrompa-o (se o comando gunicorn prendeu o seu terminal, termine ele com Ctrl-C):

$ sudo pkill gunicorn

Vamos configurar o controlador de processos para iniciar a aplicação SATHub:

$ sudo vim /etc/supervidor/conf.d/sathub.conf

Digite o seguinte:

[program:sathub]
command = gunicorn sathub:app -b localhost:8000
directory = /home/www/sathub
user = root

E então reinicie e atualize o controlador de processos:

$ sudo supervisorctl reread
$ sudo supervisorctl update
$ sudo supervisorctl start sathub

Este é o procedimento mais simples para colocar o projeto SATHub em operação, garantindo o compartilhamento do equipamento SAT para mais de um ponto-de-venda.

Se você tiver algum problema ao seguir estas instruções, a web está repleta de recursos sobre o stack de software citados neste guia. De qualquer maneira temos um canal via Gitter Chat onde você pode procurar por ajuda.