diff --git a/__manifest__.py b/__manifest__.py index 3bb458c..f7497d1 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,17 +1,32 @@ +# -*- coding: utf-8 -*- { - 'name': 'Gestao Escolar', - 'version': '1.0', - 'summary': 'Sistema de Gestão Escolar', - 'author': 'Sebastiao', + 'name': 'Gestão Escolar Avançada - CEFOPE Core', + 'version': '1.0.0', + 'summary': 'Sistema de Gestão Escolar para as Instituíções de Angola', + 'description': """ + Módulo central do projeto CEFOPE: + - Gestão de Candidatos e Exames + - Configuração de Cursos e Turmas + - Controlo de Matrículas e Notas + """, + 'author': 'Hilaritech', 'category': 'Education', - 'depends': ['base'], + 'license': 'LGPL-3', + + 'depends': [ + 'base', + ], 'data': [ - 'security/groups.xml', + 'security/cefope_security_groups.xml', 'security/ir.model.access.csv', - 'views/school_views.xml', + 'views/academic_applicant_views.xml', + 'views/academic_course_views.xml', + 'views/academic_exam_views.xml', + 'views/menus.xml', ], 'installable': True, 'application': True, -} + 'auto_install': False, +} \ No newline at end of file diff --git a/__pycache__/__init__.cpython-313.pyc b/__pycache__/__init__.cpython-313.pyc index 58bcd69..181bb60 100644 Binary files a/__pycache__/__init__.cpython-313.pyc and b/__pycache__/__init__.cpython-313.pyc differ diff --git a/models/__init__.py b/models/__init__.py index a2369d6..f5a8fbe 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,7 +1,3 @@ -from . import student -from . import teacher -from . import academic_year -from . import school_class -from . import subject -from . import enrollment -from . import assessment +from . import academic_applicant +from . import academic_exam +from . import academic_course \ No newline at end of file diff --git a/models/__pycache__/__init__.cpython-313.pyc b/models/__pycache__/__init__.cpython-313.pyc index 31f2ca5..db4a6ed 100644 Binary files a/models/__pycache__/__init__.cpython-313.pyc and b/models/__pycache__/__init__.cpython-313.pyc differ diff --git a/models/__pycache__/academic_applicant.cpython-313.pyc b/models/__pycache__/academic_applicant.cpython-313.pyc new file mode 100644 index 0000000..083a8be Binary files /dev/null and b/models/__pycache__/academic_applicant.cpython-313.pyc differ diff --git a/models/__pycache__/academic_course.cpython-313.pyc b/models/__pycache__/academic_course.cpython-313.pyc new file mode 100644 index 0000000..de00595 Binary files /dev/null and b/models/__pycache__/academic_course.cpython-313.pyc differ diff --git a/models/__pycache__/academic_exam.cpython-313.pyc b/models/__pycache__/academic_exam.cpython-313.pyc new file mode 100644 index 0000000..552fc96 Binary files /dev/null and b/models/__pycache__/academic_exam.cpython-313.pyc differ diff --git a/models/__pycache__/academic_year.cpython-313.pyc b/models/__pycache__/academic_year.cpython-313.pyc deleted file mode 100644 index 33a702b..0000000 Binary files a/models/__pycache__/academic_year.cpython-313.pyc and /dev/null differ diff --git a/models/__pycache__/assessment.cpython-313.pyc b/models/__pycache__/assessment.cpython-313.pyc deleted file mode 100644 index 5215691..0000000 Binary files a/models/__pycache__/assessment.cpython-313.pyc and /dev/null differ diff --git a/models/__pycache__/enrollment.cpython-313.pyc b/models/__pycache__/enrollment.cpython-313.pyc deleted file mode 100644 index 25ff4bc..0000000 Binary files a/models/__pycache__/enrollment.cpython-313.pyc and /dev/null differ diff --git a/models/__pycache__/school_class.cpython-313.pyc b/models/__pycache__/school_class.cpython-313.pyc deleted file mode 100644 index a1e05ec..0000000 Binary files a/models/__pycache__/school_class.cpython-313.pyc and /dev/null differ diff --git a/models/__pycache__/student.cpython-313.pyc b/models/__pycache__/student.cpython-313.pyc deleted file mode 100644 index 469bc87..0000000 Binary files a/models/__pycache__/student.cpython-313.pyc and /dev/null differ diff --git a/models/__pycache__/subject.cpython-313.pyc b/models/__pycache__/subject.cpython-313.pyc deleted file mode 100644 index ea9660d..0000000 Binary files a/models/__pycache__/subject.cpython-313.pyc and /dev/null differ diff --git a/models/__pycache__/teacher.cpython-313.pyc b/models/__pycache__/teacher.cpython-313.pyc deleted file mode 100644 index 6ef9f41..0000000 Binary files a/models/__pycache__/teacher.cpython-313.pyc and /dev/null differ diff --git a/models/academic_applicant.py b/models/academic_applicant.py new file mode 100644 index 0000000..131f4b3 --- /dev/null +++ b/models/academic_applicant.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +from odoo import fields, models, api +from odoo.exceptions import ValidationError + + +class AcademicApplicant(models.Model): + _name = 'academic.applicant' + _description = 'Candidato Académico' + _order = 'id desc' + + # --- Dados Pessoais --- + name = fields.Char(string="Nome Completo", required=True) + birth_date = fields.Date(string="Data de Nascimento", required=True) + gender = fields.Selection([ + ('M', 'Masculino'), + ('F', 'Feminino') + ], string="Género", required=True) + bi = fields.Char(string="Número de Identidade (BI)", required=True) + + # --- Documentos (Binary) --- + photo_bi = fields.Binary(string="Foto do BI (Frente e Verso)", attachment=True, required=True) + certificate = fields.Binary(string="Certificado de Conclusão", attachment=True, required=True) + + # --- Histórico Escolar --- + previous_school = fields.Char(string="Escola Anterior", required=True) + previous_school_type = fields.Selection([ + ('public', 'Pública'), + ('private', 'Privada'), + ('ppp', 'Parceria Público-Privada') + ], string="Tipo de Escola", default='public', required=True) + graduation_year = fields.Integer(string="Ano de Conclusão", required=True) + + # --- Contactos --- + phone = fields.Char(string="Telefone") + email = fields.Char(string="Email") + + # --- Relações --- + course_id = fields.Many2one('academic.course', string="Curso Pretendido", required=True) + exam_id = fields.Many2one("academic.exam", string="Exame de Acesso") + exam_score = fields.Float(string="Nota do Exame", digits=(1, 2)) + + # Relacionamento com o Utilizador (Para Record Rules) + user_id = fields.Many2one('res.users', string="Utilizador", default=lambda self: self.env.user) + + # --- Workflow de Estado --- + state = fields.Selection([ + ('draft', 'Rascunho'), + ('submitted', 'Submetido'), + ('exam', 'Exame Marcado'), + ('taken', 'Exame Realizado'), + ('approved', 'Aprovado'), + ('rejected', 'Rejeitado') + ], string="Estado", default='draft') + + + # --- Funções de Fluxo (Botões do Header) --- + + def action_submit(self): + """Apenas valida documentos e avança para Submetido""" + for record in self: + if not record.photo_bi or not record.bi: + raise ValidationError("Erro: É obrigatório anexar a foto do BI e preencher o número do BI!") + record.state = 'submitted' + + def action_mark_exam(self): + """Esta é a função que exige o exame. Só deve ser clicada APÓS a submissão""" + for record in self: + if not record.exam_id: + raise ValidationError("Erro: Selecione primeiro o Exame de Acesso no campo correspondente.") + record.state = 'exam' + + @api.onchange('exam_score') + def _onchange_exam_score(self): + """Quando a nota muda (mesmo na lista de chamada), atualiza o estado""" + for record in self: + if record.exam_score >= 10: + record.state = 'approved' + elif 0 < record.exam_score < 10: + record.state = 'rejected' \ No newline at end of file diff --git a/models/academic_course.py b/models/academic_course.py new file mode 100644 index 0000000..4c584ec --- /dev/null +++ b/models/academic_course.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from odoo import fields, models + + +class AcademicCourse(models.Model): + _name = 'academic.course' + _description = 'Curso Académico' + _order = 'name' + + name = fields.Char(string="Nome do Curso", required=True) + code = fields.Char(string="Código do Curso", help="Ex: TI-01, MEC-02") + duration = fields.Integer(string="Duração (Anos)", default=4) + description = fields.Text(string="Descrição/Perfil de Saída") + + # Campo para definir se o curso está ativo para novas inscrições + active = fields.Boolean(string="Ativo", default=True) + + # Relacionamento: Um curso tem muitos candidatos + applicant_ids = fields.One2many( + 'academic.applicant', + 'course_id', + string="Candidatos Inscritos" + ) + + _sql_constraints = [ + ('name_unique', 'unique(name)', 'O nome do curso deve ser único!'), + ('code_unique', 'unique(code)', 'O código do curso deve ser único!') + ] \ No newline at end of file diff --git a/models/academic_exam.py b/models/academic_exam.py new file mode 100644 index 0000000..60f3e05 --- /dev/null +++ b/models/academic_exam.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +from odoo import fields, models, api + + +class AcademicExam(models.Model): + _name = 'academic.exam' + _description = 'Exame de Acesso' + _order = 'date desc' + + name = fields.Char(string="Identificação do Exame", required=True, help="Ex: Exame de Informática - Sala 13") + date = fields.Datetime(string="Data e Hora", required=True) + room = fields.Char(string="Sala/Local", required=True) + capacity = fields.Integer(string="Capacidade Máxima", default=30) + + # Relacionamento com o curso (opcional, se o exame for por curso) + course_id = fields.Many2one('academic.course', string="Curso Relacionado") + + # Lista de candidatos inscritos neste exame específico + applicant_ids = fields.One2many( + 'academic.applicant', + 'exam_id', + string="Candidatos Inscritos" + ) + + # Campo calculado para saber quantos já estão inscritos + applicant_count = fields.Integer( + string="Total Inscritos", + compute='_compute_applicant_count', + store=True + ) + + @api.depends('applicant_ids') + def _compute_applicant_count(self): + for record in self: + record.applicant_count = len(record.applicant_ids) \ No newline at end of file diff --git a/models/academic_year.py b/models/academic_year.py deleted file mode 100644 index d0729c8..0000000 --- a/models/academic_year.py +++ /dev/null @@ -1,9 +0,0 @@ -from odoo import models, fields - -class AcademicYear(models.Model): - _name = 'school.academic.year' - _description = 'Academic Year' - - name = fields.Char(required=True) - start_date = fields.Date() - end_date = fields.Date() diff --git a/models/assessment.py b/models/assessment.py deleted file mode 100644 index 4447f29..0000000 --- a/models/assessment.py +++ /dev/null @@ -1,17 +0,0 @@ -from odoo import models, fields - -class SchoolAssessment(models.Model): - _name = 'school.assessment' - _description = 'Assessment' - - enrollment_id = fields.Many2one( - 'school.enrollment', - string="Enrollment" - ) - - subject_id = fields.Many2one( - 'school.subject', - string="Subject" - ) - - grade = fields.Float(string="Grade") diff --git a/models/enrollment.py b/models/enrollment.py deleted file mode 100644 index d961bd8..0000000 --- a/models/enrollment.py +++ /dev/null @@ -1,26 +0,0 @@ -from odoo import models, fields - -class SchoolEnrollment(models.Model): - _name = 'school.enrollment' - _description = 'Enrollment' - - student_id = fields.Many2one( - 'cefope.student', - string="Student" - ) - - class_id = fields.Many2one( - 'school.class', - string="Class" - ) - - academic_year_id = fields.Many2one( - 'school.academic.year', - string="Academic Year" - ) - - status = fields.Selection([ - ('active','Active'), - ('completed','Completed'), - ('cancelled','Cancelled') - ], default='active') diff --git a/models/school_class.py b/models/school_class.py deleted file mode 100644 index cbc1b7f..0000000 --- a/models/school_class.py +++ /dev/null @@ -1,17 +0,0 @@ -from odoo import models, fields - -class SchoolClass(models.Model): - _name = 'school.class' - _description = 'Class' - - name = fields.Char(required=True) - - academic_year_id = fields.Many2one( - 'school.academic.year', - string="Academic Year" - ) - - teacher_id = fields.Many2one( - 'school.teacher', - string="Teacher" - ) diff --git a/models/student.py b/models/student.py deleted file mode 100644 index 131679c..0000000 --- a/models/student.py +++ /dev/null @@ -1,14 +0,0 @@ -from odoo import models, fields - -class Student(models.Model): - _name = 'cefope.student' - _description = 'Student' - - name = fields.Char(string="Name") - email = fields.Char(string="Email") - phone = fields.Char(string="Phone") - - user_id = fields.Many2one( - 'res.users', - string="User" - ) diff --git a/models/subject.py b/models/subject.py deleted file mode 100644 index 7409f35..0000000 --- a/models/subject.py +++ /dev/null @@ -1,12 +0,0 @@ -from odoo import models, fields - -class SchoolSubject(models.Model): - _name = 'school.subject' - _description = 'Subject' - - name = fields.Char(required=True) - - class_id = fields.Many2one( - 'school.class', - string="Class" - ) diff --git a/models/teacher.py b/models/teacher.py deleted file mode 100644 index 95da0bd..0000000 --- a/models/teacher.py +++ /dev/null @@ -1,9 +0,0 @@ -from odoo import models, fields - -class SchoolTeacher(models.Model): - _name = 'school.teacher' - _description = 'Teacher' - - name = fields.Char(required=True) - email = fields.Char() - phone = fields.Char() diff --git a/security/cefope_security_groups.xml b/security/cefope_security_groups.xml new file mode 100644 index 0000000..9e3126a --- /dev/null +++ b/security/cefope_security_groups.xml @@ -0,0 +1,31 @@ + + + Gestão Escolar CEFOPE + Níveis de acesso para o sistema escolar + 10 + + + + Administrador Escolar + + + + + + + Responsável Financeiro + + + + + + Professor + + + + + + Estudante + + + \ No newline at end of file diff --git a/security/cefope_security_rules.xml b/security/cefope_security_rules.xml new file mode 100644 index 0000000..0fcb9fb --- /dev/null +++ b/security/cefope_security_rules.xml @@ -0,0 +1,34 @@ + + + + + + Candidato: Ver apenas a sua própria ficha + + + [('user_id', '=', user.id)] + + + + Professor: Gerir apenas os seus exames + + + [('create_uid', '=', user.id)] + + + + Financeiro: Ver todos os candidatos + + + [(1, '=', 1)] + + + + Admin: Acesso Total + + + [(1, '=', 1)] + + + + \ No newline at end of file diff --git a/security/groups.xml b/security/groups.xml deleted file mode 100644 index f9a11c0..0000000 --- a/security/groups.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - Student - - - - Teacher - - - - School Manager - - - diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index b433f95..86feb0e 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -1,8 +1,13 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_student,access_student,model_cefope_student,,1,1,1,1 -access_teacher,access_teacher,model_school_teacher,,1,1,1,1 -access_academic_year,access_academic_year,model_school_academic_year,,1,1,1,1 -access_class,access_class,model_school_class,,1,1,1,1 -access_subject,access_subject,model_school_subject,,1,1,1,1 -access_enrollment,access_enrollment,model_school_enrollment,,1,1,1,1 -access_assessment,access_assessment,model_school_assessment,,1,1,1,1 +access_academic_applicant_admin,academic.applicant,model_academic_applicant,cefope_core.group_cefope_administrator,1,1,1,1 +access_academic_applicant_finance,academic.applicant,model_academic_applicant,cefope_core.group_cefope_finance,1,1,1,0 +access_academic_applicant_teacher,academic.applicant,model_academic_applicant,cefope_core.group_cefope_teacher,1,1,0,0 +access_academic_applicant_student,academic.applicant,model_academic_applicant,cefope_core.group_cefope_student,1,1,0,0 +access_academic_course_admin,academic.course,model_academic_course,cefope_core.group_cefope_administrator,1,1,1,1 +access_academic_course_finance,academic.course,model_academic_course,cefope_core.group_cefope_finance,1,0,0,0 +access_academic_course_teacher,academic.course,model_academic_course,cefope_core.group_cefope_teacher,1,0,0,0 +access_academic_course_student,academic.course,model_academic_course,cefope_core.group_cefope_student,1,0,0,0 +access_academic_exam_admin,academic.exam,model_academic_exam,cefope_core.group_cefope_administrator,1,1,1,1 +access_academic_exam_finance,academic.exam,model_academic_exam,cefope_core.group_cefope_finance,1,0,0,0 +access_academic_exam_teacher,academic.exam,model_academic_exam,cefope_core.group_cefope_teacher,1,1,1,1 +access_academic_exam_student,academic.exam,model_academic_exam,cefope_core.group_cefope_student,1,0,0,0 \ No newline at end of file diff --git a/security/rules.xml b/security/rules.xml deleted file mode 100644 index 07456ec..0000000 --- a/security/rules.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - Student sees only his record - - - [('user_id','=',user.id)] - - - diff --git a/views/academic_applicant_views.xml b/views/academic_applicant_views.xml new file mode 100644 index 0000000..0b76ce8 --- /dev/null +++ b/views/academic_applicant_views.xml @@ -0,0 +1,106 @@ + + + + academic.applicant.list + academic.applicant + + + + + + + + + + + + + academic.applicant.form + academic.applicant + +
+
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + Candidatos + academic.applicant + list,form + +
\ No newline at end of file diff --git a/views/academic_course_views.xml b/views/academic_course_views.xml new file mode 100644 index 0000000..b031601 --- /dev/null +++ b/views/academic_course_views.xml @@ -0,0 +1,59 @@ + + + + academic.course.list + academic.course + + + + + + + + + + + + academic.course.form + academic.course + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + Cursos + academic.course + list,form + +
\ No newline at end of file diff --git a/views/academic_exam_views.xml b/views/academic_exam_views.xml new file mode 100644 index 0000000..9e55c07 --- /dev/null +++ b/views/academic_exam_views.xml @@ -0,0 +1,69 @@ + + + + academic.exam.list + academic.exam + + + + + + + + + + + + + academic.exam.calendar + academic.exam + + + + + + + + + + academic.academic.exam.form + academic.exam + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + Exames de Acesso + academic.exam + list,calendar,form + +
\ No newline at end of file diff --git a/views/academic_views.xml b/views/academic_views.xml deleted file mode 100644 index e69de29..0000000 diff --git a/views/assessment_views.xml b/views/assessment_views.xml deleted file mode 100644 index e69de29..0000000 diff --git a/views/class_views.xml b/views/class_views.xml deleted file mode 100644 index e69de29..0000000 diff --git a/views/enrollment_views.xml b/views/enrollment_views.xml deleted file mode 100644 index e69de29..0000000 diff --git a/views/menus.xml b/views/menus.xml new file mode 100644 index 0000000..414dde2 --- /dev/null +++ b/views/menus.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/views/school_views.xml b/views/school_views.xml deleted file mode 100644 index 1fce6aa..0000000 --- a/views/school_views.xml +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - - - - - - - - - student.list - cefope.student - - - - - - - - - - - - student.form - cefope.student - -
- - - - - - - - -
-
-
- - - Students - cefope.student - list,form - - - - - - - - - - teacher.list - school.teacher - - - - - - - - - - - teacher.form - school.teacher - -
- - - - - - - -
-
-
- - - Teachers - school.teacher - list,form - - - - - - - - - - academic.year.list - school.academic.year - - - - - - - - - - - academic.year.form - school.academic.year - -
- - - - - - - -
-
-
- - - Academic Years - school.academic.year - list,form - - - - - - - - - - class.list - school.class - - - - - - - - - - - class.form - school.class - -
- - - - - - - -
-
-
- - - Classes - school.class - list,form - - - - - - - - - - subject.list - school.subject - - - - - - - - - - subject.form - school.subject - -
- - - - - - -
-
-
- - - Subjects - school.subject - list,form - - - - - - - - - - enrollment.list - school.enrollment - - - - - - - - - - - - enrollment.form - school.enrollment - -
- - - - - - - - -
-
-
- - - Enrollments - school.enrollment - list,form - - - - - - - - - - assessment.list - school.assessment - - - - - - - - - - - assessment.form - school.assessment - -
- - - - - - - -
-
-
- - - Assessments - school.assessment - list,form - - - - -
diff --git a/views/student_views.xml b/views/student_views.xml deleted file mode 100644 index e69de29..0000000 diff --git a/views/subject_views.xml b/views/subject_views.xml deleted file mode 100644 index e69de29..0000000 diff --git a/views/teacher_views.xml b/views/teacher_views.xml deleted file mode 100644 index e69de29..0000000