Commit ce1ecf146edfe5ae5c63f082b1e5cdc35c287075

Authored by daniel@ruoso.com
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
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;
Fila-ETL/lib/Fila/ETL/Controller/Guiches.pm 0 → 100644
@@ -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;
Fila-ETL/lib/Fila/ETL/DB/FEstadosGuiches.pm 0 → 100644
@@ -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
Fila-ETL/lib/Fila/ETL/DB/FNoShow.pm 0 → 100644
@@ -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
@@ -52,7 +52,7 @@ __PACKAGE__-&gt;add_columns @@ -52,7 +52,7 @@ __PACKAGE__-&gt;add_columns
52 { 52 {
53 data_type => 'integer', 53 data_type => 'integer',
54 }, 54 },
55 - quantidade_no_show => 55 + quantidade_avaliacao =>
56 { 56 {
57 data_type => 'integer', 57 data_type => 'integer',
58 }, 58 },