Commit 6e3f6cce27d43274ddb70fddc17ec5b43d8885ab
Committed by
Eduardo Santos
1 parent
bee7f236
Exists in
master
and in
1 other branch
Novo relatório de faturamento que agrupa os resultados pelo MAC Address, mostran…
…do explicitamente as informações que forem repetidas.
Showing
6 changed files
with
224 additions
and
37 deletions
Show diff stats
app/config/config.yml
... | ... | @@ -123,6 +123,9 @@ doctrine: |
123 | 123 | orm: |
124 | 124 | auto_generate_proxy_classes: "%kernel.debug%" |
125 | 125 | auto_mapping: true |
126 | + dql: | |
127 | + string_functions: | |
128 | + string_agg: Cacic\CommonBundle\Query\PostgreSQL\StringAggFunction | |
126 | 129 | |
127 | 130 | # Swiftmailer Configuration |
128 | 131 | swiftmailer: | ... | ... |
src/Cacic/CommonBundle/Entity/LogAcessoRepository.php
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | namespace Cacic\CommonBundle\Entity; |
4 | 4 | |
5 | 5 | use Doctrine\ORM\EntityRepository; |
6 | +use Doctrine\ORM\Query\ResultSetMapping; | |
6 | 7 | |
7 | 8 | /** |
8 | 9 | * LogAcessoRepository |
... | ... | @@ -42,7 +43,7 @@ class LogAcessoRepository extends EntityRepository |
42 | 43 | |
43 | 44 | // Monta a Consulta básica... |
44 | 45 | $query = $this->createQueryBuilder('log') |
45 | - ->select('rede.idRede', 'rede.nmRede', 'rede.teIpRede', 'loc.nmLocal', 'loc.sgLocal', 'COUNT(DISTINCT log.idComputador) as numComp') | |
46 | + ->select('rede.idRede', 'rede.nmRede', 'rede.teIpRede', 'loc.nmLocal', 'loc.sgLocal', 'COUNT(DISTINCT comp.teNodeAddress) as numComp') | |
46 | 47 | ->innerJoin('log.idComputador', 'comp') |
47 | 48 | ->innerJoin('comp.idRede', 'rede') |
48 | 49 | ->innerJoin('rede.idLocal', 'loc') |
... | ... | @@ -63,29 +64,84 @@ class LogAcessoRepository extends EntityRepository |
63 | 64 | |
64 | 65 | return $query->getQuery()->execute(); |
65 | 66 | } |
66 | - public function gerarRelatorioRede( $filtros, $idRede,$dataInicio, $dataFim ) | |
67 | + | |
68 | + | |
69 | + public function gerarRelatorioRede( $filtros, $idRede, $dataInicio, $dataFim ) | |
67 | 70 | { |
68 | - $query = $this->createQueryBuilder('log') | |
69 | - ->select('comp.idComputador', 'comp.nmComputador', 'comp.teNodeAddress','comp.teIpComputador', 'max(log.data) AS data', 'so.idSo', 'so.inMswindows', 'so.sgSo', 'rede.idRede', 'rede.nmRede', 'rede.teIpRede', 'local.nmLocal', 'local.idLocal') | |
70 | - ->innerJoin('log.idComputador','comp') | |
71 | - ->innerJoin('comp.idSo', 'so') | |
72 | - ->innerJoin('comp.idRede','rede') | |
73 | - ->innerJoin('rede.idLocal', 'local') | |
74 | - ->groupBy('comp.idComputador', 'comp.nmComputador', 'comp.teNodeAddress','comp.teIpComputador', 'so.idSo', 'so.inMswindows', 'so.sgSo', 'rede.idRede', 'rede.nmRede', 'rede.teIpRede', 'local.nmLocal', 'local.idLocal'); | |
71 | + $rsm = new ResultSetMapping(); | |
72 | + $rsm->addScalarResult('te_node_address', 'teNodeAddress'); | |
73 | + $rsm->addScalarResult('id_computador', 'idComputador'); | |
74 | + $rsm->addScalarResult('te_ip_computador', 'teIpComputador'); | |
75 | + $rsm->addScalarResult('nm_computador', 'nmComputador'); | |
76 | + $rsm->addScalarResult('id_so', 'idSo'); | |
77 | + $rsm->addScalarResult('sg_so', 'sgSo'); | |
78 | + $rsm->addScalarResult('id_rede', 'idRede'); | |
79 | + $rsm->addScalarResult('nm_rede', 'nmRede'); | |
80 | + $rsm->addScalarResult('te_ip_rede', 'teIpRede'); | |
81 | + $rsm->addScalarResult('max_data', 'data'); | |
82 | + $rsm->addScalarResult('nm_local', 'nmLocal'); | |
83 | + $rsm->addScalarResult('id_local', 'idLocal'); | |
84 | + | |
85 | + $sql = " | |
86 | +SELECT c0_.te_node_address AS te_node_address, | |
87 | + string_agg(DISTINCT CAST(c0_.id_computador AS text), ', ') as id_computador, | |
88 | + string_agg(DISTINCT c0_.te_ip_computador, ', ') as te_ip_computador, | |
89 | + string_agg(DISTINCT c0_.nm_computador, ', ') AS nm_computador, | |
90 | + string_agg(DISTINCT CAST(s2_.id_so AS text), ', ') AS id_so, | |
91 | + string_agg(DISTINCT s2_.sg_so, ', ') AS sg_so, | |
92 | + string_agg(DISTINCT CAST(r3_.id_rede AS text), ', ') AS id_rede, | |
93 | + string_agg(DISTINCT r3_.nm_rede, ', ') AS nm_rede, | |
94 | + string_agg(DISTINCT r3_.te_ip_rede, ', ') AS te_ip_rede, | |
95 | + max(l1_.data) AS max_data, | |
96 | + l4_.nm_local AS nm_local, | |
97 | + l4_.id_local AS id_local | |
98 | +FROM log_acesso l1_ | |
99 | +INNER JOIN computador c0_ ON l1_.id_computador = c0_.id_computador | |
100 | +INNER JOIN so s2_ ON c0_.id_so = s2_.id_so | |
101 | +INNER JOIN rede r3_ ON c0_.id_rede = r3_.id_rede | |
102 | +INNER JOIN local l4_ ON r3_.id_local = l4_.id_local | |
103 | +WHERE 1 = 1 | |
104 | +"; | |
75 | 105 | |
76 | 106 | /** |
77 | 107 | * Verifica os filtros que foram parametrizados |
78 | 108 | */ |
79 | - if ( $dataInicio ) | |
80 | - $query->andWhere( 'log.data >= :dtInicio' )->setParameter('dtInicio', ( $dataInicio.' 00:00:00' )); | |
109 | + if ( $dataInicio ) { | |
110 | + $sql .= " AND l1_.data >= ? "; | |
111 | + } | |
112 | + | |
113 | + if ( $dataFim ) { | |
114 | + $sql .= " AND l1_.data <= ?"; | |
115 | + } | |
116 | + | |
117 | + if ( $idRede ) { | |
118 | + $sql .= " AND c0_.id_rede IN (?)"; | |
119 | + } | |
120 | + | |
121 | + $sql .= " | |
122 | +GROUP BY c0_.te_node_address, | |
123 | + l4_.nm_local, | |
124 | + l4_.id_local | |
125 | + "; | |
126 | + | |
127 | + $query = $this->getEntityManager()->createNativeQuery($sql, $rsm); | |
128 | + | |
129 | + /** | |
130 | + * Verifica os filtros que foram parametrizados | |
131 | + */ | |
132 | + if ( $dataInicio ) { | |
133 | + $query->setParameter(1, ( $dataInicio.' 00:00:00' )); | |
134 | + } | |
135 | + | |
81 | 136 | |
82 | 137 | if ( $dataFim ) |
83 | - $query->andWhere( 'log.data <= :dtFim' )->setParameter('dtFim', ( $dataFim.' 23:59:59' )); | |
138 | + $query->setParameter(2, ( $dataFim.' 23:59:59' )); | |
84 | 139 | |
85 | - if ( ($idRede) ) | |
86 | - $query->andWhere( 'comp.idRede IN (:rede)' )->setParameter('rede', $idRede); | |
140 | + if ( $idRede ) | |
141 | + $query->setParameter(3, $idRede); | |
87 | 142 | |
88 | - return $query->getQuery()->execute(); | |
143 | + | |
144 | + return $query->execute(); | |
89 | 145 | } |
90 | 146 | |
91 | 147 | /** |
... | ... | @@ -97,7 +153,7 @@ class LogAcessoRepository extends EntityRepository |
97 | 153 | public function countPorComputador() { |
98 | 154 | |
99 | 155 | $query = $this->createQueryBuilder('log') |
100 | - ->select('COUNT(DISTINCT comp.idComputador)') | |
156 | + ->select('COUNT(DISTINCT comp.teNodeAddress)') | |
101 | 157 | ->innerJoin('CacicCommonBundle:Computador','comp', 'WITH', 'log.idComputador = comp.idComputador') |
102 | 158 | ->andWhere( 'log.data >= (current_date() - 30)' ); |
103 | 159 | |
... | ... | @@ -107,12 +163,13 @@ class LogAcessoRepository extends EntityRepository |
107 | 163 | |
108 | 164 | return $query->execute(); |
109 | 165 | } |
166 | + | |
110 | 167 | public function faturamentoCsv( $dataInicio, $dataFim, $locais ) |
111 | 168 | { |
112 | 169 | |
113 | 170 | // Monta a Consulta básica... |
114 | 171 | $query = $this->createQueryBuilder('log') |
115 | - ->select( 'loc.nmLocal', 'rede.nmRede', 'rede.teIpRede', 'COUNT(DISTINCT log.idComputador) as numComp') | |
172 | + ->select( 'loc.nmLocal', 'rede.nmRede', 'rede.teIpRede', 'COUNT(DISTINCT comp.teNodeAddress) as numComp') | |
116 | 173 | ->innerJoin('log.idComputador', 'comp') |
117 | 174 | ->innerJoin('comp.idRede', 'rede') |
118 | 175 | ->innerJoin('rede.idLocal', 'loc') |
... | ... | @@ -133,29 +190,74 @@ class LogAcessoRepository extends EntityRepository |
133 | 190 | |
134 | 191 | return $query->getQuery()->execute(); |
135 | 192 | } |
193 | + | |
136 | 194 | public function listarCsv( $filtros, $idRede, $dataInicio, $dataFim ) |
137 | 195 | { |
138 | - $query = $this->createQueryBuilder('log') | |
139 | - ->select('comp.nmComputador', 'comp.teNodeAddress','comp.teIpComputador', 'so.sgSo', 'local.nmLocal', 'rede.nmRede','max(log.data) AS data') | |
140 | - ->innerJoin('log.idComputador','comp') | |
141 | - ->innerJoin('comp.idSo', 'so') | |
142 | - ->innerJoin('comp.idRede','rede') | |
143 | - ->innerJoin('rede.idLocal', 'local') | |
144 | - ->groupBy( 'comp.idComputador', 'comp.nmComputador', 'comp.teNodeAddress','comp.teIpComputador', 'so.idSo', 'so.inMswindows', 'so.sgSo', 'rede.idRede', 'rede.nmRede', 'rede.teIpRede', 'local.nmLocal', 'local.idLocal'); | |
196 | + | |
197 | + $rsm = new ResultSetMapping(); | |
198 | + $rsm->addScalarResult('nm_computador', 'nmComputador'); | |
199 | + $rsm->addScalarResult('te_node_address', 'teNodeAddress'); | |
200 | + $rsm->addScalarResult('te_ip_computador', 'teIpComputador'); | |
201 | + $rsm->addScalarResult('sg_so', 'sgSo'); | |
202 | + $rsm->addScalarResult('nm_local', 'nmLocal'); | |
203 | + $rsm->addScalarResult('nm_rede', 'nmRede'); | |
204 | + $rsm->addScalarResult('max_data', 'data'); | |
205 | + | |
206 | + $sql = " | |
207 | +SELECT c0_.te_node_address AS te_node_address, | |
208 | + string_agg(DISTINCT c0_.te_ip_computador, ', ') as te_ip_computador, | |
209 | + string_agg(DISTINCT c0_.nm_computador, ', ') AS nm_computador, | |
210 | + string_agg(DISTINCT s2_.sg_so, ', ') AS sg_so, | |
211 | + string_agg(DISTINCT r3_.nm_rede, ', ') AS nm_rede, | |
212 | + max(l1_.data) AS max_data, | |
213 | + l4_.nm_local AS nm_local | |
214 | +FROM log_acesso l1_ | |
215 | +INNER JOIN computador c0_ ON l1_.id_computador = c0_.id_computador | |
216 | +INNER JOIN so s2_ ON c0_.id_so = s2_.id_so | |
217 | +INNER JOIN rede r3_ ON c0_.id_rede = r3_.id_rede | |
218 | +INNER JOIN local l4_ ON r3_.id_local = l4_.id_local | |
219 | +WHERE 1 = 1 | |
220 | +"; | |
145 | 221 | |
146 | 222 | /** |
147 | 223 | * Verifica os filtros que foram parametrizados |
148 | 224 | */ |
149 | - if ( $dataInicio ) | |
150 | - $query->andWhere( 'log.data >= :dtInicio' )->setParameter('dtInicio', ( $dataInicio.' 00:00:00' )); | |
225 | + if ( $dataInicio ) { | |
226 | + $sql .= " AND l1_.data >= ? "; | |
227 | + } | |
228 | + | |
229 | + if ( $dataFim ) { | |
230 | + $sql .= " AND l1_.data <= ?"; | |
231 | + } | |
232 | + | |
233 | + if ( $idRede ) { | |
234 | + $sql .= " AND c0_.id_rede IN (?)"; | |
235 | + } | |
236 | + | |
237 | + $sql .= " | |
238 | +GROUP BY c0_.te_node_address, | |
239 | + l4_.nm_local, | |
240 | + l4_.id_local | |
241 | + "; | |
242 | + | |
243 | + $query = $this->getEntityManager()->createNativeQuery($sql, $rsm); | |
244 | + | |
245 | + /** | |
246 | + * Verifica os filtros que foram parametrizados | |
247 | + */ | |
248 | + if ( $dataInicio ) { | |
249 | + $query->setParameter(1, ( $dataInicio.' 00:00:00' )); | |
250 | + } | |
251 | + | |
151 | 252 | |
152 | 253 | if ( $dataFim ) |
153 | - $query->andWhere( 'log.data <= :dtFim' )->setParameter('dtFim', ( $dataFim.' 23:59:59' )); | |
254 | + $query->setParameter(2, ( $dataFim.' 23:59:59' )); | |
154 | 255 | |
155 | - if ( count($idRede) ) | |
156 | - $query->andWhere( 'comp.idRede IN (:rede)' )->setParameter('rede', $idRede); | |
256 | + if ( $idRede ) | |
257 | + $query->setParameter(3, $idRede); | |
157 | 258 | |
158 | - return $query->getQuery()->execute(); | |
259 | + | |
260 | + return $query->execute(); | |
159 | 261 | } |
160 | 262 | |
161 | 263 | } | ... | ... |
src/Cacic/CommonBundle/Query/PostgreSQL/StringAggFunction.php
0 → 100644
... | ... | @@ -0,0 +1,40 @@ |
1 | +<?php | |
2 | +/** | |
3 | + * Created by PhpStorm. | |
4 | + * User: eduardo | |
5 | + * Date: 26/06/14 | |
6 | + * Time: 00:08 | |
7 | + */ | |
8 | + | |
9 | +namespace Cacic\CommonBundle\Query\PostgreSQL; | |
10 | + | |
11 | +use Doctrine\ORM\Query\AST\Functions\FunctionNode; | |
12 | +use Doctrine\ORM\Query\Lexer; | |
13 | +use Doctrine\ORM\Query\Parser; | |
14 | +use Doctrine\ORM\Query\SqlWalker; | |
15 | + | |
16 | +/** | |
17 | + * Class StringAggFunction | |
18 | + * @package Cacic\CommonBundle\Query\PostgreSQL | |
19 | + * | |
20 | + * Extracted from http://pierrickcaen.fr/blog/symfony-sql-functions.html | |
21 | + */ | |
22 | + | |
23 | +class StringAggFunction extends FunctionNode | |
24 | +{ | |
25 | + public function getSql(SqlWalker $sqlWalker) | |
26 | + { | |
27 | + return 'string_agg(' . $this->expression->dispatch($sqlWalker) . ',' . $this->delimiter->dispatch($sqlWalker) .')'; | |
28 | + } | |
29 | + | |
30 | + public function parse(Parser $parser) | |
31 | + { | |
32 | + $parser->match(Lexer::T_IDENTIFIER); | |
33 | + $parser->match(Lexer::T_OPEN_PARENTHESIS); | |
34 | + $parser->match(Lexer::T_DISTINCT); | |
35 | + $this->expression = $parser->ArithmeticPrimary(); | |
36 | + $parser->match(Lexer::T_COMMA); | |
37 | + $this->delimiter = $parser->ArithmeticPrimary(); | |
38 | + $parser->match(Lexer::T_CLOSE_PARENTHESIS); | |
39 | + } | |
40 | +} | |
0 | 41 | \ No newline at end of file | ... | ... |
src/Cacic/RelatorioBundle/Controller/FaturamentoController.php
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 | use Ddeboer\DataImport\Writer\CsvWriter; |
13 | 13 | use Ddeboer\DataImport\ValueConverter\CallbackValueConverter; |
14 | 14 | use Symfony\Component\HttpFoundation\BinaryFileResponse; |
15 | + use Cacic\CommonBundle\Form\Type\ComputadorConsultaType; | |
15 | 16 | |
16 | 17 | |
17 | 18 | class FaturamentoController extends Controller { |
... | ... | @@ -323,4 +324,30 @@ |
323 | 324 | $response->headers->set('Content-Disposition', 'attachment; filename="Não Coletadas.csv"'); |
324 | 325 | $response->headers->set('Content-Transfer-Encoding', 'binary'); |
325 | 326 | } |
327 | + | |
328 | + /** | |
329 | + * Search computer with params | |
330 | + * | |
331 | + * @param Request $request | |
332 | + * @return \Symfony\Component\HttpFoundation\Response | |
333 | + */ | |
334 | + public function computadorAction( Request $request ) | |
335 | + { | |
336 | + $locale = $request->getLocale(); | |
337 | + $data = $request->query->all(); | |
338 | + | |
339 | + $form = $this->createForm( new ComputadorConsultaType() ); | |
340 | + | |
341 | + $computadores = $this->getDoctrine()->getRepository( 'CacicCommonBundle:Computador') | |
342 | + ->selectIp($data['teIpComputador'],$data['nmComputador'] ,$data['teNodeAddress'] ); | |
343 | + | |
344 | + | |
345 | + return $this->render( 'CacicCommonBundle:Computador:buscar.html.twig', | |
346 | + array( | |
347 | + 'local'=>$locale , | |
348 | + 'form' => $form->createView(), | |
349 | + 'computadores' => ( $computadores ) | |
350 | + ) | |
351 | + ); | |
352 | + } | |
326 | 353 | } | ... | ... |
src/Cacic/RelatorioBundle/Resources/config/routing.yml
... | ... | @@ -175,4 +175,8 @@ cacic_relatorio_csv_hardware_wmi: |
175 | 175 | |
176 | 176 | cacic_relatorio_csv_hardware_wmi_detalhe: |
177 | 177 | pattern: /csv/hardware/{classe}/{propriedade} |
178 | - defaults: { _controller: CacicRelatorioBundle:Hardware:csvWMIRelatorioDetalhe } | |
179 | 178 | \ No newline at end of file |
179 | + defaults: { _controller: CacicRelatorioBundle:Hardware:csvWMIRelatorioDetalhe } | |
180 | + | |
181 | +cacic_faturamento_computador: | |
182 | + pattern: /faturamento/computador | |
183 | + defaults: { _controller: CacicRelatorioBundle:Faturamento:computador } | |
180 | 184 | \ No newline at end of file | ... | ... |
src/Cacic/RelatorioBundle/Resources/views/Faturamento/listar.html.twig
... | ... | @@ -10,7 +10,6 @@ |
10 | 10 | <table class="display datatable" id="datatable"> |
11 | 11 | <thead> |
12 | 12 | <tr> |
13 | - <th width="5%" style="text-align: center"></th> | |
14 | 13 | <th width="15%">{{ "Computador"|trans }}</th> |
15 | 14 | <th width="10%">{{ "MAC Address"|trans }}</th> |
16 | 15 | <th width="10%">{{ "Endereço IP"|trans }}</th> |
... | ... | @@ -23,14 +22,26 @@ |
23 | 22 | |
24 | 23 | <tbody> |
25 | 24 | {% for reg in dados %} |
25 | + {% set computadores = reg.idComputador|split(',') %} | |
26 | + {% set nomes = reg.nmComputador|split(',') %} | |
27 | + {% set ips = reg.teIpComputador|split(',') %} | |
26 | 28 | <tr> |
27 | - <td style="text-align: center">{{ loop.index }}</td> | |
28 | 29 | <td> |
29 | - <b><a href="{{ path('cacic_computador_detalhar') }}/{{ reg.idComputador }}" title="{{ "Todas as informações do computador"|trans }}" target="_blank">{{ reg.nmComputador }}</a></b> | |
30 | + {% for comp in nomes %} | |
31 | + <b><a href="{{ path('cacic_faturamento_computador', {'nmComputador' : comp|trim }) }}" title="{{ 'Detalhar computador'|trans }}" target="_blank">{{ comp }}</a></b> | |
32 | + {% else %} | |
33 | + <b>{{ reg.nmComputador }}</b> | |
34 | + {% endfor %} | |
30 | 35 | </td> |
31 | - <td><a href="{{ path('cacic_computador_detalhar') }}/{{ reg.idComputador }}" title="{{ "Todas as informações do computador"|trans }}" target="_blank">{{ reg.teNodeAddress }}</a></td> | |
32 | - <td><a href="{{ path('cacic_computador_detalhar') }}/{{ reg.idComputador }}" title="{{ "Todas as informações do computador"|trans }}" target="_blank">{{ reg.teIpComputador }}</a></td> | |
33 | - <td><span class="{% if reg.inMswindows == 'S' %}red{% else %}blue{% endif %}">{{ reg.sgSo }}</span></td> | |
36 | + <td><a href="{{ path('cacic_faturamento_computador', {'teNodeAddress' : reg.teNodeAddress|trim }) }}" title="{{ 'Detalhar computador'|trans }}" target="_blank">{{ reg.teNodeAddress }}</a></td> | |
37 | + <td> | |
38 | + {% for comp in ips %} | |
39 | + <b><a href="{{ path('cacic_faturamento_computador', {'teIpComputador' : comp|trim }) }}" title="{{ 'Detalhar computador'|trans }}" target="_blank">{{ comp }}</a></b> | |
40 | + {% else %} | |
41 | + <b>{{ reg.teIpComputador }}</b> | |
42 | + {% endfor %} | |
43 | + </td> | |
44 | + <td>{{ reg.sgSo }}</td> | |
34 | 45 | <td>{{ reg.nmLocal }}</td> |
35 | 46 | <td>{{ reg.nmRede }} / {{ reg.teIpRede }}</td> |
36 | 47 | <td>{{ reg.data|date(' d, M, Y H:m:s') }}</td> | ... | ... |