Commit 5516a061c984eab2f4a93e5eb0934d2aa26ad823

Authored by Eriksen Costa Paixão
1 parent c35fd453
Exists in master

Atualizado relatório '''Alunos 5ª Avaliação''' para usar o ''service'' {{{Avalia…

…cao_Service_Boletim}}}:

 * Relatório chama-se agora '''Alunos em Exame''' pois não é mais subentendido que o ano letivo será dividido em 4 módulos bimestrais
 * Adicionado novo médoto em {{{TabelaArredondamento_Model_Tabela}}} {{{predictValue()}}} para prever qual é o primeiro arredondamento que satisfaz uma dada condição (ex: qual deve ser a nota no Exame para que o aluno obtenha a média necessária?)
ieducar/intranet/educar_relatorio_alunos_quinta_avaliacao.php
... ... @@ -48,7 +48,7 @@ class clsIndexBase extends clsBase
48 48 {
49 49 function Formular()
50 50 {
51   - $this->SetTitulo($this->_instituicao . ' i-Educar - Alunos em 5ª Avaliação');
  51 + $this->SetTitulo($this->_instituicao . ' i-Educar - Alunos em Exame');
52 52 $this->processoAp = 807;
53 53 }
54 54 }
... ... @@ -208,7 +208,7 @@ function acao2()
208 208 return;
209 209 }
210 210  
211   - showExpansivelImprimir(400, 200,'',[], 'Quinta Avaliação');
  211 + showExpansivelImprimir(400, 200,'',[], 'Alunos em Exame');
212 212  
213 213 document.formcadastro.target = 'miolo_' + (DOM_divs.length - 1);
214 214  
... ...
ieducar/intranet/educar_relatorio_alunos_quinta_avaliacao_proc.php
... ... @@ -34,6 +34,10 @@ require_once 'include/clsBanco.inc.php';
34 34 require_once 'include/pmieducar/geral.inc.php';
35 35 require_once 'include/relatorio.inc.php';
36 36  
  37 +require_once 'Avaliacao/Service/Boletim.php';
  38 +require_once 'ComponenteCurricular/Model/ComponenteDataMapper.php';
  39 +require_once 'RegraAvaliacao/Model/RegraDataMapper.php';
  40 +
