SlideShare a Scribd company logo
1 of 44
Download to read offline
Líder em soluções de TI para governo
Sistema de Gestão Escolar
Carlos M. dos Santos
Coordenação Estratégica de Ações Governamentais - CEAGO
1º Seminário de PHP da SERPRO
9 de novembro de 2015
Agenda
● Introdução
● Histórico
● Situação atual
● Arquitetura de código
● Contribuições do SERPRO
Introdução
● Software de gestão escolar
● Desenvolvido inicialmente pela Prefeitura de Itajaí, SC
● Software Livre
● Desenvolvimento ativo
Software livre
● Portal do Software Público Brasileiro (SPB)
● Disponível sob licença GPL
● http://softwarepublico.gov.br
Histórico
● 2006/2007
● Criação do Software
CTIMA – Prefeitura Municipal de Itajaí
● 2008
● Portal do Software Público Brasileiro
● Parceria com Cobra Tecnologia
● 2010/2011
● Comunidade ativa
● Portabilis Tecnologia
● 2014/2015
● Parceria – SERPRO, Ieducativa Soluções e Portabilis Tecnologia
● Trabalho unificado no novo Portal do SPB
Evolução
● CTIMA/Prefeitura de Itajaí
● Desenvolvimento do software
● Cobra Tecnologia
● Refatoração e criação de arquitetura em framework
● Portabilis Tecnologia
● Novas funcionalidades, modelo Software as a Service (SaaS)
● SERPRO
● Migração para PostgreSQL 9.X
● Produção a ser feita em modelo Infrastructure as a Service
(IaaS)
● Importação Educacenso
Quem usa?
●Araranguá/SC
●Arapiraca/AL
●Balneário Arroio do Silva/SC
●Balneário Gaivota/SC
●Balneário Rincão/SC
●Benevides/PA
●Bonito/MS
●Botucatu/SP
●Cocal do Sul/SC
●Colégio Tiradentes da Brigada
Militar
Passo Fundo/RS
●Dom Eliseu/PA
●Esplanada/BA
●Estado de Alagoas
●Florianópolis/SC
●Grão Pará/SC
●Içara/SC
●Irecê/BA
●Instituto Mãos de Arte
Paranoá/DF
●Itajaí/SC
●Jacinto Machado/SC
●Jaguaruna/SC
●Lagoa Grande/PE
●Laguna/SC
●Maracajá/SC
●Meleiro/SC
● Montes Claros/MG
● Natuba/PB
● Nova Veneza/SC
● Pacajá/PA
● Pescaria Brava/SC
● Praia Grande/SC
● Polícia Militar da Paraíba
● Sangão/SC
● Santa Rosa do Sul/SC
● São Francisco do
Conde/BA
● Sombrio/SC
● Timbé do Sul/SC
● Sombrio/SC
● Valparaíso de Goiás/GO
Programa Cidades Digitais
● Ministério das Comunicações
Secretaria de Inclusão Digital
● 362 municípios contemplados
● Infraestrutura de acesso
● Softwares de Gestão Pública
Quem o SERPRO atende?
Valparaíso de Goiás
Acordo de Cooperação
Viçosa do Ceará
Programa Cidades Digitais
Módulos principais
● Escola
● Cadastros: Controle de alunos, turmas, matrículas, ...
● Movimentações: Controle de notas, frequência, ...
● Documentos: Emissão de boletins, atestados, certificados, …
● Biblioteca
● Controle de empréstimos
● Inventário do acervo
● Transporte escolar
● Cadastro de prestadores e veículos
● Controle de rotas oferecidas
● Agenda
● Gestão de Pessoas
Funcionalidades
● Cadastros
● Funcionários, endereçamento, alunos, escolas,
material didático, ...
Funcionalidades
● Operacional
● Matrículas, lançamentos de notas e faltas,
calendário letivo, ...
Funcionalidades
● Gerenciamento de biblioteca
● Acervo, controle de empréstimos, ...
Transporte Escolar
Funcionalidades
● Documentos
● Emissão de boletins, relatórios gerenciais e
atestados de vaga e matrícula, ...
Benefícios
● Menor despesa com sistemas de informação
● Automação dos procedimentos de gestão escolar
● Redução do uso de papel
● Centralização dos cadastros
● Gestão unificada da rede de ensino
● Frequente evolução do software na comunidade
Demonstração
i-Educar na prática
Arquitetura de código
“Talk is cheap. Show me the code.”
Linus Torvalds
Três gerações de código
● 1ª – Gerador de código (ewwww...)
● 2ª – Framework próprio
● 3ª – Migração para API
Exploração arqueológica do código
● Aplicação da intranet da Prefeitura de Itajaí
● Stack em Linux, PostgreSQL (8.2!), PHP e Apache
HTTPD
● Diversos sistemas de controle integrados
● Charset ISO-8859-1
Código antigo – DAOs primitivos
<?php
class clsPessoaFisica extends clsPessoaFj {
var $idpes;
var $data_nasc;
var $sexo;
var $data_obito;
var $nacionalidade;
var $idmun_nascimento;
function clsPessoaFisica($int_idpes = FALSE, $numeric_cpf = FALSE,
$date_data_nasc = FALSE, $str_sexo = FALSE, …);
function lista($str_nome = FALSE, $numeric_cpf = FALSE,
$inicio_limite = FALSE, $qtd_registros = FALSE, $str_orderBy =
FALSE, …);
function detalhe();
function excluir();
}
?>
Código antigo – Templates simples
<table summary="" class='tabelanum2' border='0' cellspacing='0'
cellpadding='0'>
<tr>
<td class="r3c1" width='170'><!-- #&MENU&# --></td>
<td valign=top>
<table summary="" class='tabelanum2' border='0'
cellspacing='0' cellpadding='0'>
<tr>
<td height="0" id="menu_suspenso">
<input type="hidden" value="" id="posx">
<input type="hidden" value="" id="posy">
</td>
</tr>
<tr>
<td height="100%" valign="top" id="corpo">
<!-- #&PROG_ALERT&# -->
<!-- #&NOTIFICACOES&# -->
<!-- #&CORPO&# -->
</td>
</tr>
</table>
</td>
</tr>
</table>
Código antigo – Um arquivo .php por página
<?php
class clsIndex extends clsBase {
function Formular() {
$this->SetTitulo( "Pessoas Físicas" );
$this->processoAp = 43;
$this->addEstilo( "localizacaoSistema" );
}
}
class indice extends clsListagem {
function Gerar() { /* retorna um monte de HTML em texto */ }
}
$pagina = new clsIndex();
$miolo = new indice();
$pagina->addForm( $miolo );
$pagina->MakeAll();
?>
Código antigo – Banco de dados
CREATE TABLE endereco_externo (
idpes numeric(8,0) NOT NULL,
tipo numeric(1,0) NOT NULL,
idtlog character varying(5) NOT NULL,
logradouro character varying(150) NOT NULL,
numero numeric(6,0),
letra character(1),
complemento character varying(20),
bairro character varying(40),
cep numeric(8,0),
cidade character varying(60) NOT NULL,
sigla_uf character(2) NOT NULL,
reside_desde date,
idpes_rev numeric,
data_rev timestamp without time zone,
origem_gravacao character(1) NOT NULL,
idpes_cad numeric,
data_cad timestamp without time zone NOT NULL,
operacao character(1) NOT NULL,
bloco character varying(20),
andar numeric(2,0),
apartamento numeric(6,0),
idsis_rev integer,
idsis_cad integer NOT NULL,
zona_localizacao integer DEFAULT 1,
CONSTRAINT ck_endereco_externo_operacao CHECK
((((operacao = 'I'::bpchar) OR (operacao =
'A'::bpchar)) OR (operacao = 'E'::bpchar))),
CONSTRAINT ck_endereco_externo_origem_gravacao
CHECK (((((origem_gravacao = 'M'::bpchar) OR
(origem_gravacao = 'U'::bpchar)) OR (origem_gravacao
= 'C'::bpchar)) OR (origem_gravacao = 'O'::bpchar))),
CONSTRAINT ck_endereco_externo_tipo CHECK (((tipo
>= (1)::numeric) AND (tipo <= (3)::numeric)))
);
CREATE TABLE endereco_pessoa (
idpes numeric(8,0) NOT NULL,
tipo numeric(1,0) NOT NULL,
cep numeric(8,0) NOT NULL,
idlog numeric(6,0) NOT NULL,
numero numeric(6,0),
letra character(1),
complemento character varying(20),
reside_desde date,
idbai numeric(6,0) NOT NULL,
idpes_rev numeric,
data_rev timestamp without time zone,
origem_gravacao character(1) NOT NULL,
idpes_cad numeric,
data_cad timestamp without time zone NOT NULL,
operacao character(1) NOT NULL,
bloco character varying(20),
andar numeric(2,0),
apartamento numeric(6,0),
idsis_rev integer,
idsis_cad integer NOT NULL,
CONSTRAINT ck_endereco_pessoa_operacao CHECK
((((operacao = 'I'::bpchar) OR (operacao =
'A'::bpchar)) OR (operacao = 'E'::bpchar))),
CONSTRAINT ck_endereco_pessoa_origem_gravacao
CHECK (((((origem_gravacao = 'M'::bpchar) OR
(origem_gravacao = 'U'::bpchar)) OR (origem_gravacao
= 'C'::bpchar)) OR (origem_gravacao = 'O'::bpchar))),
CONSTRAINT ck_endereco_pessoa_tipo CHECK (((tipo
>= (1)::numeric) AND (tipo <= (3)::numeric)))
);
Código antigo – Triggers aleatórias
CREATE FUNCTION fcn_aft_ins_endereco_pessoa() RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
v_idpes numeric;
v_tipo_endereco text;
BEGIN
v_idpes := NEW.idpes;
v_tipo_endereco := NEW.tipo;
EXECUTE 'DELETE FROM cadastro.endereco_externo WHERE idpes='||
quote_literal(v_idpes)||' AND tipo='||v_tipo_endereco||';';
RETURN NEW;
END; $$;
Código moderno – Framework próprio
~/i/d/i/i/l/CoreExt ls -l master❯❯❯ ⏎
total 140
drwxr-xr-x 2 wolverine xmen 4096 Set 25 17:44 Config
drwxr-xr-x 5 wolverine xmen 4096 Ago 6 10:30 Controller
drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 DataMapper
drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 Entity
drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 Exception
drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 Service
drwxr-xr-x 3 wolverine xmen 4096 Ago 6 10:30 Session
drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 Validate
drwxr-xr-x 3 wolverine xmen 4096 Ago 6 10:30 View
-rw-r--r-- 1 wolverine xmen 7312 Ago 6 10:30 Config.class.php
-rw-r--r-- 1 wolverine xmen 2849 Ago 6 10:30 Configurable.php
-rw-r--r-- 1 wolverine xmen 22526 Ago 6 10:30 DataMapper.php
-rw-r--r-- 1 wolverine xmen 33495 Ago 6 10:30 Entity.php
-rw-r--r-- 1 wolverine xmen 4801 Ago 6 10:30 Enum.php
-rw-r--r-- 1 wolverine xmen 1451 Ago 6 10:30 Exception.php
-rw-r--r-- 1 wolverine xmen 5437 Ago 6 10:30 Locale.php
-rw-r--r-- 1 wolverine xmen 1504 Ago 6 10:30 Session.php
-rw-r--r-- 1 wolverine xmen 3205 Ago 6 10:30 Singleton.php
-rw-r--r-- 1 wolverine xmen 1486 Ago 6 10:30 View.php
Código moderno – Arquivo de coniguração
[production]
app.database.dbname = ieducar
app.database.username = ieducar
app.database.hostname = 10.100.148.56
app.database.password = ieducar
app.database.port = 5432
app.aws.bucketname = fotos_alunos
app.aws.awsacesskey = 114aa9bac59642fa951a0fed8359930fc602679d
app.aws.awssecretkey = de53907ec5f10615d1c093bd7eb3d11249381f4f
app.template.vars.instituicao = Secretaria de Educação de Campos Novos
app.template.pdf.titulo = Relatório i-Educar
app.template.pdf.logo = campos_novos.png
app.template.loginpage = templates/template_cidades_digitais.tpl
[gothamcity.ieducar.com.br : production]
app.database.dbname = Gotham
app.locale.province = SP
app.entity.name = Prefeitura de Gotham city
report.logo_file_name = batman.png
app.routes.redirect_to = /intranet/coringa.php
Código moderno – Bootstrapping
global $coreExt;
$coreExt = array();
// Localização para pt_BR
$locale = CoreExt_Locale::getInstance();
$locale->setCulture('pt_BR')->setLocale();
// Instancia objeto CoreExt_Configuration
$coreExt['Config'] = new CoreExt_Config_Ini($configFile,
CORE_EXT_CONFIGURATION_ENV);
$coreExt['Locale'] = $locale;
// Timezone
date_default_timezone_set($coreExt['Config']->app->locale->timezone);
$tenantEnv = $_SERVER['HTTP_HOST'];
// tenta carregar as configurações da seção especifica do tenant,
// ex: ao acessar http://tenant.ieducar.com.br será carregado a seção
tenant.ieducar.com.br caso exista
if ($coreExt['Config']->hasEnviromentSection($tenantEnv))
$coreExt['Config']->changeEnviroment($tenantEnv);
...
Código moderno – API
class PessoaController extends ApiCoreController {
protected function validatesResourceId();
protected function loadPessoa($id = null);
protected function loadPessoaByCpf($cpf = null);
protected function searchOptions();
protected function get() {
$pessoa = array();
if ($this->canGet()) {
if ($this->getRequest()->id)
$pessoa = $this->loadPessoa($this->getRequest()->id);
else
$pessoa = $this->loadPessoaByCpf($this->getRequest()->cpf);
$attrs = array('id', 'nome');
$pessoa = Portabilis_Array_Utils::filter($pessoa, $attrs);
$details = $this->loadDetails($this->getRequest()->id);
}
return $pessoa;
}
public function Gerar() {
if ($this->isRequestFor('get', 'pessoa-search'))
$this->appendResponse($this->search());
elseif ($this->isRequestFor('get', 'pessoa'))
$this->appendResponse($this->get());
else
$this->notImplementedOperationError();
}
}
Código moderno – MVC - View
class ViewController extends Core_Controller_Page_ViewController {
protected $_dataMapper = 'Docente_Model_LicenciaturaDataMapper';
protected $_titulo = 'Detalhes da licenciatura';
protected $_processoAp = 635;
protected $_tableMap = array(
'Licenciatura' => 'licenciatura',
'Curso' => 'curso',
'Ano de conclusão' => 'anoConclusao',
'IES' => 'ies'
);
public function setUrlEditar(CoreExt_Entity $entry) {
$this->url_editar = CoreExt_View_Helper_UrlHelper::url(
'edit', array('query' => array(
'id' => $entry->id,
'servidor' => $entry->servidor,
'instituicao' => $this->getRequest()->instituicao
))
);
}
public function setUrlCancelar(CoreExt_Entity $entry) {
$this->url_cancelar = CoreExt_View_Helper_UrlHelper::url(
'index', array('query' => array(
'id' => $entry->id,
'servidor' => $entry->servidor,
'instituicao' => $this->getRequest()->instituicao
))
);
}
}
Código moderno – MVC - Model
class Docente_Model_Licenciatura extends CoreExt_Entity {
protected $_data = array(
'servidor' => NULL,
'licenciatura' => NULL,
'curso' => NULL,
'anoConclusao' => NULL,
'ies' => NULL,
'user' => NULL,
'created_at' => NULL,
'updated_at' => NULL
);
protected $_references = array(
'licenciatura' => array(
'value' => NULL,
'class' => 'App_Model_SimNao',
'file' => 'App/Model/SimNao.php'
),
'ies' => array(
'value' => NULL,
'class' => 'Educacenso_Model_IesDataMapper',
'file' => 'Educacenso/Model/IesDataMapper.php'
),
'curso' => array(
'value' => NULL,
'class' => 'Educacenso_Model_CursoSuperiorDataMapper',
'file' => 'Educacenso/Model/CursoSuperiorDataMapper.php'
)
);
}
Código moderno – Relatórios – Formulários
class BoletimController extends Portabilis_Controller_ReportCoreController {
protected $_titulo = 'Boletim Escolar';
function form() {
$this->inputsHelper()->dynamic(array('ano', 'instituicao', 'escola', 'curso',
'serie', 'turma'));
$this->inputsHelper()->dynamic('matricula', array('required' => false));
$this->inputsHelper()->checkbox('manual', array('label' => 'Preenchimento
manual?'));
$this->loadResourceAssets($this->getDispatcher());
}
function report() {
return new BoletimReport();
}
function beforeValidation() {
$this->report->addArg('ano', (int)$this->getRequest()->ano);
$this->report->addArg('instituicao', (int)$this->getRequest()-
>ref_cod_instituicao);
$this->report->addArg('escola', (int)$this->getRequest()->ref_cod_escola);
$this->report->addArg('curso', (int)$this->getRequest()->ref_cod_curso);
$this->report->addArg('serie', (int)$this->getRequest()->ref_cod_serie);
$this->report->addArg('turma', (int)$this->getRequest()->ref_cod_turma);
if (is_null($this->getRequest()->ref_cod_matricula))
$this->report->addArg('matricula',0);
else
$this->report->addArg('matricula', (int)$this->getRequest()-
>ref_cod_matricula);
$this->report->addArg('manual', $this->getRequest()->manual ? 1 : 0);
}
}
Código moderno – Relatórios – Mapeamento
class BoletimReport extends Portabilis_Report_ReportCore {
function templateName() {
$flagTipoBoletimTurma = App_Model_IedFinder::getTurma($codTurma = $this-
>args['turma']);
$flagTipoBoletimTurma = $flagTipoBoletimTurma['tipo_boletim'];
if (empty($flagTipoBoletimTurma)) {
throw new Exception(
Portabilis_String_Utils::toLatin1("Não foi definido o tipo de boletim no
cadastro de turmas.")
);
}
$tiposBoletim = Portabilis_Model_Report_TipoBoletim;
$templates = array($tiposBoletim::BIMESTRAL => 'portabilis_boletim',
$tiposBoletim::TRIMESTRAL => 'portabilis_boletim_trimestral');
$template =
is_null($flagTipoBoletimTurma) ? '' : $templates[$flagTipoBoletimTurma];
function requiredArgs() {
$this->addRequiredArg('ano');
$this->addRequiredArg('instituicao');
$this->addRequiredArg('escola');
$this->addRequiredArg('curso');
$this->addRequiredArg('serie');
$this->addRequiredArg('turma');
}
}
Código moderno – Relatórios – .jrxml
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports
http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="portabilis_boletim"
language="groovy" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20"
rightMargin="20" topMargin="20" bottomMargin="20" uuid="4f9ea369-c6c3-48c5-ae82-
2872022857d3">
<parameter name="ano" class="java.lang.Integer">
<defaultValueExpression><![CDATA[new
java.lang.Integer(0)]]></defaultValueExpression>
</parameter>
<parameter name="instituicao" class="java.lang.Integer">
<defaultValueExpression><![CDATA[new
java.lang.Integer(0)]]></defaultValueExpression>
</parameter>
<parameter name="escola" class="java.lang.Integer">
<defaultValueExpression><![CDATA[new
java.lang.Integer(0)]]></defaultValueExpression>
</parameter>
<parameter name="curso" class="java.lang.Integer">
<defaultValueExpression><![CDATA[new
java.lang.Integer(0)]]></defaultValueExpression>
</parameter>
<parameter name="serie" class="java.lang.Integer">
<defaultValueExpression><![CDATA[new
java.lang.Integer(0)]]></defaultValueExpression>
</parameter>
Futuro para o código
● Premissa: Aprender com o passado
● Merging nos repositórios do SPB
● Migrations: Phinx
● Concluir implementação da API
● Padronizar uma API
● Criar novos clientes – Professor, Gestão, Pais
● Refatorar o backend
Trabalho em Comunidade
Novosdocumentoserelatórios
Diário de classe
Certificado de conclusão
Atestado de reserva de vaga
...
Administraçãonoatendimentomulti-tenant
Múltiplos clientes por
instância de aplicação
Facilidade de administração
MelhoriasnoacessoaoPostgreSQL
Migração da versão 8.2 para 9.x
Visualização dos dados do coletor de estatísticas
AutomaçãodetestescomBehat+ Mink
BDD: Behavior-Driven Development
Próximo passo: Integração contínua
IntegraçãocomEducacenso
Importação dos dados do Censo Escolar/INEP
Migração completa em desenvolvimento na comunidade
Próximos passos
Conclusão dos rollouts atuais
- Cidades Digitais
- Valparaíso de Goiás
Entrega do modelo de negócio/serviço
Novas funcionalidades e melhoria contínua
"Fazer do SERPRO uma empresa atuante,
parceira e inovadora em soluções de
gestão educacional, escolar e acadêmica
para uma Pátria, de fato, Educadora."
"O SERPRO, em atendimento ao Programa Cidades Digitais,
internalizou o i-Educar e agora implanta uma nova linha de
atuação para atendimento educacional, com
desenvolvimento colaborativo em comunidade."
Carlos M. dos Santos
Desenvolvedor de Software
SERPRO Florianópolis
carlos-morais.santos@serpro.gov.br
+55 48 3231 8970

More Related Content

Similar to i-Educar - 1º Seminário PHP no Serpro

Desenvolvimento web com CodeIgniter
Desenvolvimento web com CodeIgniterDesenvolvimento web com CodeIgniter
Desenvolvimento web com CodeIgniter
Pedro Junior
 
Fábrica de Software da Procempa - Palestra no 6o Fórum Internacional Software...
Fábrica de Software da Procempa - Palestra no 6o Fórum Internacional Software...Fábrica de Software da Procempa - Palestra no 6o Fórum Internacional Software...
Fábrica de Software da Procempa - Palestra no 6o Fórum Internacional Software...
Éberli Cabistani Riella
 

Similar to i-Educar - 1º Seminário PHP no Serpro (20)

Sobre o workshop "Raspagem de dados para mulheres"
Sobre o workshop "Raspagem de dados para mulheres"Sobre o workshop "Raspagem de dados para mulheres"
Sobre o workshop "Raspagem de dados para mulheres"
 
Desenvolvimento web com CodeIgniter
Desenvolvimento web com CodeIgniterDesenvolvimento web com CodeIgniter
Desenvolvimento web com CodeIgniter
 
Web Scraping: aplicações nos negócios e na ciência
Web Scraping: aplicações nos negócios e na ciênciaWeb Scraping: aplicações nos negócios e na ciência
Web Scraping: aplicações nos negócios e na ciência
 
MongoDB + PHP
MongoDB + PHPMongoDB + PHP
MongoDB + PHP
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
Apostila aed
Apostila aedApostila aed
Apostila aed
 
Portfólio ADS- sem 4 - atividade em grupo
Portfólio ADS- sem 4 - atividade em grupoPortfólio ADS- sem 4 - atividade em grupo
Portfólio ADS- sem 4 - atividade em grupo
 
Jj08 otimizacao
Jj08 otimizacaoJj08 otimizacao
Jj08 otimizacao
 
Doctrine for Dummies
Doctrine for DummiesDoctrine for Dummies
Doctrine for Dummies
 
DDD > Experiências
DDD > ExperiênciasDDD > Experiências
DDD > Experiências
 
PIPES: Uma linguagem para processamento distribuído de eventos complexos
PIPES: Uma linguagem para processamento distribuído de eventos complexosPIPES: Uma linguagem para processamento distribuído de eventos complexos
PIPES: Uma linguagem para processamento distribuído de eventos complexos
 
Palestra DataFlow - II São Paulo Perl Workshop
Palestra DataFlow - II São Paulo Perl WorkshopPalestra DataFlow - II São Paulo Perl Workshop
Palestra DataFlow - II São Paulo Perl Workshop
 
SQLServerDF XIII - xEvents
SQLServerDF XIII - xEventsSQLServerDF XIII - xEvents
SQLServerDF XIII - xEvents
 
SQLAlchemy - Desenvolvendo uma aplicação com Python
SQLAlchemy - Desenvolvendo uma aplicação com Python SQLAlchemy - Desenvolvendo uma aplicação com Python
SQLAlchemy - Desenvolvendo uma aplicação com Python
 
Desmitificando as aplicações RESTFul usando Django Rest Framework
Desmitificando as aplicações RESTFul usando Django Rest FrameworkDesmitificando as aplicações RESTFul usando Django Rest Framework
Desmitificando as aplicações RESTFul usando Django Rest Framework
 
SICJUR - Sistema de Controle Jurídico
SICJUR - Sistema de Controle JurídicoSICJUR - Sistema de Controle Jurídico
SICJUR - Sistema de Controle Jurídico
 
Machine Learning: Do Notebook ao modelo em produção
Machine Learning: Do Notebook ao modelo em produçãoMachine Learning: Do Notebook ao modelo em produção
Machine Learning: Do Notebook ao modelo em produção
 
Como ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noiteComo ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noite
 
Prática de laboratório utilizando views, stored procedures e triggers
Prática de laboratório   utilizando views, stored procedures e triggersPrática de laboratório   utilizando views, stored procedures e triggers
Prática de laboratório utilizando views, stored procedures e triggers
 
Fábrica de Software da Procempa - Palestra no 6o Fórum Internacional Software...
Fábrica de Software da Procempa - Palestra no 6o Fórum Internacional Software...Fábrica de Software da Procempa - Palestra no 6o Fórum Internacional Software...
Fábrica de Software da Procempa - Palestra no 6o Fórum Internacional Software...
 

More from Flávio Lisboa

More from Flávio Lisboa (20)

Criando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHPCriando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHP
 
Cooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e ArgentinaCooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e Argentina
 
Aprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com LaminasAprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com Laminas
 
Ciência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com métodoCiência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com método
 
Turbinando microsserviços em PHP
Turbinando microsserviços em PHPTurbinando microsserviços em PHP
Turbinando microsserviços em PHP
 
O que esperar do framework Laminas
O que esperar do framework LaminasO que esperar do framework Laminas
O que esperar do framework Laminas
 
PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?
 
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
 
Criando microsserviços em PHP
Criando microsserviços em PHPCriando microsserviços em PHP
Criando microsserviços em PHP
 
Como se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundoComo se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundo
 
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHPA demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
 
Comunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperamComunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperam
 
Criação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dadosCriação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dados
 
Amanhecer esmeralda
Amanhecer esmeraldaAmanhecer esmeralda
Amanhecer esmeralda
 
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de DadosEstudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
 
Arquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviçosArquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviços
 
Semeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoasSemeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoas
 
O que é programação de computadores
O que é programação de computadoresO que é programação de computadores
O que é programação de computadores
 
Economia em rede (comunidade)
Economia em rede (comunidade)Economia em rede (comunidade)
Economia em rede (comunidade)
 
Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)
 

Recently uploaded

Assessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdfAssessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdf
Natalia Granato
 

Recently uploaded (6)

Assessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdfAssessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdf
 
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docxATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
 
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docxATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
 
Boas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsBoas práticas de programação com Object Calisthenics
Boas práticas de programação com Object Calisthenics
 
Padrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploPadrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemplo
 
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docxATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
 

i-Educar - 1º Seminário PHP no Serpro

  • 1. Líder em soluções de TI para governo Sistema de Gestão Escolar Carlos M. dos Santos Coordenação Estratégica de Ações Governamentais - CEAGO 1º Seminário de PHP da SERPRO 9 de novembro de 2015
  • 2. Agenda ● Introdução ● Histórico ● Situação atual ● Arquitetura de código ● Contribuições do SERPRO
  • 3. Introdução ● Software de gestão escolar ● Desenvolvido inicialmente pela Prefeitura de Itajaí, SC ● Software Livre ● Desenvolvimento ativo
  • 4. Software livre ● Portal do Software Público Brasileiro (SPB) ● Disponível sob licença GPL ● http://softwarepublico.gov.br
  • 5. Histórico ● 2006/2007 ● Criação do Software CTIMA – Prefeitura Municipal de Itajaí ● 2008 ● Portal do Software Público Brasileiro ● Parceria com Cobra Tecnologia ● 2010/2011 ● Comunidade ativa ● Portabilis Tecnologia ● 2014/2015 ● Parceria – SERPRO, Ieducativa Soluções e Portabilis Tecnologia ● Trabalho unificado no novo Portal do SPB
  • 6. Evolução ● CTIMA/Prefeitura de Itajaí ● Desenvolvimento do software ● Cobra Tecnologia ● Refatoração e criação de arquitetura em framework ● Portabilis Tecnologia ● Novas funcionalidades, modelo Software as a Service (SaaS) ● SERPRO ● Migração para PostgreSQL 9.X ● Produção a ser feita em modelo Infrastructure as a Service (IaaS) ● Importação Educacenso
  • 7. Quem usa? ●Araranguá/SC ●Arapiraca/AL ●Balneário Arroio do Silva/SC ●Balneário Gaivota/SC ●Balneário Rincão/SC ●Benevides/PA ●Bonito/MS ●Botucatu/SP ●Cocal do Sul/SC ●Colégio Tiradentes da Brigada Militar Passo Fundo/RS ●Dom Eliseu/PA ●Esplanada/BA ●Estado de Alagoas ●Florianópolis/SC ●Grão Pará/SC ●Içara/SC ●Irecê/BA ●Instituto Mãos de Arte Paranoá/DF ●Itajaí/SC ●Jacinto Machado/SC ●Jaguaruna/SC ●Lagoa Grande/PE ●Laguna/SC ●Maracajá/SC ●Meleiro/SC ● Montes Claros/MG ● Natuba/PB ● Nova Veneza/SC ● Pacajá/PA ● Pescaria Brava/SC ● Praia Grande/SC ● Polícia Militar da Paraíba ● Sangão/SC ● Santa Rosa do Sul/SC ● São Francisco do Conde/BA ● Sombrio/SC ● Timbé do Sul/SC ● Sombrio/SC ● Valparaíso de Goiás/GO
  • 8. Programa Cidades Digitais ● Ministério das Comunicações Secretaria de Inclusão Digital ● 362 municípios contemplados ● Infraestrutura de acesso ● Softwares de Gestão Pública
  • 9. Quem o SERPRO atende? Valparaíso de Goiás Acordo de Cooperação Viçosa do Ceará Programa Cidades Digitais
  • 10. Módulos principais ● Escola ● Cadastros: Controle de alunos, turmas, matrículas, ... ● Movimentações: Controle de notas, frequência, ... ● Documentos: Emissão de boletins, atestados, certificados, … ● Biblioteca ● Controle de empréstimos ● Inventário do acervo ● Transporte escolar ● Cadastro de prestadores e veículos ● Controle de rotas oferecidas ● Agenda ● Gestão de Pessoas
  • 11. Funcionalidades ● Cadastros ● Funcionários, endereçamento, alunos, escolas, material didático, ...
  • 12. Funcionalidades ● Operacional ● Matrículas, lançamentos de notas e faltas, calendário letivo, ...
  • 13. Funcionalidades ● Gerenciamento de biblioteca ● Acervo, controle de empréstimos, ...
  • 15. Funcionalidades ● Documentos ● Emissão de boletins, relatórios gerenciais e atestados de vaga e matrícula, ...
  • 16. Benefícios ● Menor despesa com sistemas de informação ● Automação dos procedimentos de gestão escolar ● Redução do uso de papel ● Centralização dos cadastros ● Gestão unificada da rede de ensino ● Frequente evolução do software na comunidade
  • 18. Arquitetura de código “Talk is cheap. Show me the code.” Linus Torvalds
  • 19. Três gerações de código ● 1ª – Gerador de código (ewwww...) ● 2ª – Framework próprio ● 3ª – Migração para API
  • 20. Exploração arqueológica do código ● Aplicação da intranet da Prefeitura de Itajaí ● Stack em Linux, PostgreSQL (8.2!), PHP e Apache HTTPD ● Diversos sistemas de controle integrados ● Charset ISO-8859-1
  • 21. Código antigo – DAOs primitivos <?php class clsPessoaFisica extends clsPessoaFj { var $idpes; var $data_nasc; var $sexo; var $data_obito; var $nacionalidade; var $idmun_nascimento; function clsPessoaFisica($int_idpes = FALSE, $numeric_cpf = FALSE, $date_data_nasc = FALSE, $str_sexo = FALSE, …); function lista($str_nome = FALSE, $numeric_cpf = FALSE, $inicio_limite = FALSE, $qtd_registros = FALSE, $str_orderBy = FALSE, …); function detalhe(); function excluir(); } ?>
  • 22. Código antigo – Templates simples <table summary="" class='tabelanum2' border='0' cellspacing='0' cellpadding='0'> <tr> <td class="r3c1" width='170'><!-- #&MENU&# --></td> <td valign=top> <table summary="" class='tabelanum2' border='0' cellspacing='0' cellpadding='0'> <tr> <td height="0" id="menu_suspenso"> <input type="hidden" value="" id="posx"> <input type="hidden" value="" id="posy"> </td> </tr> <tr> <td height="100%" valign="top" id="corpo"> <!-- #&PROG_ALERT&# --> <!-- #&NOTIFICACOES&# --> <!-- #&CORPO&# --> </td> </tr> </table> </td> </tr> </table>
  • 23. Código antigo – Um arquivo .php por página <?php class clsIndex extends clsBase { function Formular() { $this->SetTitulo( "Pessoas Físicas" ); $this->processoAp = 43; $this->addEstilo( "localizacaoSistema" ); } } class indice extends clsListagem { function Gerar() { /* retorna um monte de HTML em texto */ } } $pagina = new clsIndex(); $miolo = new indice(); $pagina->addForm( $miolo ); $pagina->MakeAll(); ?>
  • 24. Código antigo – Banco de dados CREATE TABLE endereco_externo ( idpes numeric(8,0) NOT NULL, tipo numeric(1,0) NOT NULL, idtlog character varying(5) NOT NULL, logradouro character varying(150) NOT NULL, numero numeric(6,0), letra character(1), complemento character varying(20), bairro character varying(40), cep numeric(8,0), cidade character varying(60) NOT NULL, sigla_uf character(2) NOT NULL, reside_desde date, idpes_rev numeric, data_rev timestamp without time zone, origem_gravacao character(1) NOT NULL, idpes_cad numeric, data_cad timestamp without time zone NOT NULL, operacao character(1) NOT NULL, bloco character varying(20), andar numeric(2,0), apartamento numeric(6,0), idsis_rev integer, idsis_cad integer NOT NULL, zona_localizacao integer DEFAULT 1, CONSTRAINT ck_endereco_externo_operacao CHECK ((((operacao = 'I'::bpchar) OR (operacao = 'A'::bpchar)) OR (operacao = 'E'::bpchar))), CONSTRAINT ck_endereco_externo_origem_gravacao CHECK (((((origem_gravacao = 'M'::bpchar) OR (origem_gravacao = 'U'::bpchar)) OR (origem_gravacao = 'C'::bpchar)) OR (origem_gravacao = 'O'::bpchar))), CONSTRAINT ck_endereco_externo_tipo CHECK (((tipo >= (1)::numeric) AND (tipo <= (3)::numeric))) ); CREATE TABLE endereco_pessoa ( idpes numeric(8,0) NOT NULL, tipo numeric(1,0) NOT NULL, cep numeric(8,0) NOT NULL, idlog numeric(6,0) NOT NULL, numero numeric(6,0), letra character(1), complemento character varying(20), reside_desde date, idbai numeric(6,0) NOT NULL, idpes_rev numeric, data_rev timestamp without time zone, origem_gravacao character(1) NOT NULL, idpes_cad numeric, data_cad timestamp without time zone NOT NULL, operacao character(1) NOT NULL, bloco character varying(20), andar numeric(2,0), apartamento numeric(6,0), idsis_rev integer, idsis_cad integer NOT NULL, CONSTRAINT ck_endereco_pessoa_operacao CHECK ((((operacao = 'I'::bpchar) OR (operacao = 'A'::bpchar)) OR (operacao = 'E'::bpchar))), CONSTRAINT ck_endereco_pessoa_origem_gravacao CHECK (((((origem_gravacao = 'M'::bpchar) OR (origem_gravacao = 'U'::bpchar)) OR (origem_gravacao = 'C'::bpchar)) OR (origem_gravacao = 'O'::bpchar))), CONSTRAINT ck_endereco_pessoa_tipo CHECK (((tipo >= (1)::numeric) AND (tipo <= (3)::numeric))) );
  • 25. Código antigo – Triggers aleatórias CREATE FUNCTION fcn_aft_ins_endereco_pessoa() RETURNS trigger LANGUAGE plpgsql AS $$ DECLARE v_idpes numeric; v_tipo_endereco text; BEGIN v_idpes := NEW.idpes; v_tipo_endereco := NEW.tipo; EXECUTE 'DELETE FROM cadastro.endereco_externo WHERE idpes='|| quote_literal(v_idpes)||' AND tipo='||v_tipo_endereco||';'; RETURN NEW; END; $$;
  • 26. Código moderno – Framework próprio ~/i/d/i/i/l/CoreExt ls -l master❯❯❯ ⏎ total 140 drwxr-xr-x 2 wolverine xmen 4096 Set 25 17:44 Config drwxr-xr-x 5 wolverine xmen 4096 Ago 6 10:30 Controller drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 DataMapper drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 Entity drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 Exception drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 Service drwxr-xr-x 3 wolverine xmen 4096 Ago 6 10:30 Session drwxr-xr-x 2 wolverine xmen 4096 Ago 6 10:30 Validate drwxr-xr-x 3 wolverine xmen 4096 Ago 6 10:30 View -rw-r--r-- 1 wolverine xmen 7312 Ago 6 10:30 Config.class.php -rw-r--r-- 1 wolverine xmen 2849 Ago 6 10:30 Configurable.php -rw-r--r-- 1 wolverine xmen 22526 Ago 6 10:30 DataMapper.php -rw-r--r-- 1 wolverine xmen 33495 Ago 6 10:30 Entity.php -rw-r--r-- 1 wolverine xmen 4801 Ago 6 10:30 Enum.php -rw-r--r-- 1 wolverine xmen 1451 Ago 6 10:30 Exception.php -rw-r--r-- 1 wolverine xmen 5437 Ago 6 10:30 Locale.php -rw-r--r-- 1 wolverine xmen 1504 Ago 6 10:30 Session.php -rw-r--r-- 1 wolverine xmen 3205 Ago 6 10:30 Singleton.php -rw-r--r-- 1 wolverine xmen 1486 Ago 6 10:30 View.php
  • 27. Código moderno – Arquivo de coniguração [production] app.database.dbname = ieducar app.database.username = ieducar app.database.hostname = 10.100.148.56 app.database.password = ieducar app.database.port = 5432 app.aws.bucketname = fotos_alunos app.aws.awsacesskey = 114aa9bac59642fa951a0fed8359930fc602679d app.aws.awssecretkey = de53907ec5f10615d1c093bd7eb3d11249381f4f app.template.vars.instituicao = Secretaria de Educação de Campos Novos app.template.pdf.titulo = Relatório i-Educar app.template.pdf.logo = campos_novos.png app.template.loginpage = templates/template_cidades_digitais.tpl [gothamcity.ieducar.com.br : production] app.database.dbname = Gotham app.locale.province = SP app.entity.name = Prefeitura de Gotham city report.logo_file_name = batman.png app.routes.redirect_to = /intranet/coringa.php
  • 28. Código moderno – Bootstrapping global $coreExt; $coreExt = array(); // Localização para pt_BR $locale = CoreExt_Locale::getInstance(); $locale->setCulture('pt_BR')->setLocale(); // Instancia objeto CoreExt_Configuration $coreExt['Config'] = new CoreExt_Config_Ini($configFile, CORE_EXT_CONFIGURATION_ENV); $coreExt['Locale'] = $locale; // Timezone date_default_timezone_set($coreExt['Config']->app->locale->timezone); $tenantEnv = $_SERVER['HTTP_HOST']; // tenta carregar as configurações da seção especifica do tenant, // ex: ao acessar http://tenant.ieducar.com.br será carregado a seção tenant.ieducar.com.br caso exista if ($coreExt['Config']->hasEnviromentSection($tenantEnv)) $coreExt['Config']->changeEnviroment($tenantEnv); ...
  • 29. Código moderno – API class PessoaController extends ApiCoreController { protected function validatesResourceId(); protected function loadPessoa($id = null); protected function loadPessoaByCpf($cpf = null); protected function searchOptions(); protected function get() { $pessoa = array(); if ($this->canGet()) { if ($this->getRequest()->id) $pessoa = $this->loadPessoa($this->getRequest()->id); else $pessoa = $this->loadPessoaByCpf($this->getRequest()->cpf); $attrs = array('id', 'nome'); $pessoa = Portabilis_Array_Utils::filter($pessoa, $attrs); $details = $this->loadDetails($this->getRequest()->id); } return $pessoa; } public function Gerar() { if ($this->isRequestFor('get', 'pessoa-search')) $this->appendResponse($this->search()); elseif ($this->isRequestFor('get', 'pessoa')) $this->appendResponse($this->get()); else $this->notImplementedOperationError(); } }
  • 30. Código moderno – MVC - View class ViewController extends Core_Controller_Page_ViewController { protected $_dataMapper = 'Docente_Model_LicenciaturaDataMapper'; protected $_titulo = 'Detalhes da licenciatura'; protected $_processoAp = 635; protected $_tableMap = array( 'Licenciatura' => 'licenciatura', 'Curso' => 'curso', 'Ano de conclusão' => 'anoConclusao', 'IES' => 'ies' ); public function setUrlEditar(CoreExt_Entity $entry) { $this->url_editar = CoreExt_View_Helper_UrlHelper::url( 'edit', array('query' => array( 'id' => $entry->id, 'servidor' => $entry->servidor, 'instituicao' => $this->getRequest()->instituicao )) ); } public function setUrlCancelar(CoreExt_Entity $entry) { $this->url_cancelar = CoreExt_View_Helper_UrlHelper::url( 'index', array('query' => array( 'id' => $entry->id, 'servidor' => $entry->servidor, 'instituicao' => $this->getRequest()->instituicao )) ); } }
  • 31. Código moderno – MVC - Model class Docente_Model_Licenciatura extends CoreExt_Entity { protected $_data = array( 'servidor' => NULL, 'licenciatura' => NULL, 'curso' => NULL, 'anoConclusao' => NULL, 'ies' => NULL, 'user' => NULL, 'created_at' => NULL, 'updated_at' => NULL ); protected $_references = array( 'licenciatura' => array( 'value' => NULL, 'class' => 'App_Model_SimNao', 'file' => 'App/Model/SimNao.php' ), 'ies' => array( 'value' => NULL, 'class' => 'Educacenso_Model_IesDataMapper', 'file' => 'Educacenso/Model/IesDataMapper.php' ), 'curso' => array( 'value' => NULL, 'class' => 'Educacenso_Model_CursoSuperiorDataMapper', 'file' => 'Educacenso/Model/CursoSuperiorDataMapper.php' ) ); }
  • 32. Código moderno – Relatórios – Formulários class BoletimController extends Portabilis_Controller_ReportCoreController { protected $_titulo = 'Boletim Escolar'; function form() { $this->inputsHelper()->dynamic(array('ano', 'instituicao', 'escola', 'curso', 'serie', 'turma')); $this->inputsHelper()->dynamic('matricula', array('required' => false)); $this->inputsHelper()->checkbox('manual', array('label' => 'Preenchimento manual?')); $this->loadResourceAssets($this->getDispatcher()); } function report() { return new BoletimReport(); } function beforeValidation() { $this->report->addArg('ano', (int)$this->getRequest()->ano); $this->report->addArg('instituicao', (int)$this->getRequest()- >ref_cod_instituicao); $this->report->addArg('escola', (int)$this->getRequest()->ref_cod_escola); $this->report->addArg('curso', (int)$this->getRequest()->ref_cod_curso); $this->report->addArg('serie', (int)$this->getRequest()->ref_cod_serie); $this->report->addArg('turma', (int)$this->getRequest()->ref_cod_turma); if (is_null($this->getRequest()->ref_cod_matricula)) $this->report->addArg('matricula',0); else $this->report->addArg('matricula', (int)$this->getRequest()- >ref_cod_matricula); $this->report->addArg('manual', $this->getRequest()->manual ? 1 : 0); } }
  • 33. Código moderno – Relatórios – Mapeamento class BoletimReport extends Portabilis_Report_ReportCore { function templateName() { $flagTipoBoletimTurma = App_Model_IedFinder::getTurma($codTurma = $this- >args['turma']); $flagTipoBoletimTurma = $flagTipoBoletimTurma['tipo_boletim']; if (empty($flagTipoBoletimTurma)) { throw new Exception( Portabilis_String_Utils::toLatin1("Não foi definido o tipo de boletim no cadastro de turmas.") ); } $tiposBoletim = Portabilis_Model_Report_TipoBoletim; $templates = array($tiposBoletim::BIMESTRAL => 'portabilis_boletim', $tiposBoletim::TRIMESTRAL => 'portabilis_boletim_trimestral'); $template = is_null($flagTipoBoletimTurma) ? '' : $templates[$flagTipoBoletimTurma]; function requiredArgs() { $this->addRequiredArg('ano'); $this->addRequiredArg('instituicao'); $this->addRequiredArg('escola'); $this->addRequiredArg('curso'); $this->addRequiredArg('serie'); $this->addRequiredArg('turma'); } }
  • 34. Código moderno – Relatórios – .jrxml <?xml version="1.0" encoding="UTF-8"?> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="portabilis_boletim" language="groovy" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="4f9ea369-c6c3-48c5-ae82- 2872022857d3"> <parameter name="ano" class="java.lang.Integer"> <defaultValueExpression><![CDATA[new java.lang.Integer(0)]]></defaultValueExpression> </parameter> <parameter name="instituicao" class="java.lang.Integer"> <defaultValueExpression><![CDATA[new java.lang.Integer(0)]]></defaultValueExpression> </parameter> <parameter name="escola" class="java.lang.Integer"> <defaultValueExpression><![CDATA[new java.lang.Integer(0)]]></defaultValueExpression> </parameter> <parameter name="curso" class="java.lang.Integer"> <defaultValueExpression><![CDATA[new java.lang.Integer(0)]]></defaultValueExpression> </parameter> <parameter name="serie" class="java.lang.Integer"> <defaultValueExpression><![CDATA[new java.lang.Integer(0)]]></defaultValueExpression> </parameter>
  • 35. Futuro para o código ● Premissa: Aprender com o passado ● Merging nos repositórios do SPB ● Migrations: Phinx ● Concluir implementação da API ● Padronizar uma API ● Criar novos clientes – Professor, Gestão, Pais ● Refatorar o backend
  • 37. Novosdocumentoserelatórios Diário de classe Certificado de conclusão Atestado de reserva de vaga ...
  • 39. MelhoriasnoacessoaoPostgreSQL Migração da versão 8.2 para 9.x Visualização dos dados do coletor de estatísticas
  • 40. AutomaçãodetestescomBehat+ Mink BDD: Behavior-Driven Development Próximo passo: Integração contínua
  • 41. IntegraçãocomEducacenso Importação dos dados do Censo Escolar/INEP Migração completa em desenvolvimento na comunidade
  • 42. Próximos passos Conclusão dos rollouts atuais - Cidades Digitais - Valparaíso de Goiás Entrega do modelo de negócio/serviço Novas funcionalidades e melhoria contínua
  • 43. "Fazer do SERPRO uma empresa atuante, parceira e inovadora em soluções de gestão educacional, escolar e acadêmica para uma Pátria, de fato, Educadora."
  • 44. "O SERPRO, em atendimento ao Programa Cidades Digitais, internalizou o i-Educar e agora implanta uma nova linha de atuação para atendimento educacional, com desenvolvimento colaborativo em comunidade." Carlos M. dos Santos Desenvolvedor de Software SERPRO Florianópolis carlos-morais.santos@serpro.gov.br +55 48 3231 8970