Pular para o conteúdo principal

RLA001 — Relação Analítica/Sintética de Análises

Fonte​

  • Form: source/RLA001/URLA001.pas
  • DFM: source/RLA001/URLA001.dfm
  • DataModule: source/RLA001/UdmRLA001.pas
  • DFM DataModule: source/RLA001/UdmRLA001.dfm
  • Package: source/RLA001/RLA001.dpk

Objetivo​

Emite o relatório de análises laboratoriais de leite dos produtores, em dois modelos (analítico por dia ou sintético com média por produtor), restrito por empresa, competências, produtores, contratos e veículos de coleta. Cruza ANALISELEITE com MOVTOLEITE (movimento de coleta) e CONTRATOLEITE (contrato do produtor) para trazer nome do produtor, endereço, contrato e descrição/valor formatado de cada análise (via procedure FORMATA_ANALISE para dados do tipo Hora e Categoria).

Modelos de Relatorio​

O combobox "Modelo de Relatório" (cmbTP_RELATORIO, MapList) oferece duas opções, mapeadas para A (analítico) e M (sintético/média). O SQL é montado dinamicamente em imprimeRelatorio conforme o valor selecionado. O nome do layout de impressão também muda por modelo (RLA001_A ou RLA001_S) — são dois templates .rtm distintos registrados no repositório de layouts.

Modelo 1: Listagem Analítica de Análises​

Quando usado: item "Listagem Analítica de Análises" do combobox (valor A, ItemIndex = 0 — default).

Lista analítica (linha-a-linha) de cada análise laboratorial feita em cada coleta. Mostra data da coleta (ML.DT_MOVTOLEITE), contrato do produtor, endereço/município/UF do produtor, análise e valor apurado formatado via FORMATA_ANALISE (trata tipos Hora e Categoria). Útil para auditar individualmente os resultados de cada recebimento.

Layout: RLA001_A

SQL Base:

SELECT CL.NR_CONTRATO,
PESSOA.NM_PESSOA,
EP.DS_ENDERECO || ' / ' || MUNICIPIO.DS_MUNICIPIO || ' - ' || MUNICIPIO.SG_ESTADO DS_ENDERECO,
AL.CD_ANALISE,
ANALISE.DS_ANALISE,
(SELECT OVL_APURADO FROM FORMATA_ANALISE(AL.CD_ANALISE, AL.VL_APURADO)) VL_APURADO,
ML.DT_MOVTOLEITE,
PF.DS_LOGOTIPO,
EMP.NM_EMPRESA,
COALESCE(EDP.DS_ENDERECO, '') DS_ENDERECOEMP,
MCP.DS_MUNICIPIO DS_MUNICIPIOEMP,
COALESCE(PE.DS_EMAIL, '') DS_EMAILEMP,
COALESCE(EDP.NR_FONE, '') NR_FONEEMP
FROM ANALISELEITE AL
INNER JOIN ANALISE ON (ANALISE.CD_ANALISE = AL.CD_ANALISE)
INNER JOIN MOVTOLEITE ML ON (ML.CD_EMPRESA = AL.CD_EMPRESA
AND ML.NR_MOVTOLEITE = AL.NR_MOVTOLEITE)
INNER JOIN CONTRATOLEITE CL ON (CL.CD_EMPRESA = ML.CD_EMPRCONTRATO
AND CL.NR_CONTRATO = ML.NR_CONTRATO)
INNER JOIN PESSOA ON (PESSOA.CD_PESSOA = CL.CD_PESSOA)
INNER JOIN ENDERECOPESSOA EP ON (EP.CD_PESSOA = CL.CD_PESSOA
AND EP.CD_ENDERECO = CL.CD_ENDERECO)
INNER JOIN MUNICIPIO ON (MUNICIPIO.CD_MUNICIPIO = EP.CD_MUNICIPIO)
INNER JOIN PARMFATUR PF ON (PF.CD_EMPRESA = :CD_EMPRESA_SESSAO) -- logotipo do relatório
-- bloco "dados da empresa emissora":
INNER JOIN EMPRESA EMP ON (EMP.CD_EMPRESA = AL.CD_EMPRESA)
INNER JOIN PESSOA PE ON (PE.CD_PESSOA = EMP.CD_PESSOA)
INNER JOIN ENDERECOPESSOA EDP ON (EDP.CD_PESSOA = PE.CD_PESSOA
AND EDP.CD_ENDERECO = (SELECT MIN(CD_ENDERECO)
FROM ENDERECOPESSOA
WHERE CD_PESSOA = PE.CD_PESSOA))
INNER JOIN MUNICIPIO MCP ON (MCP.CD_MUNICIPIO = EDP.CD_MUNICIPIO)
WHERE ML.ST_MOVTOLEITE <> 'C' -- exclui coletas canceladas
AND ML.TP_MOVTOLEITE = 'C' -- apenas movimento tipo Coleta
AND CL.CD_EMPRESA = :CD_EMPRESA
{AND CL.DT_COMPETENCIA IN (...)} -- filtro grid "Competências"
{AND CL.CD_PESSOA IN (...)} -- filtro grid "Produtores de Leite"
{AND ML.NR_PLACA IN (...)} -- filtro grid "Veículos"
{AND CL.NR_CONTRATO IN (...)} -- filtro grid "Contratos"
ORDER BY PESSOA.NM_PESSOA, CL.NR_CONTRATO, ML.DT_MOVTOLEITE