37 41 /**
38 42 * clsIndexBase class.
39 43 *
... ... @@ -48,7 +52,7 @@ class clsIndexBase extends clsBase
48 52 {
49 53 function Formular()
50 54 {
51   - $this->SetTitulo($this->_instituicao . ' i-Educar - Alunos em 5ª Avaliação');
  55 + $this->SetTitulo($this->_instituicao . ' i-Educar - Alunos em Exame');
52 56 $this->processoAp = 807;
53 57 $this->renderMenu = FALSE;
54 58 $this->renderMenuSuspenso = FALSE;
... ... @@ -77,13 +81,8 @@ class indice extends clsCadastro
77 81  
78 82 var $ano;
79 83  
80   - var $cursos = array();
81   -
82 84 var $get_link;
83 85  
84   - var $media;
85   - var $media_exame;
86   -
87 86 function renderHTML()
88 87 {
89 88 if ($_POST){
... ... @@ -99,259 +98,208 @@ class indice extends clsCadastro
99 98 $fonte = 'arial';
100 99 $corTexto = '#000000';
101 100  
102   - if (is_numeric($this->ref_cod_escola) && is_numeric($this->ref_cod_curso) &&
103   - is_numeric($this->ref_cod_serie) && is_numeric($this->ref_cod_turma) &&
104   - is_numeric($this->ano)
  101 + if (!is_numeric($this->ref_cod_escola) || !is_numeric($this->ref_cod_curso) ||
  102 + !is_numeric($this->ref_cod_serie) || !is_numeric($this->ref_cod_turma) ||
  103 + !is_numeric($this->ano)
105 104 ) {
106   -
  105 + print $this->getError();
  106 + return;
107 107 }
108 108  
109   - $obj_ref_cod_curso = new clsPmieducarCurso($this->ref_cod_curso);
110   - $det_ref_cod_curso = $obj_ref_cod_curso->detalhe();
111   -
112   - $nm_curso = $det_ref_cod_curso['nm_curso'];
113   - $padrao_ano_escolar = $det_ref_cod_curso['padrao_ano_escolar'];
114   -
115   - if ($padrao_ano_escolar) {
116   - $obj_ano_letivo = new clsPmieducarEscolaAnoLetivo();
117   - $lst_ano_letivo = $obj_ano_letivo->lista($this->ref_cod_escola, $this->ano,
118   - NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1);
119   -
120   - if (is_array($lst_ano_letivo)) {
121   - $det_ano_letivo = array_shift($lst_ano_letivo);
122   - $ano_letivo = $det_ano_letivo['ano'];
123   -
124   - $obj_ano_letivo_modulo = new clsPmieducarAnoLetivoModulo();
125   - $lst_ano_letivo_modulo = $obj_ano_letivo_modulo->lista($ano_letivo, $this->ref_cod_escola);
126   -
127   - if (is_array($lst_ano_letivo_modulo)) {
128   - $qtd_modulos = count($lst_ano_letivo_modulo);
129   - }
130   - }
131   - else {
132   - echo '
133   - <script>
134   - alert("Escola não possui calendário definido para este ano");
135   - window.parent.fechaExpansivel(\'div_dinamico_\'+(window.parent.DOM_divs.length-1));
136   - </script>';
137   -
138   - return TRUE;
139   - }
140   - }
141   - else {
142   - $obj_turma_modulo = new clsPmieducarTurmaModulo();
143   - $lst_turma_modulo = $obj_turma_modulo->lista($registro['ref_cod_turma']);
144   -
145   - if (is_array($lst_turma_modulo)) {
146   - $qtd_modulos = count($lst_turma_modulo);
147   - }
148   - }
149   -
150   - if ($this->ano == date('Y')) {
151   - $sql = sprintf('
152   - SELECT
153   - m.cod_matricula,
154   - (
155   - SELECT
156   - nome
157   - FROM
158   - pmieducar.aluno al,
159   - cadastro.pessoa
160   - WHERE
161   - al.cod_aluno = m.ref_cod_aluno
162   - AND al.ref_idpes = pessoa.idpes
163   - ) AS nome
164   - FROM
165   - pmieducar.matricula m,
166   - pmieducar.matricula_turma mt
167   - WHERE
168   - mt.ref_cod_turma = %d
169   - AND mt.ref_cod_matricula = m.cod_matricula
170   - AND m.aprovado = 3
171   - AND mt.ativo = 1 AND m.ativo = 1
172   - AND m.modulo > %d
173   - AND m.ano = %d
174   - ORDER BY
175   - nome', $this->ref_cod_turma, $qtd_modulos, $this->ano);
176   - }
177   - else {
178   - $sql = sprintf('
  109 + // Instituição
  110 + $obj_instituicao = new clsPmieducarInstituicao($this->ref_cod_instituicao);
  111 + $nm_instituicao = $obj_instituicao->detalhe();
  112 + $nm_instituicao = $nm_instituicao['nm_instituicao'];
  113 +
  114 + // Escola
  115 + $obj_escola = new clsPmieducarEscola($this->ref_cod_escola);
  116 + $nm_escola = $obj_escola->detalhe();
  117 + $nm_escola = $nm_escola['nome'];
  118 +
  119 + // Curso
  120 + $obj_curso = new clsPmieducarCurso($this->ref_cod_curso);
  121 + $obj_curso->setCamposLista('media, media_exame, nm_curso');
  122 + $det_curso = $obj_curso->detalhe();
  123 + $nm_curso = $det_curso['nm_curso'];
  124 +
  125 + // Série
  126 + $obj_serie = new clsPmieducarSerie($this->ref_cod_serie);
  127 + $obj_serie->setCamposLista('nm_serie');
  128 + $det_serie = $obj_serie->detalhe();
  129 + $nm_serie = $det_serie['nm_serie'];
  130 + $regraId = $det_serie['regra_avaliacao_id'];
  131 +
  132 + // Turma
  133 + $obj_turma = new clsPmieducarTurma($this->ref_cod_turma);
  134 + $obj_turma->setCamposLista('nm_turma');
  135 + $det_turma = $obj_turma->detalhe();
  136 + $nm_turma = $det_turma['nm_turma'];
  137 +
  138 + // Situação da matrícula do aluno (aprovado)
  139 + $situacao = $this->ano == date('Y') ?
  140 + App_Model_MatriculaSituacao::EM_ANDAMENTO :
  141 + implode(', ', array(
  142 + App_Model_MatriculaSituacao::APROVADO,
  143 + App_Model_MatriculaSituacao::REPROVADO,
  144 + App_Model_MatriculaSituacao::EM_ANDAMENTO
  145 + ));
  146 +
  147 + $sql = sprintf('
  148 + SELECT
  149 + m.cod_matricula,
  150 + (
179 151 SELECT
180   - m.cod_matricula,
181   - (
182   - SELECT
183   - nome
184   - FROM
185   - pmieducar.aluno al,
186   - cadastro.pessoa
187   - WHERE
188   - al.cod_aluno = m.ref_cod_aluno
189   - AND al.ref_idpes = pessoa.idpes
190   - ) AS nome
  152 + nome
191 153 FROM
192   - pmieducar.matricula m,
193   - pmieducar.matricula_turma mt
  154 + pmieducar.aluno al,
  155 + cadastro.pessoa
194 156 WHERE
195   - mt.ref_cod_turma = %d
196   - AND mt.ref_cod_matricula = m.cod_matricula
197   - AND m.aprovado IN (1, 2, 3)
198   - AND mt.ativo = 1 AND m.ativo = 1
199   - AND m.modulo > %d
200   - AND m.ano = %d
201   - ORDER BY
202   - nome', $this->ref_cod_turma, $qtd_modulos, $this->ano);
203   - }
  157 + al.cod_aluno = m.ref_cod_aluno
  158 + AND al.ref_idpes = pessoa.idpes
  159 + ) AS nome
  160 + FROM
  161 + pmieducar.matricula m,
  162 + pmieducar.matricula_turma mt
  163 + WHERE
  164 + mt.ref_cod_turma = %d
  165 + AND mt.ref_cod_matricula = m.cod_matricula
  166 + AND m.aprovado IN (%s)
  167 + AND mt.ativo = 1
  168 + AND m.ativo = 1
  169 + AND m.ano = %d
  170 + ORDER BY
  171 + nome', $this->ref_cod_turma, $situacao, $this->ano);
204 172  
205 173 $db = new clsBanco();
206 174 $db->Consulta($sql);
207 175  
  176 + // Mappers
  177 + $regraMapper = new RegraAvaliacao_Model_RegraDataMapper();
  178 + $componenteMapper = new ComponenteCurricular_Model_ComponenteDataMapper();
  179 +
  180 + $regra = $regraMapper->find($regraId);
  181 + if (is_null($regra->formulaRecuperacao)) {
  182 + $regra = 'A regra de avaliação dessa série não possui uma fórmula de cálculo de recuperação.';
  183 + }
  184 + else {
  185 + $regra = sprintf('Recuperação: %s; fórmula: %s.', $regra->formulaRecuperacao, $regra->formulaRecuperacao->formulaMedia);
  186 + }
  187 +
208 188 if ($db->Num_Linhas()) {
209 189 $alunos = array();
210 190  
211 191 // Disciplinas da escola-série
212 192 $obj_disciplinas = new clsPmieducarEscolaSerieDisciplina();
213   - $obj_disciplinas->setOrderby('nm_disciplina');
214   - $obj_disciplinas->setCamposLista('cod_disciplina, nm_disciplina');
215 193 $lst_disciplinas = $obj_disciplinas->lista($this->ref_cod_serie,
216   - $this->ref_cod_escola, NULL, 1, TRUE);
217   -
218   - // Curso
219   - $obj_curso = new clsPmieducarCurso($this->ref_cod_curso);
220   - $obj_curso->setCamposLista('media, media_exame, nm_curso');
221   - $det_curso = $obj_curso->detalhe();
222   -
223   - $this->media = $det_curso['media'];
224   - $this->media_exame = $det_curso['media_exame'];
  194 + $this->ref_cod_escola, NULL, 1);
225 195  
226 196 // Instancia objeto de relatório padrão
227   - $detalhes = sprintf('%s%s%s%s%s%s%s - Turma: %s %s', $this->nm_instituicao,
228   - "\n", $this->nm_escola, "\n", $this->nm_curso, "\n", $this->nm_serie,
229   - $this->nm_turma, date('d/m/Y'));
  197 + $detalhes = sprintf('%s%s%s%s%s%s%s - Turma: %s %s', $nm_instituicao,
  198 + "\n", $nm_escola, "\n", $nm_curso, "\n", $nm_serie,
  199 + $nm_turma, date('d/m/Y'));
230 200  
231   - $relatorio = new relatorios('Relação de alunos em 5ª avaliação', 210,
232   - FALSE, 'Relação de alunos em 5ª avaliação', 'A4', $detalhes);
  201 + $relatorio = new relatorios('Relação de alunos em exame', 210,
  202 + FALSE, 'Relação de alunos em exame', 'A4', $detalhes);
233 203  
  204 + $relatorio->exibe_produzido_por = FALSE;
234 205 $relatorio->setMargem(20, 20, 20, 20);
235 206  
236   - // Escola
237   - $obj_escola = new clsPmieducarEscola($this->ref_cod_escola);
238   - $nm_escola = $obj_escola->detalhe();
239   - $nm_escola = $nm_escola['nome'];
240   - $nm_curso = $det_curso['nm_curso'];
241   -
242   - // Série
243   - $obj_serie = new clsPmieducarSerie($this->ref_cod_serie);
244   - $obj_serie->setCamposLista('nm_serie');
245   - $det_serie = $obj_serie->detalhe();
246   - $nm_serie = $det_serie['nm_serie'];
247   -
248   - // Turma
249   - $obj_turma = new clsPmieducarTurma($this->ref_cod_turma);
250   - $obj_turma->setCamposLista('nm_turma');
251   - $det_turma = $obj_turma->detalhe();
252   - $nm_turma = $det_turma['nm_turma'];
253   -
254 207 $relatorio->novalinha(array(sprintf('Nome Escola: %s Ano: %d', $nm_escola, $this->ano)),
255 208 0, 12, TRUE, 'arial', FALSE, '#000000', '#d3d3d3', '#FFFFFF', FALSE, TRUE);
256 209  
257   - $relatorio->novalinha(array(sprintf('Curso: %s Ano/Série: %s Turma: %s Date: %s', $nm_curso, $nm_serie, $nm_turma, date('d/m/Y'))),
  210 + $relatorio->novalinha(array(sprintf('Curso: %s Ano/Série: %s Turma: %s', $nm_curso, $nm_serie, $nm_turma)),
  211 + 0, 12, TRUE, 'arial', FALSE, '#000000', '#d3d3d3', '#FFFFFF', FALSE, TRUE);
  212 +
  213 + $relatorio->novalinha(array(sprintf('%s Data: %s', $regra, date('d/m/Y'))),
258 214 0, 12, TRUE, 'arial', FALSE, '#000000', '#d3d3d3', '#FFFFFF', FALSE, TRUE);
259 215  
260   - $relatorio->novalinha(array('Matrícula', 'Nome Aluno', 'Disciplinas', 'Pontos', 'Nota 5º Av. Passar'),
261   - 0, 12, TRUE, 'arial', array(50, 200, 150, 50), '#515151', '#d3d3d3', '#FFFFFF', FALSE, TRUE);
  216 + $relatorio->novalinha(array('Mat.', 'Nome Aluno', 'Componentes', 'Média', 'Nota necessária (mín.)'),
  217 + 0, 12, TRUE, 'arial', array(30, 180, 150, 60), '#515151', '#d3d3d3', '#FFFFFF', FALSE, TRUE);
262 218  
263 219 while ($db->ProximoRegistro()) {
264 220 list($cod_matricula, $nome_aluno) = $db->Tupla();
265 221  
266   - foreach ($lst_disciplinas as $disciplina) {
267   - $obj_nota_aluno = new clsPmieducarNotaAluno();
268   - $obj_nota_aluno->setOrderby('modulo ASC');
269   - $lst_nota_aluno = $obj_nota_aluno->lista(NULL, NULL, NULL,
270   - $this->ref_cod_serie, $this->ref_cod_escola, $disciplina['cod_disciplina'],
271   - $cod_matricula, NULL, NULL, NULL, NULL, NULL, NULL, 1);
  222 + $boletim = new Avaliacao_Service_Boletim(array(
  223 + 'matricula' => $cod_matricula,
  224 + 'RegraDataMapper' => $regraMapper,
  225 + 'ComponenteDataMapper' => $componenteMapper
  226 + ));
272 227  
273   - $aluno_notas = array();
274   - $aluno_notas_normal = array();
  228 + $componentes = $boletim->getComponentes();
  229 + $medias = $boletim->getMediasComponentes();
  230 + $situacao = $boletim->getSituacaoComponentesCurriculares();
275 231  
276   - if (is_array($lst_nota_aluno)) {
277   - $aluno_notas[$disciplina['cod_disciplina']] = 0;
278   -
279   - foreach ($lst_nota_aluno as $nota_aluno) {
280   - $obj_avaliacao_valores = new clsPmieducarTipoAvaliacaoValores(
281   - $nota_aluno['ref_ref_cod_tipo_avaliacao'], $nota_aluno['ref_sequencial']
282   - );
283   -
284   - $det_avaliacao_valores = $obj_avaliacao_valores->detalhe();
285   -
286   - $aluno_notas[$disciplina['cod_disciplina']] += $det_avaliacao_valores['valor'];
287   - }
  232 + if ($situacao->situacao != App_Model_MatriculaSituacao::EM_EXAME) {
  233 + continue;
  234 + }
288 235  
289   - $aluno_notas_normal[$disciplina['cod_disciplina']] = $aluno_notas[$disciplina['cod_disciplina']];
  236 + foreach ($situacao->componentesCurriculares as $id => $situacaoComponente) {
  237 + if ($situacaoComponente->situacao != App_Model_MatriculaSituacao::EM_EXAME) {
  238 + continue;
  239 + }
290 240  
291   - $aluno_notas[$disciplina['cod_disciplina']] /= count($lst_nota_aluno);
  241 + $mediaRecuperacao = $boletim->preverNotaRecuperacao($id);
292 242  
293   - $aluno_notas[$disciplina['cod_disciplina']] = sprintf('%01.1f', $aluno_notas[$disciplina['cod_disciplina']]);
  243 + if (!is_null($mediaRecuperacao)) {
  244 + $previsao = sprintf('%s (%.2f)', $mediaRecuperacao->nome, $mediaRecuperacao->valorMinimo);
294 245 }
295   -
296   - if (is_array($aluno_notas)) {
297   - foreach ($aluno_notas as $cod_disciplina => $media) {
298   - if ($media < $this->media && $this->media_exame) {
299   - // @todo WTF!??? Que diabos de nota fixa é essa?
300   - // FÓRMULA: 30 - (SOMA DE PONTOS DOS 4 BIMESTRES) / 2.
301   - // Ex: 30 - 23 / 2 = 3,5
302   - $nota_necessaria_passar = (30 - $aluno_notas_normal[$cod_disciplina]) / 2;
303   -
304   - $data = array(
305   - $cod_matricula,
306   - $nome_aluno,
307   - $disciplina['nm_disciplina'],
308   - $aluno_notas_normal[$cod_disciplina],
309   - $nota_necessaria_passar
310   - );
311   -
312   - $relatorio->novalinha($data, 0, 12, FALSE, 'arial',
313   - array(50, 200, 150, 50), '#515151', '#d3d3d3', '#FFFFFF', FALSE, TRUE);
314   - }
315   - }
  246 + else {
  247 + $previsao = 'Nenhuma nota possível.';
316 248 }
317   - }
318   - }
319 249  
320   - $this->get_link = $relatorio->fechaPdf();
  250 + $data = array(
  251 + $cod_matricula,
  252 + $nome_aluno,
  253 + $componentes[$id],
  254 + $medias[$id][0]->mediaArredondada,
  255 + $previsao
  256 + );
321 257  
322   - echo sprintf('
323   - <script>
324   - window.onload=function()
325   - {
326   - parent.EscondeDiv("LoadImprimir");
327   - window.location="download.php?filename=%s"
328   - }
329   - </script>', $this->get_link);
330   -
331   - echo sprintf('
332   - <html>
333   - <center>
334   - Se o download não iniciar automaticamente <br>
335   - <a target="blank" href="%s" style="font-size: 16px; color: #000000; text-decoration: underline;">clique aqui!</a><br><br>
336   - <span style="font-size: 10px;">
337   - Para visualizar os arquivos PDF, é necessário instalar o Adobe Acrobat Reader.<br>
338   - Clique na Imagem para Baixar o instalador<br><br>
339   - <a href="http://www.adobe.com.br/products/acrobat/readstep2.html" target="new"><br><img src="imagens/acrobat.gif" width="88" height="31" border="0"></a>
340   - </span>
341   - </center>
342   - </html>', $this->get_link);
  258 + $relatorio->novalinha($data, 0, 12, FALSE, 'arial',
  259 + array(30, 180, 150, 60), '#515151', '#d3d3d3', '#FFFFFF', FALSE, TRUE);
  260 + }
  261 + }
343 262 }
344 263 else {
345   - echo '
346   - <script>
  264 + print $this->getError();
  265 + return;
  266 + }
  267 +
  268 + $this->get_link = $relatorio->fechaPdf();
  269 +
  270 + echo sprintf('
  271 + <script>
347 272 window.onload=function()
348 273 {
349 274 parent.EscondeDiv("LoadImprimir");
  275 + window.location="download.php?filename=%s"
350 276 }
351   - </script>';
  277 + </script>', $this->get_link);
  278 +
  279 + echo sprintf('
  280 + <html>
  281 + <center>
  282 + Se o download não iniciar automaticamente <br>
  283 + <a target="blank" href="%s" style="font-size: 16px; color: #000000; text-decoration: underline;">clique aqui!</a><br><br>
  284 + <span style="font-size: 10px;">
  285 + Para visualizar os arquivos PDF, é necessário instalar o Adobe Acrobat Reader.<br>
  286 + Clique na Imagem para Baixar o instalador<br><br>
  287 + <a href="http://www.adobe.com.br/products/acrobat/readstep2.html" target="new"><br><img src="imagens/acrobat.gif" width="88" height="31" border="0"></a>
  288 + </span>
  289 + </center>
  290 + </html>', $this->get_link);
  291 + }
352 292  
353   - echo 'Nenhum aluno está em exame';
354   - }
  293 + function getError()
  294 + {
  295 + return '
  296 + <script>
  297 + window.onload=function()
  298 + {
  299 + parent.EscondeDiv("LoadImprimir");
  300 + }
  301 + </script>' .
  302 + 'Nenhum aluno está em exame';
355 303 }
356 304  
357 305 function Editar()
... ...
ieducar/intranet/include/pmieducar/clsPmieducarEscolaSerieDisciplina.inc.php
... ... @@ -258,6 +258,8 @@ class clsPmieducarEscolaSerieDisciplina
258 258 /**
259 259 * Retorna uma lista de registros filtrados de acordo com os parâmetros.
260 260 * @return array
  261 + * @todo Refatorar o primeiro if, tabela referenciada não armazena mais os
  262 + * componentes curriculares
261 263 */
262 264 function lista($int_ref_ref_cod_serie = NULL, $int_ref_ref_cod_escola = NULL,
263 265 $int_ref_cod_disciplina = NULL, $int_ativo = NULL, $boo_nome_disc = FALSE)
... ...
ieducar/misc/database/deltas/19_atualiza_nome_de_relatorio_no_menu_e_permissoes.sql 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +-- //
  2 +
  3 +--
  4 +-- @author Eriksen Costa Paixão <eriksen.paixao_bs@cobra.com.br>
  5 +-- @license @@license@@
  6 +-- @version $Id$
  7 +--
  8 +
  9 +UPDATE portal.menu_submenu SET nm_submenu = 'Alunos em Exame' WHERE cod_menu_submenu = 917;
  10 +UPDATE pmicontrolesis.menu SET tt_menu = 'Alunos em Exame' WHERE cod_menu = 21184;
  11 +
  12 +-- //@UNDO
  13 +
  14 +UPDATE portal.menu_submenu SET nm_submenu = 'Alunos 5ª Avaliação' WHERE cod_menu_submenu = 917;
  15 +UPDATE pmicontrolesis.menu SET tt_menu = 'Alunos 5ª Avaliação' WHERE cod_menu = 21184;
  16 +
  17 +-- //
