Merge branch '16-contract-dev' into 16-career-dev

16-career-dev
Florian Roger 7 months ago
commit aba81ca7f9

@ -10,10 +10,11 @@ Addons for Odoo 16.
| gn_l10n_fr_pcg_asso | 16.0.0.0.3 | French chart of account and fiscal position for NGO's |
| gn_cc | 16.0.0.0.2 | Configuration for French convention collective, with data for IDCC3442 |
| gn_holidays | 16.0.0.0.1 | French configuration for Publics Holidays and Leave Management |
| gn_contract | 16.0.0.0.2 | Amendements to Hr Contracts |
| gn_contract | 16.0.0.0.3 | Amendements to Hr Contracts |
| gn_career | 16.0.0.0.4 | Fiche de poste et évolution de carrière |
## ToDo
## gn_payroll

@ -15,8 +15,16 @@ Module de gestion des avenants aux contrats
- v16.0.0.0.2 (2024/03/10):
- Bouton de création d'un avenant
- Vues des contrats précédents
- v16.0.0.0.3 (2024/03/12):
- Liens entre contrats liés passés et futurs
- model method and Cron job for contract status automation (!! NOT TESTED !!)
- Add date_validity_start and date_validity_end to keep date_start and date_end from contract and keep track of child contracts (avenants) date ranges.
- Addlink to previous and next contract
## Issues
- [] Needs a View for Previous contract (cf issue #9)
- [x] Needs an Action to Create a New Contract linked with a Previous one (cf issue #10)
- [x] Needs a View for Previous contract (cf issue #9)
- [x] Needs an Action to Create a New Contract linked with a Previous one (cf issue #10)
- [x] Creating a New Contract (Avenant) should lead to changements to parent_contract
- [x] associated_contracts should be in the past, and also in the future, so recomputed automatically
- [x] Manage contract's status automatically

@ -1,6 +1,6 @@
{
"name": "Gestion des Contrats: Typologie et Gestion des Avenants",
"version": "16.0.0.0.2",
"version": "16.0.0.0.3",
"category": "HR",
"summary": "Permet de relier entre eux les contrats",
"author": "Le Garage Numérique",
@ -12,6 +12,7 @@
],
"data": [
"data/gn_contract.xml",
"data/gn_contract_cron.xml",
"views/gn_contract.xml",
],
"license": "LGPL-3",

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data noupdate="1">
<record id="cron_update_contract_status" model="ir.cron">
<field name="name">Update Contract Status</field>
<field name="model_id" ref="model_hr_contract"/>
<field name="state">code</field>
<field name="code">model.cron_update_contract_status()</field>
<field name="active" eval="True"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="nextcall" eval="(datetime.now() + timedelta(hours=1)).strftime('%Y-%m-%d 00:10:00')"/>
<field name="doall" eval="False"/>
</record>
</data>
</odoo>

@ -1,7 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import timedelta
from odoo import fields, models, api
from pytz import timezone
import logging
_logger = logging.getLogger(__name__)
@ -9,23 +12,33 @@ _logger = logging.getLogger(__name__)
class GnHrContract(models.Model):
_inherit = "hr.contract"
previous_contract_id = fields.Many2one("hr.contract", string="Contrat précédent (en cas d'avenant, de renouvellement ou de changement de poste)")
previous_contract_id = fields.Many2one("hr.contract", string="Contrat précédent")
next_contract_id = fields.Many2one("hr.contract", string="Contrat suivant")
date_validity_start = fields.Date(string="Date de prise en compte de l'avenant")
date_validity_end = fields.Date(string="Fin de prise en compte de l'avenant")
lineage_sequence_number = fields.Integer(string="Numéro de séquence dans l'historique du salarié", compute='_compute_lineage_sequence_number', store=True)
related_contract_ids = fields.Many2many('hr.contract',
string="Ensemble des contrats liés", compute='_compute_related_contracts')
len_related_contracts = fields.Integer(string="Nombre de contrats liés", compute='_len_related_contracts', store=True)
@api.depends('previous_contract_id')
@api.depends('previous_contract_id', 'next_contract_id')
def _compute_related_contracts(self):
for contract in self:
if contract.previous_contract_id:
previous_contract = contract.previous_contract_id
associated_contract_ids = [previous_contract.id,]
while previous_contract.previous_contract_id:
previous_contract = previous_contract.previous_contract_id
associated_contract_ids = []
if contract.previous_contract_id or contract.next_contract_id:
if contract.previous_contract_id:
previous_contract = contract.previous_contract_id
associated_contract_ids.append(previous_contract.id)
while previous_contract.previous_contract_id:
previous_contract = previous_contract.previous_contract_id
associated_contract_ids.append(previous_contract.id)
if contract.next_contract_id:
next_contract = contract.next_contract_id
associated_contract_ids.append(next_contract.id)
while next_contract.next_contract_id:
next_contract = next_contract.next_contract_id
associated_contract_ids.append(next_contract.id)
contract.related_contract_ids = [(6, 0, associated_contract_ids)]
else:
contract.related_contract_ids = False
@ -62,6 +75,7 @@ class GnHrContract(models.Model):
'previous_contract_id': self.id,
'date_start': self.date_start,
'date_end': self.date_end,
'date_validity_start': fields.Date.context_today(self),
'resource_calendar_id': self.resource_calendar_id.id,
'department_id': self.department_id.id,
'job_id': self.job_id.id,
@ -73,6 +87,9 @@ class GnHrContract(models.Model):
'struct_id': self.struct_id.id,
}
new_contract = self.create(default_vals)
self.write({'next_contract_id': new_contract.id})
for contract in self.related_contract_ids:
contract._compute_related_contracts()
return {
'type': 'ir.actions.act_window',
'name': 'Avenant',
@ -82,6 +99,22 @@ class GnHrContract(models.Model):
'target': 'current',
}
def cron_update_contract_status(self):
"""Scheduled action to update contract statuses based on start and end dates."""
today = fields.Date.context_today(self)
contracts_to_close = self.search([('date_validity_end', '<=', today), ('status', '=', 'open')])
for contract in contracts_to_close:
contract.ensure_one()
contract.write({'status': 'close'})
contracts_to_open = self.search([('date_start', '<=', today), ('date_validity_start', '<=', today), ('status', '=', 'draft'), '|', ('date_validity_end', '>', today), ('date_validity_end', '=', False)])
for contract in contracts_to_open:
contract.ensure_one()
contract.write({'status': 'open'})
if contract.previous_contract_id:
contract.previous_contract_id.write({'status': 'close',
'date_validity_end': contract.date_validity_start - timedelta(days=1)
})
def open_related_contracts(self):
self.ensure_one()

@ -17,10 +17,9 @@ class GnHrEmployee(models.Model):
def _compute_anciennete_start_date(self):
for employee in self:
if employee.contract_id:
contract = employee.contract_id
while contract.previous_contract_id:
contract = contract.previous_contract_id
previous_contract = employee.contract_id
while previous_contract.previous_contract_id:
previous_contract = previous_contract.previous_contract_id
employee.anciennete_start_date = previous_contract.date_start

@ -6,18 +6,30 @@
<field name="priority" eval="30"/>
<field name="inherit_id" ref="hr_contract.hr_contract_view_form"/>
<field name="arch" type="xml">
<data>
<xpath expr="//div[@name='button_box']" position="inside">
<button name="open_related_contracts" type='object' class="oe_stat_button" icon="fa-money" groups="hr_contract.group_hr_contract_manager">
<field name="len_related_contracts" widget="statinfo" string="Contrats liés"/>
</button>
</xpath>
</data>
<data>
<header>
<button name="create_child_contract" type="object" string="Créer un avenant" class="oe_highlight"/>
</header>
</data>
<xpath expr="//div[@name='button_box']" position="inside">
<button name="open_related_contracts" type='object' class="oe_stat_button" icon="fa-money" groups="hr_contract.group_hr_contract_manager">
<field name="len_related_contracts" widget="statinfo" string="Contrats liés"/>
</button>
</xpath>
<xpath expr="//field[@name='date_start']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='date_start']" position="after">
<field name="previous_contract_id" attrs="{'readonly': True, 'invisible': [('previous_contract_id', '=', False)]}"/>
<field name="next_contract_id" attrs="{'readonly': True, 'invisible': [('next_contract_id', '=', False)]}"/>
<field name="date_start" attrs="{'readonly': [('previous_contract_id', '!=', False)]}"/>
<field name="date_validity_start" attrs="{'invisible': [('previous_contract_id', '=', False)]}"/>
</xpath>
<xpath expr="//field[@name='date_end']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='date_end']" position="after">
<field name="date_end" attrs="{'readonly': [('previous_contract_id', '!=', False)]}"/>
<field name="date_validity_end" attrs="{'invisible': [('previous_contract_id', '=', False)]}"/>
</xpath>
<header>
<button name="create_child_contract" type="object" string="Créer un avenant" class="oe_highlight"/>
</header>
</field>
</record>
</odoo>

Loading…
Cancel
Save