Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions academic/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@
'security/ir.model.access.csv',
'views/academic_menuitem.xml',
'views/res_partner_views.xml',
'wizards/group_move_student_wizard_views.xml',
'views/academic_group_views.xml',
'views/academic_division_views.xml',
'views/academic_shift_views.xml',
'views/academic_level_views.xml',
'views/academic_study_plan_views.xml',
'views/academic_promotion_views.xml',
Expand Down Expand Up @@ -71,6 +73,7 @@
'demo/res.partner.csv',
'demo/res.partner.link.csv',
'demo/academic.division.csv',
'demo/academic.shift.csv',
'demo/academic.study.plan.csv',
'demo/res_company_demo.xml',
'demo/academic_group.xml',
Expand Down
3 changes: 3 additions & 0 deletions academic/demo/academic.shift.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
id,name
academic_shift_manana,Mañana
academic_shift_tarde,Tarde
52 changes: 39 additions & 13 deletions academic/demo/academic_group.xml
Original file line number Diff line number Diff line change
@@ -1,29 +1,55 @@
<odoo>
<record id="academic_group_1" model="academic.group">
<record id="academic_group_parent_1" model="academic.group">
<field name="level_id" ref="academic_course_1"/>
<field name="division_id" ref="academic_division_1"/>
<field name="company_id" ref="res_company_los_arroyos"/>
<field name="subject_id" ref="academic_subject_1"/>
<field name="teacher_id" ref="res_partner_ignacio_rodriguez"/>
<field name="year" eval="str(datetime.now().year)"/>
<field name="student_ids" eval="[(6, 0, [ref('res_partner_alvaro_diaz'), ref('res_partner_jose_martin_rodriguez'), ref('res_partner_bautista')])]"/>
</record>

<record id="academic_group_2" model="academic.group">
<record id="academic_group_parent_2" model="academic.group">
<field name="level_id" ref="academic_course_2"/>
<field name="division_id" ref="academic_division_2"/>
<field name="company_id" ref="res_company_los_molinos"/>
<field name="subject_id" ref="academic_subject_2"/>
<field name="teacher_id" ref="res_partner_laura_sali"/>
<field name="year" eval="str(datetime.now().year)"/>
<field name="student_ids" eval="[(6, 0, [ref('res_partner_martin_perez'), ref('res_partner_luz'), ref('res_partner_martina')])]"/>
</record>

<record id="academic_group_3" model="academic.group">
<record id="academic_group_parent_3" model="academic.group">
<field name="level_id" ref="academic_course_3"/>
<field name="division_id" ref="academic_division_3"/>
<field name="company_id" ref="base.main_company"/>
<field name="year" eval="str(datetime.now().year)"/>
<field name="student_ids" eval="[(6, 0, [ref('res_partner_mateo'), ref('res_partner_amalia'), ref('res_partner_ignacio')])]"/>
</record>

<record id="academic_group_1a" model="academic.group">
<field name="parent_id" ref="academic_group_parent_1"/>
<field name="division_id" ref="academic_division_1"/>
<field name="student_ids" eval="[(6, 0, [ref('res_partner_jose_martin_rodriguez'), ref('res_partner_bautista')])]"/>
</record>

<record id="academic_group_2a" model="academic.group">
<field name="parent_id" ref="academic_group_parent_2"/>
<field name="division_id" ref="academic_division_1"/>
<field name="student_ids" eval="[(6, 0, [ref('res_partner_luz'), ref('res_partner_martina')])]"/>
</record>

<record id="academic_group_3a" model="academic.group">
<field name="parent_id" ref="academic_group_parent_3"/>
<field name="division_id" ref="academic_division_1"/>
<field name="student_ids" eval="[(6, 0, [ref('res_partner_amalia'), ref('res_partner_ignacio')])]"/>
</record>

<record id="academic_group_1b" model="academic.group">
<field name="parent_id" ref="academic_group_parent_1"/>
<field name="division_id" ref="academic_division_2"/>
<field name="student_ids" eval="[(6, 0, [ref('res_partner_alvaro_diaz')])]"/>
</record>

<record id="academic_group_2b" model="academic.group">
<field name="parent_id" ref="academic_group_parent_2"/>
<field name="division_id" ref="academic_division_2"/>
<field name="student_ids" eval="[(6, 0, [ref('res_partner_martin_perez')])]"/>
</record>

<record id="academic_group_3b" model="academic.group">
<field name="parent_id" ref="academic_group_parent_3"/>
<field name="division_id" ref="academic_division_2"/>
<field name="student_ids" eval="[(6, 0, [ref('res_partner_mateo')])]"/>
</record>
</odoo>
1 change: 1 addition & 0 deletions academic/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# For copyright and license notices, see __manifest__.py file in module root
# directory
##############################################################################
from . import academic_shift
from . import academic_division
from . import academic_group
from . import academic_level
Expand Down
134 changes: 102 additions & 32 deletions academic/models/academic_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,71 @@
##############################################################################
from odoo import api, models, fields, _
from datetime import date
from odoo.exceptions import UserError
import random
import string