Modelo 2: Listagem Sintética de Análises (Média)​

Quando usado: item "Listagem Sintética de Análises (Média)" do combobox (valor M, ItemIndex = 1).

Consolidado por produtor × análise dentro do período/filtros, com média dos valores apurados. Montado como UNION ALL de dois blocos: o primeiro agrega analitícamente via AVG apenas analises de tipo numérico/inteiro (ANALISE.TP_DADO IN ('N','I')); o segundo agrega tipos Hora/Categoria (TP_DADO IN ('H','C')) reutilizando FORMATA_ANALISE para formatar o valor representativo. O GROUP BY é por produtor + análise + endereço. Útil para visão gerencial do desempenho médio de cada produtor.

Regra específica deste modelo: o filtro de Veículos é ignorado neste modelo (cmbTP_RELATORIO.ItemIndex <> 1), pois a média é por produtor e não por veículo de coleta.

Layout: RLA001_S

SQL Base:

/* Bloco 1 — tipos numérico/inteiro: faz a média AVG */
SELECT PESSOA.NM_PESSOA,
EP.DS_ENDERECO || ' / ' || MUNICIPIO.DS_MUNICIPIO || ' - ' || MUNICIPIO.SG_ESTADO DS_ENDERECO,
AL.CD_ANALISE,
ANALISE.DS_ANALISE,
CAST(AVG(CAST(AL.VL_APURADO AS NUMERIC(15,3))) AS VARCHAR(60)) VL_APURADO,
PESSOA.CD_PESSOA,
PF.DS_LOGOTIPO, EMP.NM_EMPRESA,
EDP.DS_ENDERECO DS_ENDERECOEMP, MCP.DS_MUNICIPIO DS_MUNICIPIOEMP,
COALESCE(PE.DS_EMAIL, '') DS_EMAILEMP,
COALESCE(EDP.NR_FONE, '') NR_FONEEMP
FROM ANALISELEITE AL
INNER JOIN ANALISE ON (ANALISE.CD_ANALISE = AL.CD_ANALISE)
INNER JOIN MOVTOLEITE ML ON (ML.CD_EMPRESA = AL.CD_EMPRESA
AND ML.NR_MOVTOLEITE = AL.NR_MOVTOLEITE)
INNER JOIN CONTRATOLEITE CL ON (CL.CD_EMPRESA = ML.CD_EMPRCONTRATO
AND CL.NR_CONTRATO = ML.NR_CONTRATO)
INNER JOIN PESSOA ON (PESSOA.CD_PESSOA = CL.CD_PESSOA)
INNER JOIN ENDERECOPESSOA EP ON (EP.CD_PESSOA = CL.CD_PESSOA
AND EP.CD_ENDERECO = CL.CD_ENDERECO)
INNER JOIN MUNICIPIO ON (MUNICIPIO.CD_MUNICIPIO = EP.CD_MUNICIPIO)
INNER JOIN PARMFATUR PF ON (PF.CD_EMPRESA = :CD_EMPRESA_SESSAO)
INNER JOIN EMPRESA EMP ON (EMP.CD_EMPRESA = AL.CD_EMPRESA)
INNER JOIN PESSOA PE ON (PE.CD_PESSOA = EMP.CD_PESSOA)
INNER JOIN ENDERECOPESSOA EDP ON (EDP.CD_PESSOA = PE.CD_PESSOA
AND EDP.CD_ENDERECO = (SELECT MIN(CD_ENDERECO)
FROM ENDERECOPESSOA
WHERE CD_PESSOA = PE.CD_PESSOA))
INNER JOIN MUNICIPIO MCP ON (MCP.CD_MUNICIPIO = EDP.CD_MUNICIPIO)
WHERE ML.ST_MOVTOLEITE <> 'C'
AND ML.TP_MOVTOLEITE = 'C'
AND ANALISE.TP_DADO IN ('N','I') -- Numérico, Inteiro
AND CL.CD_EMPRESA = :CD_EMPRESA
{AND CL.DT_COMPETENCIA IN (...)}
{AND CL.CD_PESSOA IN (...)}
{AND CL.NR_CONTRATO IN (...)} -- filtro de Veículos NÃO é aplicado neste modelo
GROUP BY PESSOA.NM_PESSOA, EP.DS_ENDERECO, MUNICIPIO.DS_MUNICIPIO, MUNICIPIO.SG_ESTADO,
AL.CD_ANALISE, ANALISE.DS_ANALISE, AL.VL_APURADO,
PESSOA.CD_PESSOA, PF.DS_LOGOTIPO, EMP.NM_EMPRESA,
EDP.DS_ENDERECO, MCP.DS_MUNICIPIO, PE.DS_EMAIL, EDP.NR_FONE