0 18 \ No newline at end of file
... ...
ieducar/misc/database/ieducar.sql
... ... @@ -17935,7 +17935,6 @@ INSERT INTO menu VALUES (21180, 911, 21126, &#39;Ficha de Rematrícula&#39;, 22, &#39;educar_
17935 17935 INSERT INTO menu VALUES (21181, 835, 21124, 'Relatório Quadros de Horário', 25, 'educar_relatorio_quadro_horario.php', '_self', 1, 15, 105);
17936 17936 INSERT INTO menu VALUES (21182, 916, 21126, 'Registro de Trans. Expedidas', 25, 'educar_relatorio_registro_transferencias.php', '_self', 1, 15, 1);
17937 17937 INSERT INTO menu VALUES (21183, 774, 21126, 'Relatório Alunos Idade x Sexo', 25, 'educar_relatorio_quadro_idade_sexo_serie.php', '_self', 1, 15, 1);
17938   -INSERT INTO menu VALUES (21184, 917, 21126, 'Alunos 5ª Avaliação', 26, 'educar_relatorio_alunos_quinta_avaliacao.php', '_self', 1, 15, 1);
17939 17938 INSERT INTO menu VALUES (21185, 918, 21126, 'Ata Resultado Final', 28, 'educar_relatorio_ata_resultado_final.php', '_self', 1, 15, 1);
17940 17939 INSERT INTO menu VALUES (21186, 836, 21126, 'Relatório de alunos por idade', 30, 'educar_relatorio_alunos_idade.php', '_self', 1, 15, 1);
17941 17940 INSERT INTO menu VALUES (21187, 823, 21126, 'Resultado Final', 30, 'educar_relatorio_resultado_final.php', '_self', 1, 15, 1);
... ... @@ -17980,6 +17979,7 @@ INSERT INTO menu VALUES (21227, 947, 21226, &#39;Listar Regras&#39;, 0, &#39;module/RegraAva
17980 17979 INSERT INTO menu VALUES (21228, 948, 21226, 'Fórmulas de Cálculo de Média', 1, 'module/FormulaMedia/index', '_self', 1, 15, 198);
17981 17980 INSERT INTO menu VALUES (21229, 949, 21226, 'Tabelas de Arredondamento', 2, 'module/TabelaArredondamento/index', '_self', 1, 15, 199);
17982 17981 INSERT INTO menu VALUES (21230, 693, 21126, 'Registro de Matrículas', 30, 'educar_relatorio_registro_matriculas.php', '_self', 1, 15, 1);
  17982 +INSERT INTO menu VALUES (21184, 917, 21126, 'Alunos em Exame', 26, 'educar_relatorio_alunos_quinta_avaliacao.php', '_self', 1, 15, 1);
17983 17983  
17984 17984  
17985 17985 --
... ... @@ -19951,7 +19951,6 @@ INSERT INTO menu_submenu VALUES (845, 55, 2, &#39;Rematrícula Automática&#39;, &#39;educar_a
19951 19951 INSERT INTO menu_submenu VALUES (944, 55, 2, 'Demonstrativo Alunos Defasados Nominal', 'educar_alunos_defasados_nominal.php', '', 3);
19952 19952 INSERT INTO menu_submenu VALUES (930, 55, 2, 'Levantamento Alfab. e não Alfab.', 'educar_relatorio_alfabetizados.php', '', 3);
19953 19953 INSERT INTO menu_submenu VALUES (918, 55, 2, 'Ata Resultado Final', 'educar_relatorio_ata_resultado_final.php', '', 3);
19954   -INSERT INTO menu_submenu VALUES (917, 55, 2, 'Alunos 5ª Avaliação', 'educar_relatorio_alunos_quinta_avaliacao.php', '', 3);
19955 19954 INSERT INTO menu_submenu VALUES (911, 55, 2, 'Ficha de Rematrícula', 'educar_relatorio_ficha_rematricula.php', '', 3);
19956 19955 INSERT INTO menu_submenu VALUES (916, 55, 2, 'Registro de Transferências Expedidas', 'educar_relatorio_registro_transferencias.php', '', 3);
19957 19956 INSERT INTO menu_submenu VALUES (900, 55, 2, 'Relação de Alunos ANEEs Quantidade', 'educar_relatorio_relacao_qtd_aluno_pnee_escola.php', '', 3);
... ... @@ -19987,6 +19986,7 @@ INSERT INTO menu_submenu VALUES (946, 55, 2, &#39;Componentes Curriculares&#39;, &#39;module
19987 19986 INSERT INTO menu_submenu VALUES (947, 55, 2, 'Regras de Avaliação', 'module/RegraAvaliacao/index', '', 3);
19988 19987 INSERT INTO menu_submenu VALUES (948, 55, 2, 'Fórmula de Cálculo de Média', 'module/FormulaMedia/index', '', 3);
19989 19988 INSERT INTO menu_submenu VALUES (949, 55, 2, 'Tabelas de Arredondamento de Nota', 'module/TabelaArredondamento/index', '', 3);
  19989 +INSERT INTO menu_submenu VALUES (917, 55, 2, 'Alunos em Exame', 'educar_relatorio_alunos_quinta_avaliacao.php', '', 3);
19990 19990  
19991 19991  
19992 19992 --
... ... @@ -20097,6 +20097,7 @@ INSERT INTO changelog VALUES (15, &#39;Main&#39;, &#39;NOW()&#39;, &#39;NOW()&#39;, &#39;dbdeploy&#39;, &#39;15_atua
20097 20097 INSERT INTO changelog VALUES (16, 'Main', 'NOW()', 'NOW()', 'dbdeploy', '16_permissoes_para_modules_e_correcao_menus.sql');
20098 20098 INSERT INTO changelog VALUES (17, 'Main', 'NOW()', 'NOW()', 'dbdeploy', '17_adiciona_campo_curso_componente_ano_escolar_e_atualiza_constraint_servidor_disciplina.sql');
20099 20099 INSERT INTO changelog VALUES (18, 'Main', 'NOW()', 'NOW()', 'dbdeploy', '18_cria_tabelas_de_parecer_descritivo.sql');
  20100 +INSERT INTO changelog VALUES (19, 'Main', 'NOW()', 'NOW()', 'dbdeploy', '19_atualiza_nome_de_relatorio_no_menu_e_permissoes.sql');
20100 20101  
20101 20102  
20102 20103 --
... ...
ieducar/modules/Avaliacao/Service/Boletim.php
... ... @@ -2107,13 +2107,62 @@ class Avaliacao_Service_Boletim implements CoreExt_Configurable
2107 2107 return $this->getRegra()->tabelaArredondamento->round($nota);
2108 2108 }
2109 2109  
  2110 + /**
  2111 + * Prevê a nota necessária para que o aluno seja aprovado após a recuperação
  2112 + * escolar.
  2113 + *
  2114 + * @param int $id
  2115 + * @return TabelaArredondamento_Model_TabelaValor|NULL
  2116 + * @see TabelaArredondamento_Model_Tabela#predictValue()
  2117 + */
  2118 + public function preverNotaRecuperacao($id)
  2119 + {
  2120 + if (is_null($this->getRegra()->formulaRecuperacao) || !isset($this->_notasComponentes[$id])) {
  2121 + return NULL;
  2122 + }
  2123 +
  2124 + $notas = $this->_notasComponentes[$id];
  2125 + $somaEtapas = array_sum(CoreExt_Entity::entityFilterAttr($notas, 'etapa', 'nota'));
  2126 + $formula = $this->getRegra()->formulaRecuperacao;
  2127 +
  2128 + $data = array(
  2129 + 'formulaValues' => array(
  2130 + 'Se' => $somaEtapas,
  2131 + 'Et' => $this->getOption('etapas'),
  2132 + 'Rc' => NULL
  2133 + ),
  2134 + 'expected' => array(
  2135 + 'var' => 'Rc',
  2136 + 'value' => $this->getRegra()->media
  2137 + )
  2138 + );
  2139 +
  2140 + foreach ($notas as $nota) {
  2141 + $data['formulaValues']['E' . $nota->etapa] = $nota->nota;
  2142 + }
2110 2143  
  2144 + return $this->getRegra()->tabelaArredondamento->predictValue($formula, $data);
  2145 + }
2111 2146  
  2147 + /**
  2148 + * @param numeric $falta
  2149 + * @param numeric $horaFalta
  2150 + * @return numeric
  2151 + */
2112 2152 protected function _calculateHoraFalta($falta, $horaFalta)
2113 2153 {
2114 2154 return ($falta * $horaFalta);
2115 2155 }
2116 2156  
  2157 + /**
  2158 + * Calcula a proporção de $num2 para $num1.
  2159 + *
  2160 + * @param numeric $num1
  2161 + * @param numeric $num2
  2162 + * @param bool $decimal Opcional. Se o resultado é retornado como decimal
  2163 + * ou percentual. O padrão é TRUE.
  2164 + * @return float
  2165 + */
2117 2166 protected function _calculatePorcentagem($num1, $num2, $decimal = TRUE)
2118 2167 {
2119 2168 $num1 = floatval($num1);
... ...
ieducar/modules/Avaliacao/_tests/Service/UtilityTest.php
... ... @@ -122,4 +122,55 @@ class Avaliacao_Service_UtilityTest extends Avaliacao_Service_TestCommon
122 122 $this->assertEquals('S', $service->arredondaNota(6.50));
123 123 $this->assertEquals('O', $service->arredondaNota(9.15));
124 124 }
  125 +
  126 + public function testPreverNotaParaRecuperacao()
  127 + {
  128 + // Define as notas do aluno
  129 + $notaAluno = $this->_getConfigOption('notaAluno', 'instance');
  130 +
  131 + $notas = array(
  132 + new Avaliacao_Model_NotaComponente(array(
  133 + 'componenteCurricular' => 1,
  134 + 'nota' => 4,
  135 + 'etapa' => 1
  136 + )),
  137 + new Avaliacao_Model_NotaComponente(array(
  138 + 'componenteCurricular' => 1,
  139 + 'nota' => 4,
  140 + 'etapa' => 2
  141 + )),
  142 + new Avaliacao_Model_NotaComponente(array(
  143 + 'componenteCurricular' => 1,
  144 + 'nota' => 4,
  145 + 'etapa' => 3
  146 + )),
  147 + new Avaliacao_Model_NotaComponente(array(
  148 + 'componenteCurricular' => 1,
  149 + 'nota' => 4,
  150 + 'etapa' => 4
  151 + )),
  152 + );
  153 +
  154 + // Configura mock para Avaliacao_Model_NotaComponenteDataMapper
  155 + $mock = $this->getCleanMock('Avaliacao_Model_NotaComponenteDataMapper');
  156 +
  157 + $mock->expects($this->at(0))
  158 + ->method('findAll')
  159 + ->with(array(), array('notaAluno' => $notaAluno->id), array('etapa' => 'ASC'))
  160 + ->will($this->returnValue($notas));
  161 +
  162 + $this->_setNotaComponenteDataMapperMock($mock);
  163 +
  164 + $service = $this->_getServiceInstance();
  165 +
  166 + $expected = new TabelaArredondamento_Model_TabelaValor(array(
  167 + 'nome' => 10,
  168 + 'valorMinimo' => 9,
  169 + 'valorMaximo' => 10
  170 + ));
  171 +
  172 + $ret = $service->preverNotaRecuperacao(1);
  173 + $this->assertEquals(array($expected->nome, $expected->valorMinimo, $expected->valorMaximo),
  174 + array($ret->nome, $ret->valorMinimo, $ret->valorMaximo));
  175 + }
125 176 }
126 177 \ No newline at end of file
... ...
ieducar/modules/TabelaArredondamento/Model/Tabela.php
... ... @@ -137,6 +137,106 @@ class TabelaArredondamento_Model_Tabela extends CoreExt_Entity
137 137 }
138 138  
139 139 /**
  140 + * Prevê em qual range de arredondamento de acordo com um valor esperado. A
  141 + * definição do valor a retornar é dada por uma instância de
  142 + * FormulaMedia_Model_Formula e um array com valores para as tokens da fórmula
  143 + * e o valor da variável a prever. Exemplo:
  144 + *
  145 + * <code>
  146 + * <?php
  147 + * // Passa valores para as tokens disponíveis de FormulaMedia_Model_Formula
  148 + * // e espera que o resultado do cálculo dê 6, usando como referência a
  149 + * // variável "Rc"
  150 + * $data = array(
  151 + * 'formulaValues' => array(
  152 + * 'Se' => 16,
  153 + * 'Et' => 4,
  154 + * 'E1' => 4,
  155 + * 'E2' => 4,
  156 + * 'E3' => 4,
  157 + * 'E4' => 4,
  158 + * 'Rc' => NULL
  159 + * ),
  160 + * 'expected' => array(
  161 + * 'var' => 'Rc',
  162 + * 'value' => 6
  163 + * )
  164 + * );
  165 + * </code>
  166 + *
  167 + * @param FormulaMedia_Model_Formula $formula
  168 + * @param array $data
  169 + * @return TabelaArredondamento_Model_TabelaValor|NULL Retorna NULL caso
  170 + * nenhuma instância de TabelaArredondamento_Model_TabelaValor corresponda
  171 + * ao valor esperado
  172 + * @todo Considerar o atributo valorMaximo da instância para o cálculo da
  173 + * fórmula. Pode ser útil para os casos de notas conceituais (Exemplo: uma
  174 + * nota "EP" que tem o range 5.25 a 7, sendo 6 a média de aprovação. Nesse
  175 + * caso somente o próximo range (se houvesse) daria o valor esperado para
  176 + * alcançar a média 6).
  177 + */
  178 + public function predictValue(FormulaMedia_Model_Formula $formula, array $data)
  179 + {
  180 + $values = $data['formulaValues'];
  181 + $scale = pow(10, $this->_precision);
  182 + $return = NULL;
  183 +
  184 + if (0 == count($this->_tabelaValores)) {
  185 + $this->_tabelaValores = $this->getDataMapper()->findTabelaValor($this);
  186 + }
  187 +
  188 + $i = 0;
  189 + $total = count($this->_tabelaValores);
  190 +
  191 + foreach ($this->_tabelaValores as $tabelaValor) {
  192 + $process = array();
  193 + $values[$data['expected']['var']] = $tabelaValor->valorMinimo;
  194 + $process[] = $values;
  195 +
  196 + // Se for o último item, verifica se a nota máxima também
  197 + if (++$i == $total) {
  198 + $values[$data['expected']['var']] = $tabelaValor->valorMaximo;
  199 + $process[] = $values;
  200 + }
  201 +
  202 + $valueRounded = $this->_getBestResultFromValuesArray($formula, $process);
  203 +
  204 + if ($valueRounded * $scale >= ($data['expected']['value'] * $scale)) {
  205 + $return = $tabelaValor;
  206 + break;
  207 + }
  208 + }
  209 +
  210 + return $return;
  211 + }
  212 +
  213 + /**
  214 + * @param FormulaMedia_Model_Formula $formula
  215 + * @param array $values
  216 + * @return TabelaArredondamento_Model_TabelaValor|NULL
  217 + */
  218 + protected function _getBestResultFromValuesArray(FormulaMedia_Model_Formula $formula, array $values)
  219 + {
  220 + $best = NULL;
  221 +
  222 + foreach ($values as $value) {
  223 + $value = $formula->execFormulaMedia($value);
  224 + $rounded = $this->round($value);
  225 +
  226 + if (is_null($best)) {
  227 + $best = $rounded;
  228 + continue;
  229 + }
  230 +
  231 + if ($best < $rounded) {
  232 + $best = $rounded;
  233 + }
  234 + }
  235 +
  236 + return $rounded;
  237 + }
  238 +
  239 + /**
140 240 * Método finder para TabelaArredondamento_Model_TabelaValor. Wrapper simples
141 241 * para o mesmo método de TabelaArredondamento_Model_TabelaDataMapper.
142 242 *
... ...
ieducar/modules/TabelaArredondamento/_tests/TabelaTest.php
... ... @@ -32,6 +32,7 @@
32 32 require_once 'TabelaArredondamento/Model/Tabela.php';
33 33 require_once 'TabelaArredondamento/Model/TabelaDataMapper.php';
34 34 require_once 'TabelaArredondamento/Model/TabelaValorDataMapper.php';
  35 +require_once 'FormulaMedia/Model/Formula.php';
35 36 require_once 'include/pmieducar/clsPmieducarInstituicao.inc.php';
36 37  
37 38 /**
... ... @@ -142,6 +143,91 @@ class TabelaTest extends UnitBaseTest
142 143 }
143 144 }
144 145  
  146 + public function testCalculoDeNotaNecessariaParaMedia()
  147 + {
  148 + $this->_entity->getDataMapper()->setTabelaValorDataMapper($this->_getMockTabelaValor());
  149 +
  150 + $formula = new FormulaMedia_Model_Formula(array(
  151 + 'formulaMedia' => '(Se / Et * 0.6) + (Rc * 0.4)',
  152 + 'tipoFormula' => FormulaMedia_Model_TipoFormula::MEDIA_RECUPERACAO
  153 + ));
  154 +
  155 + $expected = new TabelaArredondamento_Model_TabelaValor(array(
  156 + 'nome' => 10,
  157 + 'valorMinimo' => 9.751,
  158 + 'valorMaximo' => 10
  159 + ));
  160 +
  161 + $data = array(
  162 + 'formulaValues' => array(
  163 + 'Se' => 13.334,
  164 + 'Et' => 4,
  165 + 'Rc' => NULL
  166 + ),
  167 + 'expected' => array(
  168 + 'var' => 'Rc',
  169 + 'value' => 6
  170 + )
  171 + );
  172 +
  173 + $ret = $this->_entity->predictValue($formula, $data);
  174 + $this->assertEquals(array($expected->nome, $expected->valorMinimo, $expected->valorMaximo),
  175 + array($ret->nome, $ret->valorMinimo, $ret->valorMaximo));
  176 +
  177 + $expected = new TabelaArredondamento_Model_TabelaValor(array(
  178 + 'nome' => 9,
  179 + 'valorMinimo' => 8.751,
  180 + 'valorMaximo' => 9.250
  181 + ));
  182 +
  183 + $data = array(
  184 + 'formulaValues' => array(
  185 + 'Se' => 16,
  186 + 'Et' => 4,
  187 + 'Rc' => NULL
  188 + ),
  189 + 'expected' => array(
  190 + 'var' => 'Rc',
  191 + 'value' => 6
  192 + )
  193 + );
  194 +
  195 + $ret = $this->_entity->predictValue($formula, $data);
  196 + $this->assertEquals(array($expected->nome, $expected->valorMinimo, $expected->valorMaximo),
  197 + array($ret->nome, $ret->valorMinimo, $ret->valorMaximo));
  198 +
  199 + $formula = new FormulaMedia_Model_Formula(array(
  200 + 'formulaMedia' => '((E1 + E2 + E3 + E4) / 4 * 0.6) + (Rc * 0.4)',
  201 + 'tipoFormula' => FormulaMedia_Model_TipoFormula::MEDIA_RECUPERACAO
  202 + ));
  203 +
  204 + $expected = new TabelaArredondamento_Model_TabelaValor(array(
  205 + 'nome' => 9,
  206 + 'valorMinimo' => 8.751,
  207 + 'valorMaximo' => 9.250
  208 + ));
  209 +
  210 + $data = array(
  211 + 'formulaValues' => array(
  212 + 'Se' => NULL,
  213 + 'Et' => NULL,
  214 + 'E1' => 4,
  215 + 'E2' => 4,
  216 + 'E3' => 4,
  217 + 'E4' => 4,
  218 + 'Rc' => NULL
  219 + ),
  220 + 'expected' => array(
  221 + 'var' => 'Rc',
  222 + 'value' => 6
  223 + )
  224 + );
  225 +
  226 + $ret = $this->_entity->predictValue($formula, $data);
  227 + $this->assertEquals(array($expected->nome, $expected->valorMinimo, $expected->valorMaximo),
  228 + array($ret->nome, $ret->valorMinimo, $ret->valorMaximo));
  229 + }
  230 +
145 231 /**
146 232 * @group CoreExt_Locale
147 233 */
... ...