class AcademicGroup(models.Model):
_name = 'academic.group'
_description = 'group'
_order = 'sequence'
_order = "company_id, year desc, level_id asc, division_id asc"
_rec_names_search = ['level_id.name', 'level_id.section_id.name', 'division_id.name', 'year', 'subject_id.name']

_sql_constraints = [
('group_unique',
'unique(subject_id, company_id, level_id, year, division_id)',
'Group should be unique per Institution, Subject,'
' Course-Division and Year')]

type = fields.Selection([
('student', 'Student'),
('teacher', 'Teacher'),
('administrator', 'Administrator'),
('gral_administrator', 'gral_administrator'),
('parent', 'Relative')]
)
'unique(subject_id, company_id, parent_id, shift_id, level_id, year, division_id)',
'Group should be unique per Institution, Subject, Course-Division and Year')]

# virtual_group = fields.Boolean()
year = fields.Integer(
required=True,
default=date.today().year,
compute='_compute_year',
store=True,
readonly=False,
recursive=True,
precompute=True,
)
division_id = fields.Many2one(
'academic.division',
string='Division',
)
shift_id = fields.Many2one(
'academic.shift',
string='Shift',
)
company_id = fields.Many2one(
'res.company',
string='Company',
required=True,
context={'default_is_company': True},
default=lambda self: self.env.company
default=lambda self: self.env.company,
compute='_compute_company',
store=True,
readonly=False,
recursive=True,
precompute=True,
)
study_plan_level_ids = fields.Many2many(related='company_id.study_plan_id.level_ids')
level_id = fields.Many2one(
'academic.level',
string='Level',
required=True,
compute='_compute_level',
store=True,
readonly=False,
recursive=True,
precompute=True,
)
subject_id = fields.Many2one(
'academic.subject',
string='Subject',
required=False,
compute='_compute_subject',
store=True,
readonly=False,
recursive=True,
)
teacher_id = fields.Many2one(
'res.partner',
Expand All @@ -72,12 +89,49 @@ class AcademicGroup(models.Model):
complete_name = fields.Char(
compute='_compute_complete_name',
)
# TODO borrar en 18 si nadie se quejo de que lo sacamos de UI
sequence = fields.Integer(help='Used to order Groups', default=10)
active = fields.Boolean(default=True)
student_ids_count = fields.Integer(
string='Student Count',
compute='_compute_student_ids_count',
store=True,
readonly=False,
)
capacity = fields.Integer(compute='_compute_capacity', store=True, readonly=False, recursive=True,)
vacancy = fields.Integer(compute='_compute_vacancy', store=True, readonly=False)
parent_id = fields.Many2one('academic.group',)
child_ids = fields.One2many('academic.group', 'parent_id')

@api.depends('child_ids.capacity')
def _compute_capacity(self):
for rec in self.filtered('child_ids'):
rec.capacity = sum(rec.child_ids.mapped('capacity'))

@api.depends('capacity', 'student_ids_count')
def _compute_vacancy(self):
for rec in self:
rec.vacancy = rec.capacity - rec.student_ids_count

@api.depends('parent_id.level_id')
def _compute_level(self):
for rec in self.filtered('parent_id'):
rec.level_id = rec.parent_id.level_id

@api.depends('parent_id.company_id')
def _compute_company(self):
for rec in self.filtered('parent_id'):
rec.company_id = rec.parent_id.company_id

@api.depends('parent_id.subject_id')
def _compute_subject(self):
for rec in self.filtered('parent_id'):
rec.subject_id = rec.parent_id.subject_id

@api.depends('parent_id.year')
def _compute_year(self):
for rec in self.filtered('parent_id'):
rec.year = rec.parent_id.year

def _compute_display_name(self):
for rec in self.filtered('complete_name'):
Expand All @@ -90,25 +144,20 @@ def _compute_display_name(self):
'division_id',
'year')
def _compute_complete_name(self):
""" Forms complete name of location from parent location to
child location.
@return: Dictionary of values
"""
for line in self:
name = line.company_id.name
name += ', ' + line.level_id.name
name = line.company_id.name or ''
name += ', {}'.format(line.level_id.name or '')

if line.division_id:
name += ' ' + line.division_id.name
name += ' - ' + line.level_id.section_id.name
name += ' - ' + _('Year: ') + str(line.year)
line.complete_name = name

def copy(self, default=None):
if default is None:
default = {}
default = default.copy()
default['division_id'] = False
return super(AcademicGroup, self).copy(default)
name += ' {}'.format(line.division_id.name or '')

section_name = line.level_id.section_id.name if line.level_id and line.level_id.section_id else ''
if section_name:
name += ' - {}'.format(section_name)

name += ' - {}{}'.format(_('Year: '), line.year or '')

line.complete_name = name.strip(', - ')