UNION ALL

/* Bloco 2 — tipos Hora/Categoria: usa FORMATA_ANALISE como representativo */
SELECT PESSOA.NM_PESSOA,
EP.DS_ENDERECO || ' / ' || MUNICIPIO.DS_MUNICIPIO || ' - ' || MUNICIPIO.SG_ESTADO DS_ENDERECO,
AL.CD_ANALISE,
ANALISE.DS_ANALISE,
CAST((SELECT OVL_APURADO FROM FORMATA_ANALISE(AL.CD_ANALISE, AL.VL_APURADO)) AS VARCHAR(60)) VL_APURADO,
PESSOA.CD_PESSOA,
PF.DS_LOGOTIPO, EMP.NM_EMPRESA,
EDP.DS_ENDERECO DS_ENDERECOEMP, MCP.DS_MUNICIPIO DS_MUNICIPIOEMP,
COALESCE(PE.DS_EMAIL, '') DS_EMAILEMP,
COALESCE(EDP.NR_FONE, '') NR_FONEEMP
FROM ANALISELEITE AL
-- (mesmos JOINs do Bloco 1)
WHERE ML.ST_MOVTOLEITE <> 'C'
AND ML.TP_MOVTOLEITE = 'C'
AND ANALISE.TP_DADO IN ('H','C') -- Hora, Categoria
AND CL.CD_EMPRESA = :CD_EMPRESA
{AND CL.DT_COMPETENCIA IN (...)}
{AND CL.CD_PESSOA IN (...)}
{AND CL.NR_CONTRATO IN (...)}
GROUP BY PESSOA.NM_PESSOA, EP.DS_ENDERECO, MUNICIPIO.DS_MUNICIPIO, MUNICIPIO.SG_ESTADO,
AL.CD_ANALISE, ANALISE.DS_ANALISE, AL.VL_APURADO,
PESSOA.CD_PESSOA, PF.DS_LOGOTIPO, EMP.NM_EMPRESA,
EDP.DS_ENDERECO, MCP.DS_MUNICIPIO, PE.DS_EMAIL, EDP.NR_FONE

A impressão é delegada a GeraRelatorio(transaction, nm_relatorio, Consulta) do jReport, que carrega o layout externo registrado (RLA001_A ou RLA001_S).

Filtros​

Campos simples:

  • Empresa (F9 — lista EMPRESAUSUARIO) — default = empresa da sessão; validação via dsFiltroCD_EMPRESAValidate verifica se o usuário tem acesso (USUARIOEMPRESA). Obrigatório — se não informado, imprimeRelatorio lança E-0000 "A empresa deve ser informada".
  • Modelo de Relatório (combo) — "Listagem Analítica de Análises" (A, default) / "Listagem Sintética de Análises (Média)" (M). Define o SQL e o layout .rtm (RLA001_A ou RLA001_S).

