Pular para o conteúdo principal

DS_PATHAPKDOW — Caminho do APK do Pedido Mobile para Download

Tela de configuração: MFA001 — Parâmetros de Faturamento Localização: Parâmetros → aba Pedido Mobile → grupo Caminho do Apk Pedido Mobile Tabela: PARMFATUR.DS_PATHAPKDOW Tipo: Texto — caminho absoluto do arquivo .apk no servidor (VARCHAR(500), nullable) — TDBMemo ReadOnly preenchido via TOpenDialog Valor padrão: vazio/NULL (o campo não é preenchido no AfterInsert do dataset e o DDL não possui DEFAULT — ver UdmMFA001.pas e docs/schema/tables/PARMFATUR.sql)

Telas impactadas​

O parâmetro é apenas configurado na MFA001. Quem o consome em runtime é a API REST do Pedido Mobile (projeto Java ERPPedidoRestAS), responsável por servir o APK aos dispositivos Android via HTTP — a tela ERP Desktop não lê este campo em nenhum outro módulo além da própria MFA001.

Módulo / ComponenteCódigoPapel
Parâmetros de FaturamentoMFA001Tela produtora — grava o caminho absoluto do arquivo .apk
API REST Pedido Mobile — ParametroSmartDAOsource/Server/PedidoMobile/ERPPedidoRestASConsumidor — lê PARMFATUR.DS_PATHAPKDOW no SELECT do parâmetro e injeta em PathServidor.INSTANCE.setDsPath(...) durante a sincronização
API REST Pedido Mobile — DownloadResource (servlet /download/*)source/Server/PedidoMobile/ERPPedidoRestASConsumidor — abre new File(filePath), transmite os bytes do APK no response HTTP (Content-Disposition: attachment)

Observação — Homônimo: há um campo similar PARMFATUR.DS_PATHDOWNAPKCOLETALEITE (também editado na MFA001, na mesma aba), porém destinado ao APK de Coleta de Leite e consumido por outra API (CaptacaoMobile). Não confundir: DS_PATHAPKDOW é exclusivamente o APK do Pedido Mobile.

Procedures impactadas​

Não há procedures/views que referenciem DS_PATHAPKDOW. O campo é acessado apenas por SELECT direto no Java (ParametroSmartDAO.TEXTO_PARAMETROS).

Campos envolvidos​

CampoDescrição
PARMFATUR.DS_PATHAPKDOWEste parâmetro. Caminho absoluto (no servidor onde o WildFly está publicado) do arquivo .apk do Pedido Mobile — VARCHAR(500)
PARMFATUR.DS_PATHDOWNAPKCOLETALEITECampo irmão, na mesma aba da MFA001 — caminho do APK de Coleta de Leite (outra API)

Comportamento / Uso​

1. Configuração na MFA001 (aba Pedido Mobile)​

A aba possui um TGroupBox "Caminho do Apk Pedido Mobile" com:

  • mmDS_PATHAPKDOW: TDBMemo — somente-leitura (ReadOnly = True), MaxLength = 240, vinculado ao campo via DataField = 'DS_PATHAPKDOW'.
  • btnDS_PATHAPKDOW: TBitBtn — Caption "Selecione Caminho do APK Pedido Mobile", Hint "Abrir Arquivo" — chama TOpenDialog e grava o FileName escolhido no campo.

Código responsável pelo clique no botão (source/MFA001/UMFA001.pas linhas 1760-1771):

procedure TfrmMFA001.btnDS_PATHAPKDOWClick(Sender: TObject);
begin
AbrirArquivo.Filter := 'Aplicativos (*.apk)|*.APK';
AbrirArquivo.Title := 'Selecione o APk do Pedido Mobile';

dmMFA001.tabPARMFATUR.Edit;

if (AbrirArquivo.Execute) then
dmMFA001.tabPARMFATURDS_PATHAPKDOW.AsString := AbrirArquivo.FileName
else
dmMFA001.tabPARMFATURDS_PATHAPKDOW.AsString := '';
end;

Atenção: ao cancelar o TOpenDialog o campo é zerado (string vazia). Para preservar o caminho existente, o usuário deve evitar clicar no botão.

Simulação passo a passo​

  1. Copie o arquivo do APK do Pedido Mobile para o servidor onde a API ERPPedidoRestAS está publicada (mesmo host do WildFly), ex.: C:\Junsoft\Mobile\junsoftpedido.apk.
  2. Abra MFA001 → aba Pedido Mobile.
  3. Clique em Selecione Caminho do APK Pedido Mobile (btnDS_PATHAPKDOW).
  4. No filtro "Aplicativos (*.apk)", selecione o arquivo → o caminho completo é gravado em mmDS_PATHAPKDOW (somente-leitura, MaxLength=240).
  5. Salve (F6) — a PARMFATUR recebe UPDATE ... SET DS_PATHAPKDOW = :DS_PATHAPKDOW.

Resultado esperado: caminho absoluto armazenado em PARMFATUR.DS_PATHAPKDOW. No próximo login do app Pedido Mobile (ou ao acionar a opção de atualização), o APK passa a ser baixado por esse caminho.


2. Consumo pela API Pedido Mobile (ParametroSmartDAO + PathServidor)​

Durante a sincronização de parâmetros do dispositivo, o DAO lê o campo diretamente no SELECT e coloca o caminho em um enum singleton (PathServidor.INSTANCE):

source/Server/PedidoMobile/ERPPedidoRestAS/src/main/java/br/com/junsoft/DAO/ParametroSmartDAO.java — linhas 25 e 130:

// SELECT dos parâmetros:
+ " P.ST_VARIOSVENDEDORES, P.DS_PATHAPKDOW, P.CD_TABPRECO, "
...
// Após ler o ResultSet:
PathServidor.INSTANCE.setDsPath(rs.getString("DS_PATHAPKDOW"));

O singleton simplesmente guarda a string em memória (source/Server/PedidoMobile/ERPPedidoRestAS/src/main/java/br/com/junsoft/sincronizacao/PathServidor.java):

public enum PathServidor {
INSTANCE;
private String dsPath;
public String getDsPath() { return dsPath; }
public void setDsPath(String dsPath) {
if (dsPath != null) { this.dsPath = dsPath; }
}
}

Observação — estado global: PathServidor é um enum singleton JVM. O valor fica cacheado no WildFly até que um novo dispositivo se sincronize e sobrescreva (ou até o servidor ser reiniciado). Por isso, após alterar o parâmetro na MFA001, talvez seja necessário um novo login/sync de dispositivo para que o cache seja atualizado — ou o DownloadResource o recarrega na demanda (ver abaixo).


3. Download do APK (DownloadResource — servlet /download/*)​

Quando o app Android (ou qualquer cliente HTTP) chama GET /download/{idEmpresa}/{arquivo}, o servlet DownloadResource transmite o arquivo apontado por PARMFATUR.DS_PATHAPKDOW.

source/Server/PedidoMobile/ERPPedidoRestAS/src/main/java/br/com/junsoft/resources/DownloadResource.java — linhas 34-82:

if (PathServidor.INSTANCE.getDsPath() == null) {
try (Sessao sessao = ConnectionFactory.createSessao(Integer.parseInt(path[3]))) {
new ParametroSmartDAO().buscar(sessao, Integer.parseInt(path[3]));
} catch (Exception ex) {
...
}
}

String filePath = PathServidor.INSTANCE.getDsPath();

File downloadFile = new File(filePath);
FileInputStream inStream = new FileInputStream(downloadFile);

String mimeType = context.getMimeType(filePath);
if (mimeType == null) { mimeType = "application/octet-stream"; }

response.setContentType(mimeType);
response.setContentLength((int) downloadFile.length());
response.setHeader("Content-Disposition",
String.format("attachment; filename=\"%s\"", downloadFile.getName()));

OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}

Fluxo do servlet:

  1. Se PathServidor.getDsPath() ainda é null, o servlet força um ParametroSmartDAO.buscar(...) passando o IdEmpresa extraído do path (posição 3 do URI) — assim ele popula o cache sob demanda.
  2. Abre o arquivo em new File(filePath) e transmite os bytes ao cliente com Content-Disposition: attachment; filename="<nomeArquivo>".
  3. O MIME type é resolvido pelo ServletContext e faz fallback para application/octet-stream.

Simulação passo a passo (lado dispositivo)​

  1. Garanta que PARMFATUR.DS_PATHAPKDOW aponta para um arquivo existente no servidor (ex.: C:\Junsoft\Mobile\junsoftpedido.apk).
  2. No app Pedido Mobile, acione a opção de atualização/download do APK (ou acesse diretamente http://<servidor>:<porta>/ERPPedidoRest/download/<idEmpresa>/junsoftpedido.apk).
  3. A API abre o arquivo no caminho configurado e transmite os bytes como attachment.

Resultado esperado: o APK é enviado ao cliente com Content-Disposition: attachment (nome = último segmento do path). Se o caminho estiver em branco ou apontar para um arquivo inexistente, o new File(...)/FileInputStream lança FileNotFoundException, que sobe como 500 Internal Server Error ao cliente (log do WildFly) — o usuário final recebe falha no download.


Formato esperado​

RegraDetalhe
Tipo de dado (DDL)DS_PATHAPKDOW DOM_VARCHAR500 — coluna nullable, sem DEFAULT (ver docs/schema/tables/PARMFATUR.sql linha 208)
Tipo de dado (FireDAC)TStringField com Size = 500 em UdmMFA001.dfm linhas 1872-1876
Componente na telaTDBMemo ReadOnly (MaxLength = 240 — inconsistente com o Size=500 do banco, limita o usuário a 240 caracteres embora o banco aceite até 500)
Como é preenchidoClique em btnDS_PATHAPKDOW → TOpenDialog (filtro "Aplicativos (.apk)
Cancelar o diálogoApaga o caminho (grava string vazia). Para preservar, o usuário deve não clicar no botão
Caminho absoluto vs. relativoO TOpenDialog retorna caminho absoluto. O servlet DownloadResource passa o valor direto para new File(filePath) — precisa ser um caminho válido no servidor do WildFly/API, não na estação do cliente que salvou
Extensão esperadaFiltro do diálogo aceita apenas *.apk (case-insensitive). Tecnicamente o campo é texto livre — qualquer caminho pode ser gravado; o servlet apenas tenta abrir como arquivo
Validação no AfterPost/OnValidateNão há. O campo não possui evento OnValidate. Um caminho inválido só é detectado no download (HTTP 500 no servlet)
Cache em memória (JVM)PathServidor.INSTANCE (enum singleton) armazena a string e só é atualizada quando um novo ParametroSmartDAO.buscar(...) é executado (nova sincronização ou chamada ao DownloadResource quando dsPath == null). Após alterar o parâmetro na MFA001, considere reiniciar o WildFly ou sincronizar um dispositivo para forçar o refresh
AmbienteO caminho deve ser resolvível pelo processo Java do WildFly. Caminhos UNC (\\SERVIDOR\Share\app.apk) funcionam se o serviço tiver permissão de rede; caminhos locais (C:\...) precisam existir na própria máquina do servidor

Referências no Código Fonte​

Tela MFA001 (configuração)​

  • source/MFA001/UMFA001.dfm linhas 12078-12136 — aba pagPedidoMobile (Caption='Pedido Mobile'), grupo grpDS_PATHAPKDOW (Caption=' Caminho do Apk Pedido Mobile '), mmDS_PATHAPKDOW: TDBMemo (ReadOnly, MaxLength=240, DataField='DS_PATHAPKDOW'), btnDS_PATHAPKDOW: TBitBtn (Caption='Selecione Caminho do APK Pedido Mobile')
  • source/MFA001/UMFA001.pas linhas 502-504 — declaração de grpDS_PATHAPKDOW, mmDS_PATHAPKDOW, btnDS_PATHAPKDOW
  • source/MFA001/UMFA001.pas linha 756 — assinatura procedure btnDS_PATHAPKDOWClick(Sender: TObject);
  • source/MFA001/UMFA001.pas linhas 1760-1771 — btnDS_PATHAPKDOWClick: aplica filtro 'Aplicativos (*.apk)|*.APK', executa TOpenDialog e grava/limpa tabPARMFATURDS_PATHAPKDOW.AsString
  • source/MFA001/UdmMFA001.pas linha 265 — tabPARMFATURDS_PATHAPKDOW: TStringField
  • source/MFA001/UdmMFA001.pas linhas 434-606 — tabPARMFATURAfterInsert: o campo não é inicializado (valor padrão = vazio)
  • source/MFA001/UdmMFA001.dfm linhas 278, 1872-1876 (definição do campo Size=500), 2436, 2608 (INSERT), 2859 (UPDATE), 3158 (FetchRow) — CRUD do parâmetro

Consumidor — API REST Pedido Mobile (Java / WildFly)​

  • source/Server/PedidoMobile/ERPPedidoRestAS/src/main/java/br/com/junsoft/DAO/ParametroSmartDAO.java linha 25 — SELECT ... P.DS_PATHAPKDOW, ... em TEXTO_PARAMETROS
  • source/Server/PedidoMobile/ERPPedidoRestAS/src/main/java/br/com/junsoft/DAO/ParametroSmartDAO.java linha 130 — PathServidor.INSTANCE.setDsPath(rs.getString("DS_PATHAPKDOW"));
  • source/Server/PedidoMobile/ERPPedidoRestAS/src/main/java/br/com/junsoft/sincronizacao/PathServidor.java — enum singleton (INSTANCE) com dsPath/getDsPath/setDsPath (ignora null em setDsPath)
  • source/Server/PedidoMobile/ERPPedidoRestAS/src/main/java/br/com/junsoft/resources/DownloadResource.java linhas 25-82 — servlet @WebServlet("/download/*"), força reload do PathServidor quando null, transmite new File(filePath) como attachment

DDL da tabela​

  • docs/schema/tables/PARMFATUR.sql linha 208 — DS_PATHAPKDOW DOM_VARCHAR500, (nullable, sem DEFAULT)