Commit ce1ecf146edfe5ae5c63f082b1e5cdc35c287075
1 parent
252b3fe5
Exists in
master
ETL agora faz mais operacoes.
git-svn-id: http://svn.softwarepublico.gov.br/svn/sistemadeatendimento/sistema/trunk@8 63db2ce5-8a6c-0410-abb9-a418dd412890
Showing
6 changed files
with
467 additions
and
265 deletions
Show diff stats
Fila-ETL/fila_etl.yaml
@@ -16,7 +16,7 @@ Model::DBSERVI: | @@ -16,7 +16,7 @@ Model::DBSERVI: | ||
16 | schema_class: 'Fila::Servico::DB' | 16 | schema_class: 'Fila::Servico::DB' |
17 | connect_info: | 17 | connect_info: |
18 | - 'dbi:Pg:host=localhost;database=fila' | 18 | - 'dbi:Pg:host=localhost;database=fila' |
19 | - - ruoso | 19 | + - fila |
20 | - teste | 20 | - teste |
21 | Model::Federado: | 21 | Model::Federado: |
22 | federacao: | 22 | federacao: |
Fila-ETL/lib/Fila/ETL/Controller/Atendimento.pm
@@ -245,153 +245,164 @@ sub estados :Chained('atendimento') :PathPart :Args(0) { | @@ -245,153 +245,164 @@ sub estados :Chained('atendimento') :PathPart :Args(0) { | ||
245 | my $local = $c->model('Federado')->target($c, $id, 'Local')->find | 245 | my $local = $c->model('Federado')->target($c, $id, 'Local')->find |
246 | ({ id_local => $id }); | 246 | ({ id_local => $id }); |
247 | 247 | ||
248 | - my $sql = q#; | 248 | + my $sql_times = q{ |
249 | SELECT | 249 | SELECT |
250 | - | ||
251 | - date_trunc('minute',times.vt_fac) AS datahora, | ||
252 | - COUNT(es_espe_ini.*) AS espe_ini, | ||
253 | - COUNT(es_espe_fim.*) AS espe_fim, | ||
254 | - COUNT(es_cham_ini.*) AS cham_ini, | ||
255 | - COUNT(es_cham_fim.*) AS cham_fim, | ||
256 | - COUNT(es_aten_ini.*) AS aten_ini, | ||
257 | - COUNT(es_aten_fim.*) AS aten_fim, | ||
258 | - COUNT(es_no_show.*) AS no_show, | ||
259 | - ct_espe_ini.id_categoria AS ct_espe_ini_id_categoria, | ||
260 | - ct_espe_ini.nome AS ct_espe_ini_nome, | ||
261 | - ct_espe_ini.codigo AS ct_espe_ini_codigo, | ||
262 | - ct_espe_fim.id_categoria AS ct_espe_fim_id_categoria, | ||
263 | - ct_espe_fim.nome AS ct_espe_fim_nome, | ||
264 | - ct_espe_fim.codigo AS ct_espe_fim_codigo, | ||
265 | - ct_cham_ini.id_categoria AS ct_cham_ini_id_categoria, | ||
266 | - ct_cham_ini.nome AS ct_cham_ini_nome, | ||
267 | - ct_cham_ini.codigo AS ct_cham_ini_codigo, | ||
268 | - ct_cham_fim.id_categoria AS ct_cham_fim_id_categoria, | ||
269 | - ct_cham_fim.nome AS ct_cham_fim_nome, | ||
270 | - ct_cham_fim.codigo AS ct_cham_fim_codigo, | ||
271 | - ct_aten_ini.id_categoria AS ct_aten_ini_id_categoria, | ||
272 | - ct_aten_ini.nome AS ct_aten_ini_nome, | ||
273 | - ct_aten_ini.codigo AS ct_aten_ini_codigo, | ||
274 | - ct_aten_fim.id_categoria AS ct_aten_fim_id_categoria, | ||
275 | - ct_aten_fim.nome AS ct_aten_fim_nome, | ||
276 | - ct_aten_fim.codigo AS ct_aten_fim_codigo, | ||
277 | - ct_no_show.id_categoria AS ct_no_show_id_categoria, | ||
278 | - ct_no_show.nome AS ct_no_show_nome, | ||
279 | - ct_no_show.codigo AS ct_no_show_codigo | ||
280 | - | 250 | + DISTINCT DATE_TRUNC('minute', estado_atendimento.vt_ini) + '59.9999999 seconds' AS vt_fac |
281 | FROM | 251 | FROM |
252 | + atendimento LEFT JOIN | ||
253 | + estado_atendimento USING (id_atendimento) | ||
254 | +WHERE | ||
255 | + atendimento.id_local = ? AND | ||
256 | + atendimento.vt_ini >= ? AND | ||
257 | + atendimento.vt_ini < ? AND | ||
258 | + estado_atendimento.vt_ini >= ? AND | ||
259 | + estado_atendimento.vt_ini < ? | ||
260 | +}; | ||
261 | + | ||
262 | + my $sql_estados_categorias = q{ | ||
263 | +SELECT | ||
264 | + COUNT(tipo_estado_atendimento.*) as quantidade, | ||
265 | + categoria.nome, categoria.codigo, categoria.id_categoria, | ||
266 | + tipo_estado_atendimento.nome as nome_estado | ||
282 | 267 | ||
283 | - ( SELECT vt_ini AS vt_fac FROM estado_atendimento estados_ini | ||
284 | - WHERE ( | ||
285 | - ( estados_ini.vt_ini >= ? ) AND | ||
286 | - ( estados_ini.vt_ini < ? ) ) | ||
287 | - UNION | ||
288 | - SELECT vt_fim AS vt_fac FROM estado_atendimento estados_fim | ||
289 | - WHERE ( | ||
290 | - ( estados_fim.vt_fim >= ? ) AND | ||
291 | - ( estados_fim.vt_fim < ? ) ) | ||
292 | - ) AS times | ||
293 | - | ||
294 | - LEFT JOIN estado_atendimento AS es_espe_ini ON (times.vt_fac = es_espe_ini.vt_ini | ||
295 | - AND es_espe_ini.id_estado=(SELECT id_estado FROM tipo_estado_atendimento WHERE nome='espera')) | ||
296 | - | ||
297 | - LEFT JOIN atendimento AS at_espe_ini ON | ||
298 | - ( es_espe_ini.id_atendimento = at_espe_ini.id_atendimento AND | ||
299 | - at_espe_ini.id_local = ? ) | ||
300 | - | ||
301 | - LEFT JOIN categoria_atendimento AS cs_espe_ini ON | ||
302 | - ( at_espe_ini.id_atendimento = cs_espe_ini.id_atendimento) | ||
303 | - | ||
304 | - LEFT JOIN categoria AS ct_espe_ini ON | ||
305 | - ( cs_espe_ini.id_categoria = ct_espe_ini.id_categoria) | ||
306 | - | ||
307 | - LEFT JOIN estado_atendimento AS es_espe_fim ON (times.vt_fac = es_espe_fim.vt_fim | ||
308 | - AND es_espe_fim.id_estado=(SELECT id_estado FROM tipo_estado_atendimento WHERE nome='espera')) | ||
309 | - | ||
310 | - LEFT JOIN atendimento AS at_espe_fim ON | ||
311 | - ( es_espe_fim.id_atendimento = at_espe_fim.id_atendimento AND | ||
312 | - at_espe_fim.id_local = ? ) | ||
313 | - | ||
314 | - LEFT JOIN categoria_atendimento AS cs_espe_fim ON | ||
315 | - ( at_espe_fim.id_atendimento = cs_espe_fim.id_atendimento) | ||
316 | - | ||
317 | - LEFT JOIN categoria AS ct_espe_fim ON | ||
318 | - ( cs_espe_fim.id_categoria = ct_espe_fim.id_categoria) | ||
319 | - | ||
320 | - LEFT JOIN estado_atendimento AS es_cham_ini ON (times.vt_fac = es_cham_ini.vt_ini | ||
321 | - AND es_cham_ini.id_estado=(SELECT id_estado FROM tipo_estado_atendimento WHERE nome='chamando')) | ||
322 | - | ||
323 | - LEFT JOIN atendimento AS at_cham_ini ON | ||
324 | - ( es_cham_ini.id_atendimento = at_cham_ini.id_atendimento AND | ||
325 | - at_cham_ini.id_local = ? ) | ||
326 | - | ||
327 | - LEFT JOIN categoria_atendimento AS cs_cham_ini ON | ||
328 | - ( at_cham_ini.id_atendimento = cs_cham_ini.id_atendimento) | 268 | +FROM |
269 | + categoria LEFT JOIN | ||
270 | + categoria_atendimento | ||
271 | + ON (categoria.id_categoria=categoria_atendimento.id_categoria AND | ||
272 | + categoria_atendimento.vt_ini <= ? AND | ||
273 | + categoria_atendimento.vt_fim > ?) LEFT JOIN | ||
274 | + atendimento | ||
275 | + ON (atendimento.id_atendimento=categoria_atendimento.id_atendimento AND | ||
276 | + atendimento.id_local = ? ) LEFT JOIN | ||
277 | + estado_atendimento | ||
278 | + ON (atendimento.id_atendimento=estado_atendimento.id_atendimento AND | ||
279 | + estado_atendimento.vt_ini <= ? AND | ||
280 | + estado_atendimento.vt_fim > ?) LEFT JOIN | ||
281 | + tipo_estado_atendimento USING (id_estado) | ||
282 | + | ||
283 | +WHERE tipo_estado_atendimento.nome IS NOT NULL | ||
329 | 284 | ||
330 | - LEFT JOIN categoria AS ct_cham_ini ON | ||
331 | - ( cs_cham_ini.id_categoria = ct_cham_ini.id_categoria) | 285 | +GROUP BY |
286 | + categoria.nome, categoria.codigo, categoria.id_categoria, | ||
287 | + tipo_estado_atendimento.nome | ||
332 | 288 | ||
333 | - LEFT JOIN estado_atendimento AS es_cham_fim ON (times.vt_fac = es_cham_fim.vt_fim | ||
334 | - AND es_cham_fim.id_estado=(SELECT id_estado FROM tipo_estado_atendimento WHERE nome='chamando')) | ||
335 | 289 | ||
336 | - LEFT JOIN atendimento AS at_cham_fim ON | ||
337 | - ( es_cham_fim.id_atendimento = at_cham_fim.id_atendimento AND | ||
338 | - at_cham_fim.id_local = ? ) | 290 | +}; |
339 | 291 | ||
340 | - LEFT JOIN categoria_atendimento AS cs_cham_fim ON | ||
341 | - ( at_cham_fim.id_atendimento = cs_cham_fim.id_atendimento) | 292 | + my $storage = $c->model('Federado')->storage($c, $id); |
293 | + $storage->ensure_connected; | ||
294 | + my $dbi = $storage->dbh; | ||
342 | 295 | ||
343 | - LEFT JOIN categoria AS ct_cham_fim ON | ||
344 | - ( cs_cham_fim.id_categoria = ct_cham_fim.id_categoria) | 296 | + my $sth = $dbi->prepare($sql_times); |
297 | + $sth->execute( $id, | ||
298 | + $c->stash->{last_vt_base}, $c->stash->{vt_base}, | ||
299 | + $c->stash->{last_vt_base}, $c->stash->{vt_base}, | ||
300 | + ); | ||
345 | 301 | ||
346 | - LEFT JOIN estado_atendimento AS es_aten_ini ON (times.vt_fac = es_aten_ini.vt_ini | ||
347 | - AND es_aten_ini.id_estado=(SELECT id_estado FROM tipo_estado_atendimento WHERE nome='atendimento')) | 302 | + my $sth_inner = $dbi->prepare($sql_estados_categorias); |
348 | 303 | ||
349 | - LEFT JOIN atendimento AS at_aten_ini ON | ||
350 | - ( es_aten_ini.id_atendimento = at_aten_ini.id_atendimento AND | ||
351 | - at_aten_ini.id_local = ? ) | 304 | + my $dlocal = $c->model('DB::DLocal')->get_dimension($local); |
305 | + my $cat_cache = {}; | ||
306 | + | ||
307 | + while (my ($datahora) = $sth->fetchrow_array) { | ||
308 | + my $datahora_dt = DateTime::Format::Pg->parse_datetime($datahora); | ||
309 | + my $data = $c->model('DB::DData')->get_dimension($datahora_dt); | ||
310 | + my $horario = $c->model('DB::DHorario')->get_dimension($datahora_dt); | ||
311 | + my $counters_cat = {}; | ||
312 | + | ||
313 | + $sth_inner->execute($datahora,$datahora,$id,$datahora,$datahora); | ||
314 | + while (my $item = $sth_inner->fetchrow_hashref) { | ||
315 | + my $id_categoria = $item->{id_categoria}; | ||
316 | + $counters_cat->{$id_categoria}{$item->{nome_estado}} = $item->{quantidade}; | ||
317 | + $counters_cat->{$id_categoria}{categoria}{codigo} = $item->{codigo}; | ||
318 | + $counters_cat->{$id_categoria}{categoria}{codigo} = $item->{nome}; | ||
319 | + } | ||
320 | + | ||
321 | + foreach my $id_categoria (keys %{$counters_cat}) { | ||
322 | + unless (exists $cat_cache->{$id_categoria}) { | ||
323 | + $cat_cache->{$id_categoria} = $c->model('DB::DCategoria')->get_dimension | ||
324 | + (Fila::Servico::DB::Categoria->new | ||
325 | + ({ map { $_ => $counters_cat->{$id_categoria}{categoria}{$_} | ||
326 | + } qw(id_categoria nome codigo) })); | ||
327 | + } | ||
328 | + my $categoria = $cat_cache->{$id_categoria}; | ||
329 | + | ||
330 | + $c->model('DB::FQuantidadeEstados')->create | ||
331 | + ({ id_local => $dlocal, | ||
332 | + id_categoria => $categoria, | ||
333 | + data => $data, | ||
334 | + horario => $horario, | ||
335 | + | ||
336 | + ( map { 'quantidade_'.$_ => ($counters_cat->{$id_categoria}{$_} || 0) } | ||
337 | + 'espera', | ||
338 | + 'chamando', | ||
339 | + 'atendimento', | ||
340 | + 'avaliacao' | ||
341 | + ) | ||
342 | + }); | ||
343 | + } | ||
352 | 344 | ||
353 | - LEFT JOIN categoria_atendimento AS cs_aten_ini ON | ||
354 | - ( at_aten_ini.id_atendimento = cs_aten_ini.id_atendimento) | 345 | + } |
355 | 346 | ||
356 | - LEFT JOIN categoria AS ct_aten_ini ON | ||
357 | - ( cs_aten_ini.id_categoria = ct_aten_ini.id_categoria) | 347 | + $c->model('DB::ActivityLog')->create |
348 | + ({ activity_type => '/atendimento/estados', | ||
349 | + id_local => $id, | ||
350 | + vt_base => $c->stash->{vt_base}, | ||
351 | + vt_ini => $c->stash->{now} }); | ||
358 | 352 | ||
359 | - LEFT JOIN estado_atendimento AS es_aten_fim ON (times.vt_fac = es_aten_fim.vt_fim | ||
360 | - AND es_aten_fim.id_estado=(SELECT id_estado FROM tipo_estado_atendimento WHERE nome='atendimento')) | 353 | + }); |
361 | 354 | ||
362 | - LEFT JOIN atendimento AS at_aten_fim ON | ||
363 | - ( es_aten_fim.id_atendimento = at_aten_fim.id_atendimento AND | ||
364 | - at_aten_fim.id_local = ? ) | 355 | +} |
365 | 356 | ||
366 | - LEFT JOIN categoria_atendimento AS cs_aten_fim ON | ||
367 | - ( at_aten_fim.id_atendimento = cs_aten_fim.id_atendimento) | 357 | +sub no_show :Chained('atendimento') :PathPart :Args(0) { |
358 | + my ($self, $c) = @_; | ||
368 | 359 | ||
369 | - LEFT JOIN categoria AS ct_aten_fim ON | ||
370 | - ( cs_aten_fim.id_categoria = ct_aten_fim.id_categoria) | 360 | + $c->model('Federado')->doeach |
361 | + ($c, sub { | ||
362 | + my $id = shift; | ||
371 | 363 | ||
372 | - LEFT JOIN estado_atendimento AS es_no_show ON (times.vt_fac = es_no_show.vt_ini | ||
373 | - AND es_no_show.id_estado=(SELECT id_estado FROM tipo_estado_atendimento WHERE nome='no_show')) | 364 | + my $result = $c->model('DB::ActivityLog')->search |
365 | + ({ activity_type => '/atendimento/no_show', | ||
366 | + id_local => $id }, | ||
367 | + { order_by => 'vt_base DESC' }); | ||
374 | 368 | ||
375 | - LEFT JOIN atendimento AS at_no_show ON | ||
376 | - ( es_no_show.id_atendimento = at_no_show.id_atendimento AND | ||
377 | - at_no_show.id_local = ? ) | 369 | + if (my $last = $result->first) { |
370 | + $c->stash->{last_vt_base} = $last->vt_base; | ||
371 | + } else { | ||
372 | + $c->stash->{last_vt_base} = '-Infinity'; | ||
373 | + } | ||
378 | 374 | ||
379 | - LEFT JOIN categoria_atendimento AS cs_no_show ON | ||
380 | - ( at_no_show.id_atendimento = cs_no_show.id_atendimento) | 375 | + my $local = $c->model('Federado')->target($c, $id, 'Local')->find |
376 | + ({ id_local => $id }); | ||
381 | 377 | ||
382 | - LEFT JOIN categoria AS ct_no_show ON | ||
383 | - ( cs_no_show.id_categoria = ct_no_show.id_categoria) | 378 | + my $sql = q# |
379 | +SELECT | ||
380 | + DATE_TRUNC('minute', estado_atendimento.vt_ini) AS datahora, | ||
381 | + COUNT(estado_atendimento.*) AS quantidade, | ||
382 | + categoria.nome, categoria.codigo, categoria.id_categoria | ||
384 | 383 | ||
385 | -GROUP BY date_trunc('minute',times.vt_fac), | ||
386 | - ct_espe_ini.id_categoria, ct_espe_ini.nome, ct_espe_ini.codigo, | ||
387 | - ct_espe_fim.id_categoria, ct_espe_fim.nome, ct_espe_fim.codigo, | ||
388 | - ct_cham_ini.id_categoria, ct_cham_ini.nome, ct_cham_ini.codigo, | ||
389 | - ct_cham_fim.id_categoria, ct_cham_fim.nome, ct_cham_fim.codigo, | ||
390 | - ct_aten_ini.id_categoria, ct_aten_ini.nome, ct_aten_ini.codigo, | ||
391 | - ct_aten_fim.id_categoria, ct_aten_fim.nome, ct_aten_fim.codigo, | ||
392 | - ct_no_show.id_categoria, ct_no_show.nome, ct_no_show.codigo | 384 | +FROM |
385 | + tipo_estado_atendimento INNER JOIN | ||
386 | + estado_atendimento | ||
387 | + ON (tipo_estado_atendimento.id_estado=estado_atendimento.id_estado AND | ||
388 | + estado_atendimento.vt_ini > ? AND | ||
389 | + estado_atendimento.vt_ini <= ?) INNER JOIN | ||
390 | + atendimento | ||
391 | + ON (estado_atendimento.id_atendimento=atendimento.id_atendimento AND | ||
392 | + atendimento.id_local = ? AND | ||
393 | + atendimento.vt_ini > ? AND | ||
394 | + atendimento.vt_ini <= ?) INNER JOIN | ||
395 | + categoria_atendimento | ||
396 | + ON (categoria_atendimento.id_atendimento=atendimento.id_atendimento AND | ||
397 | + categoria_atendimento.vt_ini <= estado_atendimento.vt_ini AND | ||
398 | + categoria_atendimento.vt_fim > estado_atendimento.vt_ini) INNER JOIN | ||
399 | + categoria USING (id_categoria) | ||
400 | + | ||
401 | +WHERE tipo_estado_atendimento.nome='no_show' | ||
393 | 402 | ||
394 | -ORDER BY datahora | 403 | +GROUP BY |
404 | + DATE_TRUNC('minute', estado_atendimento.vt_ini), | ||
405 | + categoria.nome, categoria.codigo, categoria.id_categoria | ||
395 | 406 | ||
396 | #; | 407 | #; |
397 | 408 | ||
@@ -401,157 +412,47 @@ ORDER BY datahora | @@ -401,157 +412,47 @@ ORDER BY datahora | ||
401 | 412 | ||
402 | my $sth = $dbi->prepare($sql); | 413 | my $sth = $dbi->prepare($sql); |
403 | $sth->execute( $c->stash->{last_vt_base}, $c->stash->{vt_base}, | 414 | $sth->execute( $c->stash->{last_vt_base}, $c->stash->{vt_base}, |
404 | - $c->stash->{last_vt_base}, $c->stash->{vt_base}, | ||
405 | - map { $id } 1..7 ); | 415 | + $id, |
416 | + $c->stash->{last_vt_base}, $c->stash->{vt_base}, | ||
417 | + ); | ||
406 | 418 | ||
407 | my $dlocal = $c->model('DB::DLocal')->get_dimension($local); | 419 | my $dlocal = $c->model('DB::DLocal')->get_dimension($local); |
408 | - my $last_datahora; | ||
409 | - my $counters_cat = {}; | ||
410 | - my $last_data; | 420 | + my $cat_cache = {}; |
411 | 421 | ||
412 | while (my $item = $sth->fetchrow_hashref) { | 422 | while (my $item = $sth->fetchrow_hashref) { |
413 | - | ||
414 | - if ($last_datahora && $item->{datahora} ne $last_datahora) { | ||
415 | - | ||
416 | - # inserir registros para cada categoria | ||
417 | - my $data = $c->model('DB::DData')->get_dimension | ||
418 | - ( DateTime::Format::Pg->parse_datetime($last_datahora) ); | ||
419 | - my $horario = $c->model('DB::DHorario')->get_dimension | ||
420 | - ( DateTime::Format::Pg->parse_datetime($last_datahora) ); | ||
421 | - | ||
422 | - foreach my $id_categoria (keys %{$counters_cat}) { | ||
423 | - | ||
424 | - my $categoria = $c->model('DB::DCategoria')->get_dimension | ||
425 | - (Fila::Servico::DB::Categoria->new | ||
426 | - ({ map { $_ => $counters_cat->{$id_categoria}{categoria}{$_} | ||
427 | - } qw(id_categoria nome codigo) })); | ||
428 | - | ||
429 | - | ||
430 | - $c->model('DB::FQuantidadeEstados')->create | ||
431 | - ({ id_local => $dlocal, | ||
432 | - id_categoria => $categoria, | ||
433 | - data => $data, | ||
434 | - horario => $horario, | ||
435 | - | ||
436 | - ( map { 'quantidade_'.$_ => ($counters_cat->{$id_categoria}{$_} || 0) } | ||
437 | - 'espera', | ||
438 | - 'chamando', | ||
439 | - 'atendimento', | ||
440 | - 'no_show' | ||
441 | - ) | ||
442 | - }); | ||
443 | - | ||
444 | - $counters_cat->{$id_categoria}{no_show} = 0; | ||
445 | - } | ||
446 | - | ||
447 | - $last_datahora = $item->{datahora}; | ||
448 | - if ($last_data ne $data) { | ||
449 | - $last_datahora = undef; | ||
450 | - $last_data = undef; | ||
451 | - } | ||
452 | - | ||
453 | - } | ||
454 | - if (not $last_datahora ) { | ||
455 | - # vamos obter os contadores iniciais para aquela datahora | ||
456 | - | ||
457 | - my $sql_quant = q# | ||
458 | - | ||
459 | -SELECT | ||
460 | - cat_est.estado, | ||
461 | - cat_est.id_categoria, | ||
462 | - cat_est.codigo, | ||
463 | - cat_est.nome, | ||
464 | - COUNT(categoria_atendimento.*) as total | ||
465 | -FROM | ||
466 | - ( SELECT tipo_estado_atendimento.id_estado, | ||
467 | - tipo_estado_atendimento.nome AS estado, categoria.id_categoria, | ||
468 | - categoria.codigo, categoria.nome FROM tipo_estado_atendimento, | ||
469 | - categoria | ||
470 | - WHERE | ||
471 | - tipo_estado_atendimento.nome IN ('espera','chamando','atendimento') | ||
472 | - ) AS cat_est | ||
473 | - INNER JOIN estado_atendimento | ||
474 | - ON (estado_atendimento.id_estado = cat_est.id_estado AND | ||
475 | - ? BETWEEN estado_atendimento.vt_ini AND estado_atendimento.vt_fim) | ||
476 | - INNER JOIN atendimento | ||
477 | - ON (estado_atendimento.id_atendimento = atendimento.id_atendimento AND | ||
478 | - ? BETWEEN atendimento.vt_ini AND atendimento.vt_fim) | ||
479 | - INNER JOIN categoria_atendimento | ||
480 | - ON (atendimento.id_atendimento = categoria_atendimento.id_atendimento AND | ||
481 | - categoria_atendimento.id_categoria = cat_est.id_categoria) | ||
482 | -GROUP BY | ||
483 | - cat_est.estado, | ||
484 | - cat_est.id_categoria, | ||
485 | - cat_est.codigo, | ||
486 | - cat_est.nome | ||
487 | - | ||
488 | -#; | ||
489 | - | ||
490 | - my $sth = $dbi->prepare($sql_quant); | ||
491 | - $sth->execute($item->{datahora}, $item->{datahora}); | ||
492 | - | ||
493 | - $counters_cat = {}; | ||
494 | - | ||
495 | - while (my $cat_est = $sth->fetchrow_hashref) { | ||
496 | - $counters_cat->{$cat_est->{id_categoria}}{categoria} = $cat_est; | ||
497 | - $counters_cat->{$cat_est->{id_categoria}}{$cat_est->{estado}} = $cat_est->{total}; | ||
498 | - $counters_cat->{$cat_est->{id_categoria}}{no_show} = 0; | ||
499 | - } | ||
500 | - | ||
501 | - $last_datahora = $item->{datahora}; | ||
502 | - $last_data = $last_datahora; | ||
503 | - $last_data =~ s/\s.+$//; | ||
504 | - } | ||
505 | - | ||
506 | - # vamos calcular os contadores | ||
507 | - if ($item->{espe_ini}) { | ||
508 | - $counters_cat->{$item->{ct_espe_ini_id_categoria}}{espera} += $item->{espe_ini}; | ||
509 | - $counters_cat->{$item->{ct_espe_ini_id_categoria}}{categoria}{codigo} = $item->{ct_espe_ini_codigo}; | ||
510 | - $counters_cat->{$item->{ct_espe_ini_id_categoria}}{categoria}{nome} = $item->{ct_espe_ini_nome}; | ||
511 | - } | ||
512 | - if ($item->{espe_fim}) { | ||
513 | - $counters_cat->{$item->{ct_espe_fim_id_categoria}}{espera} -= $item->{espe_fim}; | ||
514 | - $counters_cat->{$item->{ct_espe_fim_id_categoria}}{categoria}{codigo} = $item->{ct_espe_fim_codigo}; | ||
515 | - $counters_cat->{$item->{ct_espe_fim_id_categoria}}{categoria}{nome} = $item->{ct_espe_fim_nome}; | ||
516 | - } | ||
517 | - if ($item->{cham_ini}) { | ||
518 | - $counters_cat->{$item->{ct_cham_ini_id_categoria}}{chamando} += $item->{cham_ini}; | ||
519 | - $counters_cat->{$item->{ct_cham_ini_id_categoria}}{categoria}{codigo} = $item->{ct_cham_ini_codigo}; | ||
520 | - $counters_cat->{$item->{ct_cham_ini_id_categoria}}{categoria}{nome} = $item->{ct_cham_ini_nome}; | ||
521 | - } | ||
522 | - if ($item->{cham_fim}) { | ||
523 | - $counters_cat->{$item->{ct_cham_fim_id_categoria}}{chamando} -= $item->{cham_fim}; | ||
524 | - $counters_cat->{$item->{ct_cham_fim_id_categoria}}{categoria}{codigo} = $item->{ct_cham_fim_codigo}; | ||
525 | - $counters_cat->{$item->{ct_cham_fim_id_categoria}}{categoria}{nome} = $item->{ct_cham_fim_nome}; | ||
526 | - } | ||
527 | - if ($item->{aten_ini}) { | ||
528 | - $counters_cat->{$item->{ct_aten_ini_id_categoria}}{atendimento} += $item->{aten_ini}; | ||
529 | - $counters_cat->{$item->{ct_aten_ini_id_categoria}}{categoria}{codigo} = $item->{ct_aten_ini_codigo}; | ||
530 | - $counters_cat->{$item->{ct_aten_ini_id_categoria}}{categoria}{nome} = $item->{ct_aten_ini_nome}; | ||
531 | - } | ||
532 | - if ($item->{aten_fim}) { | ||
533 | - $counters_cat->{$item->{ct_aten_fim_id_categoria}}{atendimento} -= $item->{aten_fim}; | ||
534 | - $counters_cat->{$item->{ct_aten_fim_id_categoria}}{categoria}{codigo} = $item->{ct_aten_fim_codigo}; | ||
535 | - $counters_cat->{$item->{ct_aten_fim_id_categoria}}{categoria}{nome} = $item->{ct_aten_fim_nome}; | ||
536 | - } | ||
537 | - if ($item->{no_show}) { | ||
538 | - $counters_cat->{$item->{ct_no_show_id_categoria}}{no_show} += $item->{no_show}; | ||
539 | - $counters_cat->{$item->{ct_no_show_id_categoria}}{categoria}{codigo} = $item->{ct_no_show_codigo}; | ||
540 | - $counters_cat->{$item->{ct_no_show_id_categoria}}{categoria}{nome} = $item->{ct_no_show_nome}; | ||
541 | - } | ||
542 | - | 423 | + my $datahora = $item->{datahora}; |
424 | + my $datahora_dt = DateTime::Format::Pg->parse_datetime($datahora); | ||
425 | + my $data = $c->model('DB::DData')->get_dimension($datahora_dt); | ||
426 | + my $horario = $c->model('DB::DHorario')->get_dimension($datahora_dt); | ||
427 | + my $id_categoria = $item->{id_categoria}; | ||
428 | + | ||
429 | + unless (exists $cat_cache->{$id_categoria}) { | ||
430 | + $cat_cache->{$id_categoria} = $c->model('DB::DCategoria')->get_dimension | ||
431 | + (Fila::Servico::DB::Categoria->new | ||
432 | + ({ map { $_ => $item->{$_} | ||
433 | + } qw(id_categoria nome codigo) })); | ||
434 | + } | ||
435 | + my $categoria = $cat_cache->{$id_categoria}; | ||
436 | + | ||
437 | + $c->model('DB::FQuantidadeEstados')->create | ||
438 | + ({ id_local => $dlocal, | ||
439 | + id_categoria => $categoria, | ||
440 | + data => $data, | ||
441 | + horario => $horario, | ||
442 | + quantidade => $item->{quantidade} | ||
443 | + }); | ||
543 | } | 444 | } |
544 | 445 | ||
446 | + | ||
545 | $c->model('DB::ActivityLog')->create | 447 | $c->model('DB::ActivityLog')->create |
546 | - ({ activity_type => '/atendimento/estados', | 448 | + ({ activity_type => '/atendimento/no_show', |
547 | id_local => $id, | 449 | id_local => $id, |
548 | vt_base => $c->stash->{vt_base}, | 450 | vt_base => $c->stash->{vt_base}, |
549 | vt_ini => $c->stash->{now} }); | 451 | vt_ini => $c->stash->{now} }); |
550 | 452 | ||
551 | }); | 453 | }); |
552 | 454 | ||
553 | - | ||
554 | - | ||
555 | } | 455 | } |
556 | 456 | ||
457 | + | ||
557 | 1; | 458 | 1; |
@@ -0,0 +1,147 @@ | @@ -0,0 +1,147 @@ | ||
1 | +package Fila::ETL::Controller::Guiches; | ||
2 | +# Copyright 2008, 2009 - Oktiva Comércio e Serviços de Informática Ltda. | ||
3 | +# | ||
4 | +# Este arquivo é parte do programa FILA - Sistema de Atendimento | ||
5 | +# | ||
6 | +# O FILA é um software livre; você pode redistribui-lo e/ou modifica-lo | ||
7 | +# dentro dos termos da Licença Pública Geral GNU como publicada pela | ||
8 | +# Fundação do Software Livre (FSF); na versão 2 da Licença. | ||
9 | +# | ||
10 | +# Este programa é distribuido na esperança que possa ser util, mas SEM | ||
11 | +# NENHUMA GARANTIA; sem uma garantia implicita de ADEQUAÇÂO a qualquer | ||
12 | +# MERCADO ou APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU | ||
13 | +# para maiores detalhes. | ||
14 | +# | ||
15 | +# Você deve ter recebido uma cópia da Licença Pública Geral GNU, sob o | ||
16 | +# título "LICENCA.txt", junto com este programa, se não, escreva para a | ||
17 | +# Fundação do Software Livre(FSF) Inc., 51 Franklin St, Fifth Floor, | ||
18 | + | ||
19 | +use strict; | ||
20 | +use warnings; | ||
21 | +use List::Util qw(sum); | ||
22 | +use base qw(Catalyst::Controller); | ||
23 | + | ||
24 | +sub guiches :Chained('/base') :PathPart :CaptureArgs(0) { | ||
25 | + my ($self, $c) = @_; | ||
26 | + $c->stash->{vt_base} = $c->stash->{now}; | ||
27 | +} | ||
28 | + | ||
29 | +sub estados :Chained('guiches') :PathPart :Args(0) { | ||
30 | + my ($self, $c) = @_; | ||
31 | + | ||
32 | + $c->model('Federado')->doeach | ||
33 | + ($c, sub { | ||
34 | + my $id = shift; | ||
35 | + | ||
36 | + my $result = $c->model('DB::ActivityLog')->search | ||
37 | + ({ activity_type => '/guiches/estados', | ||
38 | + id_local => $id }, | ||
39 | + { order_by => 'vt_base DESC' }); | ||
40 | + | ||
41 | + if (my $last = $result->first) { | ||
42 | + $c->stash->{last_vt_base} = $last->vt_base; | ||
43 | + } else { | ||
44 | + $c->stash->{last_vt_base} = '-Infinity'; | ||
45 | + } | ||
46 | + | ||
47 | + my $local = $c->model('Federado')->target($c, $id, 'Local')->find | ||
48 | + ({ id_local => $id }); | ||
49 | + | ||
50 | + my $sql_times = q{ | ||
51 | +SELECT | ||
52 | + DISTINCT DATE_TRUNC('minute', estado_guiche.vt_ini) + '59.9999999 seconds' AS vt_fac | ||
53 | +FROM | ||
54 | + guiche LEFT JOIN | ||
55 | + estado_guiche USING (id_guiche) | ||
56 | +WHERE | ||
57 | + guiche.id_local = ? AND | ||
58 | + guiche.vt_ini >= ? AND | ||
59 | + guiche.vt_ini < ? AND | ||
60 | + estado_guiche.vt_ini >= ? AND | ||
61 | + estado_guiche.vt_ini < ? | ||
62 | +}; | ||
63 | + | ||
64 | + my $sql_estados = q{ | ||
65 | +SELECT | ||
66 | + COUNT(tipo_estado_guiche.*) as quantidade, | ||
67 | + tipo_estado_guiche.nome as nome_estado | ||
68 | + | ||
69 | +FROM | ||
70 | + guiche LEFT JOIN | ||
71 | + estado_guiche | ||
72 | + ON (guiche.id_guiche=estado_guiche.id_guiche AND | ||
73 | + estado_guiche.vt_ini <= ? AND | ||
74 | + estado_guiche.vt_fim > ?) LEFT JOIN | ||
75 | + tipo_estado_guiche USING (id_estado) | ||
76 | + | ||
77 | +WHERE tipo_estado_guiche.nome IS NOT NULL | ||
78 | + AND guiche.id_local=? | ||
79 | + | ||
80 | +GROUP BY | ||
81 | + tipo_estado_guiche.nome | ||
82 | + | ||
83 | + | ||
84 | +}; | ||
85 | + | ||
86 | + my $storage = $c->model('Federado')->storage($c, $id); | ||
87 | + $storage->ensure_connected; | ||
88 | + my $dbi = $storage->dbh; | ||
89 | + | ||
90 | + my $sth = $dbi->prepare($sql_times); | ||
91 | + $sth->execute( $id, | ||
92 | + $c->stash->{last_vt_base}, $c->stash->{vt_base}, | ||
93 | + $c->stash->{last_vt_base}, $c->stash->{vt_base}, | ||
94 | + ); | ||
95 | + | ||
96 | + my $sth_inner = $dbi->prepare($sql_estados); | ||
97 | + | ||
98 | + my $dlocal = $c->model('DB::DLocal')->get_dimension($local); | ||
99 | + my $func_cache = {}; | ||
100 | + my $guic_cache = {}; | ||
101 | + | ||
102 | + while (my ($datahora) = $sth->fetchrow_array) { | ||
103 | + my $datahora_dt = DateTime::Format::Pg->parse_datetime($datahora); | ||
104 | + my $data = $c->model('DB::DData')->get_dimension($datahora_dt); | ||
105 | + my $horario = $c->model('DB::DHorario')->get_dimension($datahora_dt); | ||
106 | + my $counters = {}; | ||
107 | + | ||
108 | + $sth_inner->execute($datahora,$datahora,$id); | ||
109 | + while (my $item = $sth_inner->fetchrow_hashref) { | ||
110 | + $counters->{$item->{nome_estado}} = $item->{quantidade}; | ||
111 | + } | ||
112 | + | ||
113 | + $c->model('DB::FEstadosGuiches')->create | ||
114 | + ({ id_local => $dlocal, | ||
115 | + data => $data, | ||
116 | + horario => $horario, | ||
117 | + quantidade_publico => | ||
118 | + sum( map { $counters->{$_} || 0 } | ||
119 | + 'disponivel', | ||
120 | + 'chamando', | ||
121 | + 'atendimento', | ||
122 | + 'avaliacao', | ||
123 | + 'concluido' | ||
124 | + ), | ||
125 | + ( map { 'quantidade_'.$_ => ($counters->{$_} || 0) } | ||
126 | + 'fechado', | ||
127 | + 'pausa', | ||
128 | + 'interno', | ||
129 | + 'disponivel', | ||
130 | + 'chamando', | ||
131 | + 'atendimento', | ||
132 | + 'avaliacao', | ||
133 | + 'concluido' | ||
134 | + ) | ||
135 | + }); | ||
136 | + } | ||
137 | + | ||
138 | + $c->model('DB::ActivityLog')->create | ||
139 | + ({ activity_type => '/guiches/estados', | ||
140 | + id_local => $id, | ||
141 | + vt_base => $c->stash->{vt_base}, | ||
142 | + vt_ini => $c->stash->{now} }); | ||
143 | + | ||
144 | + }); | ||
145 | + | ||
146 | +} | ||
147 | +1; |
@@ -0,0 +1,91 @@ | @@ -0,0 +1,91 @@ | ||
1 | +package Fila::ETL::DB::FEstadosGuiches; | ||
2 | +# Copyright 2008, 2009 - Oktiva Comércio e Serviços de Informática Ltda. | ||
3 | +# | ||
4 | +# Este arquivo é parte do programa FILA - Sistema de Atendimento | ||
5 | +# | ||
6 | +# O FILA é um software livre; você pode redistribui-lo e/ou modifica-lo | ||
7 | +# dentro dos termos da Licença Pública Geral GNU como publicada pela | ||
8 | +# Fundação do Software Livre (FSF); na versão 2 da Licença. | ||
9 | +# | ||
10 | +# Este programa é distribuido na esperança que possa ser util, mas SEM | ||
11 | +# NENHUMA GARANTIA; sem uma garantia implicita de ADEQUAÇÂO a qualquer | ||
12 | +# MERCADO ou APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU | ||
13 | +# para maiores detalhes. | ||
14 | +# | ||
15 | +# Você deve ter recebido uma cópia da Licença Pública Geral GNU, sob o | ||
16 | +# título "LICENCA.txt", junto com este programa, se não, escreva para a | ||
17 | +# Fundação do Software Livre(FSF) Inc., 51 Franklin St, Fifth Floor, | ||
18 | + | ||
19 | +use strict; | ||
20 | +use warnings; | ||
21 | +use base qw(DBIx::Class); | ||
22 | + | ||
23 | +__PACKAGE__->load_components(qw(Core)); | ||
24 | +__PACKAGE__->table('f_estados_guiches'); | ||
25 | +__PACKAGE__->add_columns | ||
26 | + ( | ||
27 | + id_local => | ||
28 | + { | ||
29 | + data_type => 'integer', | ||
30 | + }, | ||
31 | + data => | ||
32 | + { | ||
33 | + data_type => 'char(10)', | ||
34 | + }, | ||
35 | + horario => | ||
36 | + { | ||
37 | + data_type => 'char(5)', | ||
38 | + }, | ||
39 | + quantidade_fechado => | ||
40 | + { | ||
41 | + data_type => 'integer', | ||
42 | + }, | ||
43 | + quantidade_publico => | ||
44 | + { | ||
45 | + data_type => 'integer', | ||
46 | + }, | ||
47 | + quantidade_pausa => | ||
48 | + { | ||
49 | + data_type => 'integer', | ||
50 | + }, | ||
51 | + quantidade_interno => | ||
52 | + { | ||
53 | + data_type => 'integer', | ||
54 | + }, | ||
55 | + quantidade_disponivel => | ||
56 | + { | ||
57 | + data_type => 'integer', | ||
58 | + }, | ||
59 | + quantidade_chamando => | ||
60 | + { | ||
61 | + data_type => 'integer', | ||
62 | + }, | ||
63 | + quantidade_atendimento => | ||
64 | + { | ||
65 | + data_type => 'integer', | ||
66 | + }, | ||
67 | + quantidade_avaliacao => | ||
68 | + { | ||
69 | + data_type => 'integer', | ||
70 | + }, | ||
71 | + quantidade_concluido => | ||
72 | + { | ||
73 | + data_type => 'integer', | ||
74 | + }, | ||
75 | + ); | ||
76 | + | ||
77 | + | ||
78 | +1; | ||
79 | + | ||
80 | +__END__ | ||
81 | + | ||
82 | +=head1 NAME | ||
83 | + | ||
84 | +FQuantidadeEstados - Tabela de quantidades por estado de atendimento | ||
85 | + | ||
86 | +=head1 DESCRIPTION | ||
87 | + | ||
88 | +Esta tabela contem o total de atendimentos em um determinado estado | ||
89 | +por local, categoria, data, hora e minuto. | ||
90 | + | ||
91 | +=cut |
@@ -0,0 +1,63 @@ | @@ -0,0 +1,63 @@ | ||
1 | +package Fila::ETL::DB::FNoShow; | ||
2 | +# Copyright 2008, 2009 - Oktiva Comércio e Serviços de Informática Ltda. | ||
3 | +# | ||
4 | +# Este arquivo é parte do programa FILA - Sistema de Atendimento | ||
5 | +# | ||
6 | +# O FILA é um software livre; você pode redistribui-lo e/ou modifica-lo | ||
7 | +# dentro dos termos da Licença Pública Geral GNU como publicada pela | ||
8 | +# Fundação do Software Livre (FSF); na versão 2 da Licença. | ||
9 | +# | ||
10 | +# Este programa é distribuido na esperança que possa ser util, mas SEM | ||
11 | +# NENHUMA GARANTIA; sem uma garantia implicita de ADEQUAÇÂO a qualquer | ||
12 | +# MERCADO ou APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU | ||
13 | +# para maiores detalhes. | ||
14 | +# | ||
15 | +# Você deve ter recebido uma cópia da Licença Pública Geral GNU, sob o | ||
16 | +# título "LICENCA.txt", junto com este programa, se não, escreva para a | ||
17 | +# Fundação do Software Livre(FSF) Inc., 51 Franklin St, Fifth Floor, | ||
18 | + | ||
19 | +use strict; | ||
20 | +use warnings; | ||
21 | +use base qw(DBIx::Class); | ||
22 | + | ||
23 | +__PACKAGE__->load_components(qw(Core)); | ||
24 | +__PACKAGE__->table('f_no_show'); | ||
25 | +__PACKAGE__->add_columns | ||
26 | + ( | ||
27 | + id_local => | ||
28 | + { | ||
29 | + data_type => 'integer', | ||
30 | + }, | ||
31 | + id_categoria => | ||
32 | + { | ||
33 | + data_type => 'integer', | ||
34 | + }, | ||
35 | + data => | ||
36 | + { | ||
37 | + data_type => 'char(10)', | ||
38 | + }, | ||
39 | + horario => | ||
40 | + { | ||
41 | + data_type => 'char(5)', | ||
42 | + }, | ||
43 | + quantidade => | ||
44 | + { | ||
45 | + data_type => 'integer', | ||
46 | + } | ||
47 | + ); | ||
48 | + | ||
49 | + | ||
50 | +1; | ||
51 | + | ||
52 | +__END__ | ||
53 | + | ||
54 | +=head1 NAME | ||
55 | + | ||
56 | +FQuantidadeEstados - Tabela de quantidades por estado de atendimento | ||
57 | + | ||
58 | +=head1 DESCRIPTION | ||
59 | + | ||
60 | +Esta tabela contem o total de atendimentos em um determinado estado | ||
61 | +por local, categoria, data, hora e minuto. | ||
62 | + | ||
63 | +=cut |
Fila-ETL/lib/Fila/ETL/DB/FQuantidadeEstados.pm