Filtros de grid (multi-selecao via F9):

  • Produtores de Leite (F9 — lista PRODUTORLEITE) — multi-seleção; filtra por CL.CD_PESSOA IN (...). Validação dsPessoaCD_PESSOAValidate exige produtor ativo (PRODUTORLEITE.ST_ATIVO = 'S').
  • Contratos (F9 — lista CONTRATO) — multi-seleção; filtra por CL.NR_CONTRATO IN (...).
  • Competências (F9 — lista COMPETENCIACONTRATO) — multi-seleção; filtra por CL.DT_COMPETENCIA IN ('YYYYMM', ...). Valores concatenados via Nulo(..., 'S') (quoted).
  • Veículos (F9 — lista VEICULOCAPTACAO) — multi-seleção; filtra por ML.NR_PLACA IN (...). Validação (dsVeiculoCalcFields) exige placa cadastrada em VEICULO e associada a ROTACAPTACAO. Ignorado no modelo Sintético (média por produtor).

Tecla F4/F5 limpam a tela (reinicia transação e esvazia todos os grids). F8 aciona a impressão. F12 fecha o módulo.

Parametros que Influenciam​

TabelaCampoEfeito
PARMFATURDS_LOGOTIPOLogotipo impresso no cabeçalho do relatório (carregado via JOIN com PF.CD_EMPRESA = sessao.empresa.cd_empresa).
USUARIOEMPRESACD_USUARIO, CD_EMPRESARestringe a empresa selecionada na validação (dsFiltroCD_EMPRESAValidate) — só aceita empresas atreladas ao usuário da sessão.

O relatório não lê PARMCAPT/PARMLEITE/similares para decidir SQL ou layout.

Regras de Negocio​

  1. Apenas coletas efetivas — o SQL filtra ML.ST_MOVTOLEITE <> 'C' e ML.TP_MOVTOLEITE = 'C', ignorando lançamentos cancelados e movimentos que não sejam de coleta.
  2. Empresa obrigatória — imprimeRelatorio força o Post do dsFiltro e aborta com E-0000 se CD_EMPRESA estiver nulo.
  3. Validação de acesso por empresa — o lookup da empresa filtra por USUARIOEMPRESA do usuário da sessão, impedindo selecionar empresa fora do escopo do login.
  4. Produtor precisa estar ativo — a validação do campo CD_PESSOA no grid de produtores rejeita produtores inativos (PRODUTORLEITE.ST_ATIVO = 'S' no lookup).
  5. Veículo precisa estar em rota — o validate do NR_PLACA exige que o veículo exista em VEICULO e possua vínculo em ROTACAPTACAO; caso contrário lança E-0000 mencionando a placa.
  6. Modelo sintético ignora veículo — o filtro de grid "Veículos" não é aplicado quando o modelo selecionado é o de média (item M), pois a agregação é por produtor.
  7. Modelo sintético separa tipos de dado — a média aritmética (AVG) só é calculada para análises com TP_DADO IN ('N','I'); análises de Hora/Categoria (TP_DADO IN ('H','C')) entram via UNION ALL no segundo bloco, usando FORMATA_ANALISE para formatar o valor representativo.
  8. Linhas em branco dos grids são descartadas no OnExit — cada gridXxxExit remove a linha corrente se o campo-chave estiver vazio, evitando cláusulas IN ('') malformadas.
  9. Filtro de competência em formato string — as competências são concatenadas como literais (Nulo(..., 'S')), portanto DT_COMPETENCIA é tratado como texto no SQL (formato armazenado: YYYYMM).
  10. Dois layouts distintos — o nm_relatorio muda conforme o modelo (RLA001_A vs RLA001_S), então cada modelo tem template .rtm próprio registrado no repositório de layouts.

Mensagens exibidas​

Levantadas de source/RLA001/ pela camada 0 (commit 96fc51e236).

Mais 4 mensagens com texto literal no código: RLA001.

Datasets e SQL​

