Commit 6991188ac41eb236d2cf11f8a29cdada34bcb354
1 parent
ce1ecf14
Exists in
master
avancando mais ainda no etl...
git-svn-id: http://svn.softwarepublico.gov.br/svn/sistemadeatendimento/sistema/trunk@9 63db2ce5-8a6c-0410-abb9-a418dd412890
Showing
7 changed files
with
409 additions
and
8 deletions
Show diff stats
@@ -0,0 +1,166 @@ | @@ -0,0 +1,166 @@ | ||
1 | +package Fila::ETL::Controller::Opiniao; | ||
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(Catalyst::Controller); | ||
22 | + | ||
23 | +sub opiniao :Chained('/base') :PathPart :CaptureArgs(0) { | ||
24 | + my ($self, $c) = @_; | ||
25 | + $c->stash->{vt_base} = $c->stash->{now}; | ||
26 | +} | ||
27 | + | ||
28 | +sub avaliacao :Chained('opiniao') :PathPart :Args(0) { | ||
29 | + my ($self, $c) = @_; | ||
30 | + | ||
31 | + $c->model('Federado')->doeach | ||
32 | + ($c, sub { | ||
33 | + my $id = shift; | ||
34 | + my $min = 'minute'; | ||
35 | + | ||
36 | + my $result = $c->model('DB::ActivityLog')->search | ||
37 | + ({ activity_type => '/opiniao/avaliacao', | ||
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 = q# | ||
51 | + | ||
52 | +SELECT DATE_TRUNC('minute', resposta_avaliacao.vt_fac) AS datahora, COUNT(*) AS | ||
53 | + quantidade, resposta, categoria.nome, categoria.codigo, | ||
54 | + categoria.id_categoria, pergunta_avaliacao.pergunta, funcionario.nome | ||
55 | + AS nome_func, funcionario.jid, guiche.identificador | ||
56 | + | ||
57 | +FROM | ||
58 | + resposta_avaliacao INNER JOIN | ||
59 | + pergunta_avaliacao USING (id_pergunta) INNER JOIN | ||
60 | + atendimento | ||
61 | + ON (resposta_avaliacao.id_atendimento=atendimento.id_atendimento AND | ||
62 | + atendimento.id_local=?) LEFT JOIN | ||
63 | + categoria_atendimento | ||
64 | + ON (atendimento.id_atendimento=categoria_atendimento.id_atendimento AND | ||
65 | + categoria_atendimento.vt_ini <= resposta_avaliacao.vt_fac AND | ||
66 | + categoria_atendimento.vt_fim >= resposta_avaliacao.vt_fac) LEFT JOIN | ||
67 | + categoria USING (id_categoria) LEFT JOIN | ||
68 | + guiche_atendimento | ||
69 | + ON (atendimento.id_atendimento=guiche_atendimento.id_atendimento AND | ||
70 | + guiche_atendimento.vt_ini <= resposta_avaliacao.vt_fac AND | ||
71 | + guiche_atendimento.vt_fim >= resposta_avaliacao.vt_fac) LEFT JOIN | ||
72 | + guiche USING (id_guiche) LEFT JOIN | ||
73 | + atendente_guiche | ||
74 | + ON (atendente_guiche.id_guiche=guiche.id_guiche AND | ||
75 | + atendente_guiche.vt_ini <= resposta_avaliacao.vt_fac AND | ||
76 | + atendente_guiche.vt_fim >= resposta_avaliacao.vt_fac) LEFT JOIN | ||
77 | + funcionario USING (id_funcionario) | ||
78 | + | ||
79 | +WHERE | ||
80 | + resposta_avaliacao.vt_fac > ? AND | ||
81 | + resposta_avaliacao.vt_fac <= ? | ||
82 | + | ||
83 | +GROUP BY DATE_TRUNC('minute', resposta_avaliacao.vt_fac), resposta, | ||
84 | + categoria.nome, categoria.codigo, categoria.id_categoria, pergunta, | ||
85 | + funcionario.nome, funcionario.jid, guiche.identificador | ||
86 | + | ||
87 | +#; | ||
88 | + | ||
89 | + my $storage = $c->model('Federado')->storage($c, $id); | ||
90 | + $storage->ensure_connected; | ||
91 | + my $dbi = $storage->dbh; | ||
92 | + | ||
93 | + my $sth = $dbi->prepare($sql); | ||
94 | + $sth->execute( $id, | ||
95 | + $c->stash->{last_vt_base}, $c->stash->{vt_base}, | ||
96 | + ); | ||
97 | + | ||
98 | + my $dlocal = $c->model('DB::DLocal')->get_dimension($local); | ||
99 | + my $func_cache = {}; | ||
100 | + my $cate_cache = {}; | ||
101 | + my $guic_cache = {}; | ||
102 | + my $perg_cache = {}; | ||
103 | + my $resp_cache = {}; | ||
104 | + | ||
105 | + while (my $item = $sth->fetchrow_hashref) { | ||
106 | + my $datahora = $item->{datahora}; | ||
107 | + my $datahora_dt = DateTime::Format::Pg->parse_datetime($datahora); | ||
108 | + my $data = $c->model('DB::DData')->get_dimension($datahora_dt); | ||
109 | + my $horario = $c->model('DB::DHorario')->get_dimension($datahora_dt); | ||
110 | + | ||
111 | + unless (exists $func_cache->{$item->{jid}}) { | ||
112 | + $func_cache->{$item->{jid}} = $c->model('DB::DAtendente') | ||
113 | + ->get_dimension({ nome => $item->{nome_func}, jid => $item->{jid}}); | ||
114 | + } | ||
115 | + my $func = $func_cache->{$item->{jid}}; | ||
116 | + | ||
117 | + unless (exists $cate_cache->{$item->{id_categoria}}) { | ||
118 | + $cate_cache->{$item->{id_categoria}} = | ||
119 | + $c->model('DB::DCategoria')->get_dimension($item); | ||
120 | + } | ||
121 | + my $cate = $cate_cache->{$item->{id_categoria}}; | ||
122 | + | ||
123 | + unless (exists $guic_cache->{$item->{identificador}}) { | ||
124 | + $guic_cache->{$item->{identificador}} = | ||
125 | + $c->model('DB::DGuiche')->get_dimension($item->{identificador}); | ||
126 | + } | ||
127 | + my $guic = $guic_cache->{$item->{identificador}}; | ||
128 | + | ||
129 | + unless (exists $perg_cache->{$item->{pergunta}}) { | ||
130 | + $perg_cache->{$item->{pergunta}} = | ||
131 | + $c->model('DB::DPerguntaAvaliacao')->get_dimension($item->{pergunta}); | ||
132 | + } | ||
133 | + my $perg = $perg_cache->{$item->{pergunta}}; | ||
134 | + | ||
135 | + unless (exists $resp_cache->{$item->{resposta}}) { | ||
136 | + $resp_cache->{$item->{resposta}} = | ||
137 | + $c->model('DB::DRespostaAvaliacao')->get_dimension($item->{resposta}); | ||
138 | + } | ||
139 | + my $resp = $resp_cache->{$item->{resposta}}; | ||
140 | + | ||
141 | + $c->model('DB::FAvaliacao')->create | ||
142 | + ({ id_local => $dlocal, | ||
143 | + data => $data, | ||
144 | + horario => $horario, | ||
145 | + id_guiche => $guic, | ||
146 | + id_categoria => $cate, | ||
147 | + id_atendente => $func, | ||
148 | + id_pergunta => $perg, | ||
149 | + id_resposta => $resp, | ||
150 | + quantidade => $item->{quantidade} | ||
151 | + }); | ||
152 | + } | ||
153 | + | ||
154 | + | ||
155 | + $c->model('DB::ActivityLog')->create | ||
156 | + ({ activity_type => '/opiniao/avaliacao', | ||
157 | + vt_base => $c->stash->{vt_base}, | ||
158 | + vt_ini => $c->stash->{now}, | ||
159 | + id_local => $id }); | ||
160 | + | ||
161 | + }); | ||
162 | + | ||
163 | + | ||
164 | +} | ||
165 | + | ||
166 | +1; |
Fila-ETL/lib/Fila/ETL/DB/DAtendente.pm
@@ -49,15 +49,23 @@ use base 'DBIx::Class::ResultSet'; | @@ -49,15 +49,23 @@ use base 'DBIx::Class::ResultSet'; | ||
49 | 49 | ||
50 | sub get_dimension { | 50 | sub get_dimension { |
51 | my ($self, $atendente) = @_; | 51 | my ($self, $atendente) = @_; |
52 | - my $matricula = $atendente->jid; | ||
53 | - $matricula =~ s/\@.+$//; | 52 | + my ($matricula, $nome); |
53 | + if (ref $atendente ne 'HASH') { | ||
54 | + $matricula = $atendente->jid; | ||
55 | + $matricula =~ s/\@.+$//; | ||
56 | + $nome = $atendente->nome; | ||
57 | + } else { | ||
58 | + $matricula = $atendente->{jid}; | ||
59 | + $matricula =~ s/\@.+$//; | ||
60 | + $nome = $atendente->{nome}; | ||
61 | + } | ||
54 | if (my $dim = $self->find({ matricula => $matricula })) { | 62 | if (my $dim = $self->find({ matricula => $matricula })) { |
55 | return $dim->id_atendente; | 63 | return $dim->id_atendente; |
56 | } else { | 64 | } else { |
57 | # TODO: Obter isso de um lugar mais inteligente; | 65 | # TODO: Obter isso de um lugar mais inteligente; |
58 | return $self->create | 66 | return $self->create |
59 | ({ matricula => $matricula ? $matricula : '', | 67 | ({ matricula => $matricula ? $matricula : '', |
60 | - nome => $atendente->nome })->id_atendente; | 68 | + nome => $nome })->id_atendente; |
61 | } | 69 | } |
62 | } | 70 | } |
63 | 71 |
Fila-ETL/lib/Fila/ETL/DB/DCategoria.pm
@@ -55,16 +55,23 @@ use base 'DBIx::Class::ResultSet'; | @@ -55,16 +55,23 @@ use base 'DBIx::Class::ResultSet'; | ||
55 | 55 | ||
56 | sub get_dimension { | 56 | sub get_dimension { |
57 | my ($self, $categoria) = @_; | 57 | my ($self, $categoria) = @_; |
58 | - my $nome = $categoria->nome; | 58 | + my ($codigo, $nome); |
59 | + if (ref $categoria eq 'HASH') { | ||
60 | + $codigo = $categoria->{codigo}; | ||
61 | + $nome = $categoria->{nome}; | ||
62 | + } else { | ||
63 | + $codigo = $categoria->{codigo}; | ||
64 | + $nome = $categoria->nome; | ||
65 | + } | ||
59 | if (my $dim = $self->find({ nome => $nome })) { | 66 | if (my $dim = $self->find({ nome => $nome })) { |
60 | return $dim->id_categoria; | 67 | return $dim->id_categoria; |
61 | } else { | 68 | } else { |
62 | # Aqui vamos presumir que se a categoria tem "preferencial" ou | 69 | # Aqui vamos presumir que se a categoria tem "preferencial" ou |
63 | # "prioritaria" no nome, ela é prioritária, senão ela é normal. | 70 | # "prioritaria" no nome, ela é prioritária, senão ela é normal. |
64 | return $self->create | 71 | return $self->create |
65 | - ({ nome => $categoria->nome, | ||
66 | - codigo => $categoria->codigo, | ||
67 | - prioritaria => $categoria->nome =~ /(prefer|priorit)/i ? 1 : 0 | 72 | + ({ nome => $nome, |
73 | + codigo => $codigo, | ||
74 | + prioritaria => $nome =~ /(prefer|priorit)/i ? 1 : 0 | ||
68 | })->id_categoria; | 75 | })->id_categoria; |
69 | } | 76 | } |
70 | } | 77 | } |
Fila-ETL/lib/Fila/ETL/DB/DGuiche.pm
@@ -45,7 +45,12 @@ use base 'DBIx::Class::ResultSet'; | @@ -45,7 +45,12 @@ use base 'DBIx::Class::ResultSet'; | ||
45 | 45 | ||
46 | sub get_dimension { | 46 | sub get_dimension { |
47 | my ($self, $guiche) = @_; | 47 | my ($self, $guiche) = @_; |
48 | - my $ident = $guiche->identificador; | 48 | + my $ident; |
49 | + if (ref $guiche) { | ||
50 | + $ident = $guiche->identificador; | ||
51 | + } else { | ||
52 | + $ident = $guiche; | ||
53 | + } | ||
49 | if (my $dim = $self->find({ identificador => $ident })) { | 54 | if (my $dim = $self->find({ identificador => $ident })) { |
50 | return $dim->id_guiche; | 55 | return $dim->id_guiche; |
51 | } else { | 56 | } else { |
@@ -0,0 +1,69 @@ | @@ -0,0 +1,69 @@ | ||
1 | +package Fila::ETL::DB::DPerguntaAvaliacao; | ||
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 PK::Auto)); | ||
24 | +__PACKAGE__->table('d_pergunta_avaliacao'); | ||
25 | +__PACKAGE__->add_columns | ||
26 | + ( | ||
27 | + id_pergunta => | ||
28 | + { | ||
29 | + data_type => 'integer', | ||
30 | + is_auto_increment => 1 | ||
31 | + }, | ||
32 | + texto => | ||
33 | + { | ||
34 | + data_type => 'varchar', | ||
35 | + is_nullable => 1, | ||
36 | + } | ||
37 | + ); | ||
38 | + | ||
39 | +__PACKAGE__->set_primary_key('id_pergunta'); | ||
40 | +__PACKAGE__->resultset_class('Fila::ETL::DB::DAtendente::RS'); | ||
41 | + | ||
42 | +package Fila::ETL::DB::DPerguntaAvaliacao::RS; | ||
43 | +use base 'DBIx::Class::ResultSet'; | ||
44 | + | ||
45 | +sub get_dimension { | ||
46 | + my ($self, $pergunta) = @_; | ||
47 | + my $texto = $pergunta->pergunta; | ||
48 | + if (my $dim = $self->find({ texto => $texto })) { | ||
49 | + return $dim->id_pergunta; | ||
50 | + } else { | ||
51 | + # TODO: Obter isso de um lugar mais inteligente; | ||
52 | + return $self->create | ||
53 | + ({ texto => $pergunta->pergunta })->id_pergunta; | ||
54 | + } | ||
55 | +} | ||
56 | + | ||
57 | +1; | ||
58 | + | ||
59 | +__END__ | ||
60 | + | ||
61 | +=head1 NAME | ||
62 | + | ||
63 | +DPerguntaAvaliacao - Tabela da dimensão "Pergunta Avaliacao" | ||
64 | + | ||
65 | +=head1 SYNOPSIS | ||
66 | + | ||
67 | +Essa tabela lista todas as entradas da dimensão "Pergunta Avaliacao". | ||
68 | + | ||
69 | +=cut |
@@ -0,0 +1,67 @@ | @@ -0,0 +1,67 @@ | ||
1 | +package Fila::ETL::DB::DRespostaAvaliacao; | ||
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 PK::Auto)); | ||
24 | +__PACKAGE__->table('d_resposta_avaliacao'); | ||
25 | +__PACKAGE__->add_columns | ||
26 | + ( | ||
27 | + id_resposta => | ||
28 | + { | ||
29 | + data_type => 'integer', | ||
30 | + is_auto_increment => 1 | ||
31 | + }, | ||
32 | + valor => | ||
33 | + { | ||
34 | + data_type => "varchar" | ||
35 | + } | ||
36 | + ); | ||
37 | + | ||
38 | +__PACKAGE__->set_primary_key('id_resposta'); | ||
39 | +__PACKAGE__->resultset_class('Fila::ETL::DB::DAtendente::RS'); | ||
40 | + | ||
41 | +package Fila::ETL::DB::DRespostaAvaliacao::RS; | ||
42 | +use base 'DBIx::Class::ResultSet'; | ||
43 | + | ||
44 | +sub get_dimension { | ||
45 | + my ($self, $resposta) = @_; | ||
46 | + my $valor = (qw(otimo bom regular ruim))[$resposta - 1]; | ||
47 | + if (my $dim = $self->find({ id_resposta => $resposta })) { | ||
48 | + return $resposta; | ||
49 | + } else { | ||
50 | + return $self->create | ||
51 | + ({ valor => $valor, id_resposta => $resposta })->id_resposta; | ||
52 | + } | ||
53 | +} | ||
54 | + | ||
55 | +1; | ||
56 | + | ||
57 | +__END__ | ||
58 | + | ||
59 | +=head1 NAME | ||
60 | + | ||
61 | +DRespostaAvaliacao - Tabela da dimensão "Resposta Avaliacao" | ||
62 | + | ||
63 | +=head1 SYNOPSIS | ||
64 | + | ||
65 | +Essa tabela lista todas as entradas da dimensão "Resposta Avaliacao". | ||
66 | + | ||
67 | +=cut |
@@ -0,0 +1,79 @@ | @@ -0,0 +1,79 @@ | ||
1 | +package Fila::ETL::DB::FAvaliacao; | ||
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_avaliacao'); | ||
25 | +__PACKAGE__->add_columns | ||
26 | + ( | ||
27 | + id_local => | ||
28 | + { | ||
29 | + data_type => 'integer', | ||
30 | + }, | ||
31 | + id_guiche => | ||
32 | + { | ||
33 | + data_type => 'integer', | ||
34 | + }, | ||
35 | + id_atendente => | ||
36 | + { | ||
37 | + data_type => 'integer', | ||
38 | + }, | ||
39 | + id_categoria => | ||
40 | + { | ||
41 | + data_type => 'integer', | ||
42 | + }, | ||
43 | + id_pergunta => | ||
44 | + { | ||
45 | + data_type => 'integer', | ||
46 | + }, | ||
47 | + id_resposta => | ||
48 | + { | ||
49 | + data_type => 'integer', | ||
50 | + }, | ||
51 | + data => | ||
52 | + { | ||
53 | + data_type => 'char(10)', | ||
54 | + }, | ||
55 | + horario => | ||
56 | + { | ||
57 | + data_type => 'char(5)', | ||
58 | + }, | ||
59 | + quantidade => | ||
60 | + { | ||
61 | + data_type => 'integer', | ||
62 | + } | ||
63 | + ); | ||
64 | + | ||
65 | + | ||
66 | +1; | ||
67 | + | ||
68 | +__END__ | ||
69 | + | ||
70 | +=head1 NAME | ||
71 | + | ||
72 | +FQuantidadeEstados - Tabela de quantidades por estado de atendimento | ||
73 | + | ||
74 | +=head1 DESCRIPTION | ||
75 | + | ||
76 | +Esta tabela contem o total de atendimentos em um determinado estado | ||
77 | +por local, categoria, data, hora e minuto. | ||
78 | + | ||
79 | +=cut |