def create_students_users(self):
'''
Expand All @@ -135,7 +184,28 @@ def print_users(self):
limit=1).report_action(self)
return report

@api.depends('student_ids')
@api.depends('child_ids.student_ids', 'student_ids')
def _compute_student_ids_count(self):
for group in self:
group.student_ids_count = len(group.student_ids)
group.student_ids_count = len(group.student_ids) + sum(group.child_ids.mapped('student_ids_count'))

def _get_all_student(self):
all_student_ids = self.student_ids.ids
for child in self.child_ids:
all_student_ids.extend(child._get_all_student())
return list(set(all_student_ids))

def open_student_list(self):
self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id('academic.action_academic_partner_students')

all_student = self._get_all_student()
if all_student:
action['domain'] = [('partner_type', '=', 'student'), ('id', 'in', all_student)]

return action

@api.ondelete(at_uninstall=False)
def _protect_unlink(self):
if self.filtered(lambda x: x.student_ids or x.child_ids):
raise UserError('No se pueden borrar groups con estudiantes o que tengan grupos hijos')
5 changes: 4 additions & 1 deletion academic/models/academic_level.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ class AcademicLevel(models.Model):
@api.depends('name', 'section_id.name')
def _compute_display_name(self):
for rec in self:
rec.display_name = rec.name + ' - ' + rec.section_id.name if rec.name else ''
rec.display_name = "{} - {}".format(
rec.name or '',
rec.section_id.name or ''
).strip(' - ')
14 changes: 14 additions & 0 deletions academic/models/academic_shift.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
##############################################################################
# For copyright and license notices, see __manifest__.py file in module root
# directory
##############################################################################
from odoo import models, fields


class AcademicShift(models.Model):
_name = 'academic.shift'
_description = 'shift'

name = fields.Char(
required=True,
)
42 changes: 42 additions & 0 deletions academic/models/res_company.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# directory
##############################################################################
from odoo import models, fields
import datetime


class ResCompany(models.Model):
Expand All @@ -19,3 +20,44 @@ class ResCompany(models.Model):
string='Plan de Estudio'
)
family_required = fields.Boolean()

def create_study_plan_groups(self):
for rec in self:
for level in rec.study_plan_id.level_ids:
year = fields.Date.add(fields.Date.today(), years=1).year
existing_groups_levels = self.env['academic.group'].search(
[('year', '=', year), ('level_id', '=', level.id), ('company_id', '=', rec.id), ('parent_id', '=', False)]).mapped('level_id')
if level in existing_groups_levels:
continue
self.env['academic.group'].create({
'year': year,
'level_id': level.id,
'company_id': rec.id,
})

def create_groups_next_year(self):
self.create_study_plan_groups()
for rec in self:
year = fields.Date.today().year
for group in self.env['academic.group'].search([('year', '=', year), ('company_id', '=', rec.id), ('parent_id', '!=', False)]):
if group.level_id not in group.study_plan_level_ids:
# TODO ver que hacemos con groups que no estan en plan de estudio
continue
current_index = group.study_plan_level_ids.ids.index(group.level_id.id)
# este seria el ultimo año del plan de estudios
if current_index + 1 < len(group.study_plan_level_ids):
next_level = group.study_plan_level_ids[current_index + 1]
parent_group = self.env['academic.group'].search(
[('year', '=', year + 1), ('level_id', '=', next_level.id), ('company_id', '=', rec.id), ('parent_id', '=', False)])
group.copy({
'year': year + 1,
'level_id': next_level.id,
'parent_id': parent_group.id,
# por ahora nos pidieron que no copiemos estudiantes
'student_ids': [(5, 0, 0)],
})
# existing_groups_levels = self.env['academic.group'].search(
# [('year', '=', year), ('level_id', '=', level.id), ('company_id', '=', rec.id), ('parent_id', '=', False)]).mapped('level_id')
# for group in rec.company_group_ids:
# if current_index + 1 < len(group.study_plan_level_ids):
# next_level = group.study_plan_level_ids[current_index + 1]
11 changes: 8 additions & 3 deletions academic/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,12 @@ def _compute_same_dni_partner_id(self):
@api.depends('student_group_ids')
def _compute_current_main_group(self):
for rec in self:
# por ahora este campo no permite el caso de un estudiante en mas de un colegio
# eventualmente, si es necesario, tal vez haciedno el campo company depant con la implentación json de 18+
# ya tengamos lo que necesitamos
student_group = rec.student_group_ids.filtered(lambda g: g.year == date.today().year and not g.subject_id)
if len(student_group) > 1:
raise ValidationError("There shouldn't be two groups in the same year without a subject for partner %s." % rec.name)
rec.current_main_group_id = student_group
# if len(student_group) > 1:
# raise ValidationError(
# "There shouldn't be two groups in the same year without a subject for partner %s. (Existing groups: %s)" % (
# rec.name, student_group.mapped('display_name')))
rec.current_main_group_id = student_group[:1]
Loading