DatasetTipoDescricao
dsFiltroTClientDataSetFiltros principais (CD_EMPRESA, NM_EMPRESA). Validate dispara lookup de empresa via USUARIOEMPRESA.
dsPessoaTClientDataSetGrid "Produtores de Leite" (CD_PESSOA, NM_PESSOA). Validate consulta PESSOA × PRODUTORLEITE ATIVO='S'.
dsContratoTClientDataSetGrid "Contratos" (NR_CONTRATO). Lookup F9 lista CONTRATO.
dsCompetenciaTClientDataSetGrid "Competências" (DT_COMPETENCIA string). Lookup F9 lista COMPETENCIACONTRATO.
dsVeiculoTClientDataSetGrid "Veículos" (NR_PLACA, DS_VEICULO). CalcFields/Validate chamam DESCRICAO_VEICULO(NR_PLACA) e exigem vínculo em ROTACAPTACAO.

Todos os datasets são in-memory (TClientDataSet), populados apenas via F9 — o relatório não persiste nada.

Perguntas Frequentes​

P: Para que serve a tela RLA001? R: A tela RLA001 é utilizada para gerar relatórios de análises de qualidade do leite, com opções de listagem analítica e sintética (média). Permite filtrar por empresa, produtores de leite, contratos, competências e veículos de coleta.

P: "A empresa deve ser informada" R: O campo Empresa é obrigatório para impressão. Preencha o código da empresa ou utilize F9 para buscar as empresas disponíveis.

P: "A Empresa não está cadastrada!" R: O código de empresa informado não existe ou seu usuário não possui acesso a esta empresa. Utilize F9 para buscar empresas disponíveis ou verifique o acesso na tela ADM002.

P: "A pessoa não está cadastrada!" R: O código informado no grid de Produtores de Leite não corresponde a um produtor de leite ativo. Verifique se a pessoa está registrada como produtor de leite ativo no sistema. Utilize F9 para buscar produtores disponíveis.

P: "O veículo com a placa [PLACA] não está cadastrado, ou não está associado a uma rota de captação!" R: O veículo informado não existe no cadastro ou não está vinculado a nenhuma rota de captação. Verifique o registro do veículo e a associação com rotas de captação nas telas de manutenção correspondentes.

Tabelas de Escrita (INSERT/UPDATE/DELETE)​

Nenhuma — tela é consumer only (apenas SELECT para montagem do relatório).

Tabelas de Leitura (SELECT)​

TabelaOperacoes
ANALISESELECT
ANALISELEITESELECT
CONTRATOLEITESELECT
EMPRESASELECT
ENDERECOPESSOASELECT
MOVTOLEITESELECT
MUNICIPIOSELECT
PARMFATURSELECT
PESSOASELECT
PRODUTORLEITESELECT
ROTACAPTACAOSELECT
USUARIOEMPRESASELECT
VEICULOSELECT

Procedures Chamadas​

ProcedureTabelas Acessadas
FORMATA_ANALISEANALISE (SELECT), RESULTADOANALISE (SELECT)
DESCRICAO_VEICULOVEICULO (SELECT)

FORMATA_ANALISE(CD_ANALISE, VL_APURADO) é chamada em ambos os modelos para formatar valores de tipos Hora/Categoria (e no modelo analítico para qualquer tipo). DESCRICAO_VEICULO(NR_PLACA) é chamada no CalcFields do grid de veículos para preencher a descrição exibida (não entra no SQL do relatório).

Tabelas via Procedures (acesso indireto)​

TabelaOperacoes
ANALISESELECT
RESULTADOANALISESELECT

Dependencias Aferentes (quem alimenta esta tela)​

Telas que escrevem em tabelas lidas por este relatório. Lista filtrada para o domínio de laboratório/captação (tabelas cadastrais genéricas como EMPRESA/PESSOA/MUNICIPIO/ENDERECOPESSOA/USUARIOEMPRESA/PARMFATUR são alimentadas por dezenas de telas em todo o ERP e não são listadas aqui).

TelaTítuloTabelas em Comum
MCA012Consulta/Alteração de Lançamento diário de LeiteCONTRATOLEITE, MOVTOLEITE
LAB001Lançamento de Análises de LeiteANALISELEITE
LAB002Cancelamento de AnálisesANALISELEITE
MCA001ContratosCONTRATOLEITE
MCA002Lançamentos PeriódicosMOVTOLEITE
MCA003Transferências entre ContratosMOVTOLEITE
MCA007Condenação de LeiteMOVTOLEITE
MCA008Recebimento Diário de LeiteMOVTOLEITE
MCA010Cancelamento de Recebimento de LeiteMOVTOLEITE
MCA011Alteração de Preço do ContratoCONTRATOLEITE
MOF001Abertura / Fechamento de Ordem de ServiçoVEICULO
MOF005Orçamento de Peças/ServiçosVEICULO
RPD025Relatório de Frota / VeículosVEICULO
RPD026Relatório de Comissão de Prestador de ServiçoVEICULO
RTR001Despesas por Período e VeículoVEICULO
RTR002Média de Consumo Litros por KmVEICULO
RTR003Viagens por VeículoVEICULO
RTR005Relação de Frota / VeículosVEICULO
RTR006Relatório de Evolução de Km/DespesaVEICULO
TCA001ProdutoresPRODUTORLEITE
TCA002Rotas de CaptaçãoROTACAPTACAO
TLA001AnálisesANALISE
TTR001VeículosVEICULO

Dependencias Eferentes (quem consome dados desta tela)​

Nenhuma — RLA001 apenas lê dados (role: consumer). Não grava nenhuma tabela, portanto não alimenta outras telas.

Modelos de Relatório​

O combobox "Modelo de Relatório" (cmbTP_RELATORIO, MapList) oferece duas opções, mapeadas para A (analítico) e M (sintético/média). O SQL é montado dinamicamente em imprimeRelatorio conforme o valor selecionado. O nome do layout de impressão também muda por modelo (RLA001_A ou RLA001_S) — são dois templates .rtm distintos registrados no repositório de layouts.

Modelo 1: Listagem Analítica de Análises​

Quando usado: item "Listagem Analítica de Análises" do combobox (valor A, ItemIndex = 0 — default).

Lista analítica (linha-a-linha) de cada análise laboratorial feita em cada coleta. Mostra data da coleta (ML.DT_MOVTOLEITE), contrato do produtor, endereço/município/UF do produtor, análise e valor apurado formatado via FORMATA_ANALISE (trata tipos Hora e Categoria). Útil para auditar individualmente os resultados de cada recebimento.

Layout: RLA001_A

SQL Base:

SELECT CL.NR_CONTRATO,
PESSOA.NM_PESSOA,
EP.DS_ENDERECO || ' / ' || MUNICIPIO.DS_MUNICIPIO || ' - ' || MUNICIPIO.SG_ESTADO DS_ENDERECO,
AL.CD_ANALISE,
ANALISE.DS_ANALISE,
(SELECT OVL_APURADO FROM FORMATA_ANALISE(AL.CD_ANALISE, AL.VL_APURADO)) VL_APURADO,
ML.DT_MOVTOLEITE,
PF.DS_LOGOTIPO,
EMP.NM_EMPRESA,
COALESCE(EDP.DS_ENDERECO, '') DS_ENDERECOEMP,
MCP.DS_MUNICIPIO DS_MUNICIPIOEMP,
COALESCE(PE.DS_EMAIL, '') DS_EMAILEMP,
COALESCE(EDP.NR_FONE, '') NR_FONEEMP
FROM ANALISELEITE AL
INNER JOIN ANALISE ON (ANALISE.CD_ANALISE = AL.CD_ANALISE)
INNER JOIN MOVTOLEITE ML ON (ML.CD_EMPRESA = AL.CD_EMPRESA
AND ML.NR_MOVTOLEITE = AL.NR_MOVTOLEITE)
INNER JOIN CONTRATOLEITE CL ON (CL.CD_EMPRESA = ML.CD_EMPRCONTRATO
AND CL.NR_CONTRATO = ML.NR_CONTRATO)
INNER JOIN PESSOA ON (PESSOA.CD_PESSOA = CL.CD_PESSOA)
INNER JOIN ENDERECOPESSOA EP ON (EP.CD_PESSOA = CL.CD_PESSOA
AND EP.CD_ENDERECO = CL.CD_ENDERECO)
INNER JOIN MUNICIPIO ON (MUNICIPIO.CD_MUNICIPIO = EP.CD_MUNICIPIO)
INNER JOIN PARMFATUR PF ON (PF.CD_EMPRESA = :CD_EMPRESA_SESSAO) -- logotipo do relatório
-- bloco "dados da empresa emissora":
INNER JOIN EMPRESA EMP ON (EMP.CD_EMPRESA = AL.CD_EMPRESA)
INNER JOIN PESSOA PE ON (PE.CD_PESSOA = EMP.CD_PESSOA)
INNER JOIN ENDERECOPESSOA EDP ON (EDP.CD_PESSOA = PE.CD_PESSOA
AND EDP.CD_ENDERECO = (SELECT MIN(CD_ENDERECO)
FROM ENDERECOPESSOA
WHERE CD_PESSOA = PE.CD_PESSOA))
INNER JOIN MUNICIPIO MCP ON (MCP.CD_MUNICIPIO = EDP.CD_MUNICIPIO)
WHERE ML.ST_MOVTOLEITE <> 'C' -- exclui coletas canceladas
AND ML.TP_MOVTOLEITE = 'C' -- apenas movimento tipo Coleta
AND CL.CD_EMPRESA = :CD_EMPRESA
{AND CL.DT_COMPETENCIA IN (...)} -- filtro grid "Competências"
{AND CL.CD_PESSOA IN (...)} -- filtro grid "Produtores de Leite"
{AND ML.NR_PLACA IN (...)} -- filtro grid "Veículos"
{AND CL.NR_CONTRATO IN (...)} -- filtro grid "Contratos"
ORDER BY PESSOA.NM_PESSOA, CL.NR_CONTRATO, ML.DT_MOVTOLEITE

Modelo 2: Listagem Sintética de Análises (Média)​

Quando usado: item "Listagem Sintética de Análises (Média)" do combobox (valor M, ItemIndex = 1).

Consolidado por produtor × análise dentro do período/filtros, com média dos valores apurados. Montado como UNION ALL de dois blocos: o primeiro agrega analitícamente via AVG apenas analises de tipo numérico/inteiro (ANALISE.TP_DADO IN ('N','I')); o segundo agrega tipos Hora/Categoria (TP_DADO IN ('H','C')) reutilizando FORMATA_ANALISE para formatar o valor representativo. O GROUP BY é por produtor + análise + endereço. Útil para visão gerencial do desempenho médio de cada produtor.

Regra específica deste modelo: o filtro de Veículos é ignorado neste modelo (cmbTP_RELATORIO.ItemIndex <> 1), pois a média é por produtor e não por veículo de coleta.

Layout: RLA001_S

SQL Base:

/* Bloco 1 — tipos numérico/inteiro: faz a média AVG */
SELECT PESSOA.NM_PESSOA,
EP.DS_ENDERECO || ' / ' || MUNICIPIO.DS_MUNICIPIO || ' - ' || MUNICIPIO.SG_ESTADO DS_ENDERECO,
AL.CD_ANALISE,
ANALISE.DS_ANALISE,
CAST(AVG(CAST(AL.VL_APURADO AS NUMERIC(15,3))) AS VARCHAR(60)) VL_APURADO,
PESSOA.CD_PESSOA,
PF.DS_LOGOTIPO, EMP.NM_EMPRESA,
EDP.DS_ENDERECO DS_ENDERECOEMP, MCP.DS_MUNICIPIO DS_MUNICIPIOEMP,
COALESCE(PE.DS_EMAIL, '') DS_EMAILEMP,
COALESCE(EDP.NR_FONE, '') NR_FONEEMP
FROM ANALISELEITE AL
INNER JOIN ANALISE ON (ANALISE.CD_ANALISE = AL.CD_ANALISE)
INNER JOIN MOVTOLEITE ML ON (ML.CD_EMPRESA = AL.CD_EMPRESA
AND ML.NR_MOVTOLEITE = AL.NR_MOVTOLEITE)
INNER JOIN CONTRATOLEITE CL ON (CL.CD_EMPRESA = ML.CD_EMPRCONTRATO
AND CL.NR_CONTRATO = ML.NR_CONTRATO)
INNER JOIN PESSOA ON (PESSOA.CD_PESSOA = CL.CD_PESSOA)
INNER JOIN ENDERECOPESSOA EP ON (EP.CD_PESSOA = CL.CD_PESSOA
AND EP.CD_ENDERECO = CL.CD_ENDERECO)
INNER JOIN MUNICIPIO ON (MUNICIPIO.CD_MUNICIPIO = EP.CD_MUNICIPIO)
INNER JOIN PARMFATUR PF ON (PF.CD_EMPRESA = :CD_EMPRESA_SESSAO)
INNER JOIN EMPRESA EMP ON (EMP.CD_EMPRESA = AL.CD_EMPRESA)
INNER JOIN PESSOA PE ON (PE.CD_PESSOA = EMP.CD_PESSOA)
INNER JOIN ENDERECOPESSOA EDP ON (EDP.CD_PESSOA = PE.CD_PESSOA
AND EDP.CD_ENDERECO = (SELECT MIN(CD_ENDERECO)
FROM ENDERECOPESSOA
WHERE CD_PESSOA = PE.CD_PESSOA))
INNER JOIN MUNICIPIO MCP ON (MCP.CD_MUNICIPIO = EDP.CD_MUNICIPIO)
WHERE ML.ST_MOVTOLEITE <> 'C'
AND ML.TP_MOVTOLEITE = 'C'
AND ANALISE.TP_DADO IN ('N','I') -- Numérico, Inteiro
AND CL.CD_EMPRESA = :CD_EMPRESA
{AND CL.DT_COMPETENCIA IN (...)}
{AND CL.CD_PESSOA IN (...)}
{AND CL.NR_CONTRATO IN (...)} -- filtro de Veículos NÃO é aplicado neste modelo
GROUP BY PESSOA.NM_PESSOA, EP.DS_ENDERECO, MUNICIPIO.DS_MUNICIPIO, MUNICIPIO.SG_ESTADO,
AL.CD_ANALISE, ANALISE.DS_ANALISE, AL.VL_APURADO,
PESSOA.CD_PESSOA, PF.DS_LOGOTIPO, EMP.NM_EMPRESA,
EDP.DS_ENDERECO, MCP.DS_MUNICIPIO, PE.DS_EMAIL, EDP.NR_FONE

UNION ALL

/* Bloco 2 — tipos Hora/Categoria: usa FORMATA_ANALISE como representativo */
SELECT PESSOA.NM_PESSOA,
EP.DS_ENDERECO || ' / ' || MUNICIPIO.DS_MUNICIPIO || ' - ' || MUNICIPIO.SG_ESTADO DS_ENDERECO,
AL.CD_ANALISE,
ANALISE.DS_ANALISE,
CAST((SELECT OVL_APURADO FROM FORMATA_ANALISE(AL.CD_ANALISE, AL.VL_APURADO)) AS VARCHAR(60)) VL_APURADO,
PESSOA.CD_PESSOA,
PF.DS_LOGOTIPO, EMP.NM_EMPRESA,
EDP.DS_ENDERECO DS_ENDERECOEMP, MCP.DS_MUNICIPIO DS_MUNICIPIOEMP,
COALESCE(PE.DS_EMAIL, '') DS_EMAILEMP,
COALESCE(EDP.NR_FONE, '') NR_FONEEMP
FROM ANALISELEITE AL
-- (mesmos JOINs do Bloco 1)
WHERE ML.ST_MOVTOLEITE <> 'C'
AND ML.TP_MOVTOLEITE = 'C'
AND ANALISE.TP_DADO IN ('H','C') -- Hora, Categoria
AND CL.CD_EMPRESA = :CD_EMPRESA
{AND CL.DT_COMPETENCIA IN (...)}
{AND CL.CD_PESSOA IN (...)}
{AND CL.NR_CONTRATO IN (...)}
GROUP BY PESSOA.NM_PESSOA, EP.DS_ENDERECO, MUNICIPIO.DS_MUNICIPIO, MUNICIPIO.SG_ESTADO,
AL.CD_ANALISE, ANALISE.DS_ANALISE, AL.VL_APURADO,
PESSOA.CD_PESSOA, PF.DS_LOGOTIPO, EMP.NM_EMPRESA,
EDP.DS_ENDERECO, MCP.DS_MUNICIPIO, PE.DS_EMAIL, EDP.NR_FONE

A impressão é delegada a GeraRelatorio(transaction, nm_relatorio, Consulta) do jReport, que carrega o layout externo registrado (RLA001_A ou RLA001_S).