job sheet workflow
This commit is contained in:
parent
69b6db9dea
commit
df15154f24
@ -15,7 +15,7 @@ Addons for Odoo 16.
|
||||
| gn_contract_amendment | 16.0.0.0.1 | Amendments to Hr Contract with Prototype Inheritance |
|
||||
| gn_contract_validation | 16.0.0.0.1 | Simple class inheritance from HrContract to add some states |
|
||||
| gn_job_sheet | 16.0.0.0.4 | Fiche de poste |
|
||||
| gn_contract_situation | 16.0.0.0.1 | Multiple Delegation Inheritance to associate original contract, amendments, job sheets |
|
||||
| gn_contract_situation | 16.0.0.0.3 | Multiple Delegation Inheritance to associate original contract, amendments, job sheets |
|
||||
|
||||
## ToDo
|
||||
|
||||
@ -38,4 +38,4 @@ Addons for Odoo 16.
|
||||
- [] compute contract.cc_id from contract.company_id.cc (cf issue #4)
|
||||
- [x] debug entretien start date on creation (cf issue #5)
|
||||
- [x] debug numérotation des entretiens par salarié on creation (cf issue #6)
|
||||
- [] better handling of event creation from entretien (cf issue #7)
|
||||
- [] better handling of event creation from entretien (cf issue #7)
|
||||
|
||||
@ -14,7 +14,15 @@ It uses delegation inheritance, which embed the inherited objects in the current
|
||||
|
||||
# Changelog
|
||||
|
||||
- v16.0.0.0.3 (20204/04/07)
|
||||
- Job Sheet Creation Workflow with wizards
|
||||
- v16.0.0.0.2 (2024/03/24)
|
||||
- First form view
|
||||
- v16.0.0.0.1 (2024/03/23)
|
||||
- inital creation
|
||||
|
||||
# Issues
|
||||
|
||||
- [] Need to delete situation records when writtent without sheet_id nor amendment_id
|
||||
- [] Freeze active records until expiration
|
||||
- [] Debug auto situation creation on amendments and sheets creation
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Gestion des Contrats: Situation de l'éxécution du contrat",
|
||||
"version": "16.0.0.0.2",
|
||||
"version": "16.0.0.0.3",
|
||||
"category": "HR",
|
||||
"summary": "Regroupe les éléments d'évolution du contrat et de son exécution",
|
||||
"author": "Le Garage Numérique",
|
||||
@ -8,13 +8,17 @@
|
||||
"website": "https://odoo.legaragenumerique.fr",
|
||||
"depends": [
|
||||
"hr",
|
||||
"hr_contract",
|
||||
"gn_contract_amendment",
|
||||
"gn_job_sheet",
|
||||
"hr_employee_calendar_planning", # from https://github.com/OCA/hr
|
||||
],
|
||||
"data": [
|
||||
'views/gn_job_sheet.xml',
|
||||
'views/gn_contract_amendment.xml',
|
||||
'views/gn_contract_history.xml',
|
||||
'views/gn_contract_situation.xml',
|
||||
'data/gn_contract_situation.xml',
|
||||
#'data/gn_contract_situation_cron.xml',
|
||||
"security/ir.model.access.csv",
|
||||
],
|
||||
"license": "LGPL-3",
|
||||
|
||||
10
gn_contract_situation/data/gn_contract_situation.xml
Normal file
10
gn_contract_situation/data/gn_contract_situation.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<menuitem
|
||||
id="gn_contract_situation.situations_menu"
|
||||
name="Conditions d'éxecution"
|
||||
parent="hr.menu_hr_employee_payroll"
|
||||
sequence="400"
|
||||
action="action_contract_situation"
|
||||
groups="hr.group_hr_manager"/>
|
||||
</odoo>
|
||||
18
gn_contract_situation/data/gn_contract_situation_cron.xml
Normal file
18
gn_contract_situation/data/gn_contract_situation_cron.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="cron_update_situation_childs_status" model="ir.cron">
|
||||
<field name="name">Update HR Status</field>
|
||||
<field name="model_id" ref="model_hr_contract_situation"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.cron_update_situation_childs_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>
|
||||
@ -2,4 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import gn_contract
|
||||
from . import gn_contract_situation
|
||||
from . import gn_contract_situation
|
||||
from . import gn_job_sheet
|
||||
from . import gn_amendment
|
||||
51
gn_contract_situation/models/gn_amendment.py
Normal file
51
gn_contract_situation/models/gn_amendment.py
Normal file
@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GnHrContractAmendment(models.Model):
|
||||
_inherit = 'hr.contract.amendment'
|
||||
|
||||
situation_ids = fields.One2many('hr.contract.situation', inverse_name='amendment_id', string="Conditions d'éxecution", readonly=True)
|
||||
|
||||
|
||||
|
||||
class AmendmentConfirmationWizard(models.TransientModel):
|
||||
_name = 'amendment.confirmation.wizard'
|
||||
_description = 'Confirm Amendment Creation'
|
||||
|
||||
message = fields.Text(default="Are you sure you want to create a new amendment?")
|
||||
|
||||
def confirm_amendment_creation(self):
|
||||
active_id = self.env.context.get('active_id')
|
||||
# active_id = self.env.context.get('active_id')
|
||||
# situation = self.env['hr.contract.situation'].browse(active_id)
|
||||
# action = self.env.context.get('action')
|
||||
|
||||
# if situation:
|
||||
# new_situation = situation.copy(default={'amendment_id': False})
|
||||
# action['context'].update({
|
||||
# 'default_situation_ids': [(4, new_situation.id)],
|
||||
# })
|
||||
# return action
|
||||
# else:
|
||||
# return
|
||||
action = self.env.context.get('action')
|
||||
# action['context'].update({
|
||||
# 'default_previous_amendment_id': active_id
|
||||
# })
|
||||
return action
|
||||
|
||||
def continue_pending_amendment(self):
|
||||
pending_id = self.env.context.get('pending_id')
|
||||
action = self.env.context.get('action')
|
||||
action['res_id'] = pending_id
|
||||
return action
|
||||
@ -9,10 +9,11 @@ import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class GnHrContract(models.Model):
|
||||
_inherit = "hr.contract"
|
||||
_inherit = 'hr.contract'
|
||||
|
||||
situation_ids = fields.One2many('hr.contract.situation', inverse_name='contract_id', string="Conditions d'éxecution", readonly=True)
|
||||
actual_situation_id = fields.Many2one('hr.contract.situation', compute='_compute_actual_situation_id', string="Conditions d'éxecution en vigueur")
|
||||
active_situation_id = fields.Many2one('hr.contract.situation', compute='_compute_active_situation_id', string="Conditions d'éxecution en vigueur")
|
||||
pending_situation_id = fields.Many2one('hr.contract.situation', compute='_compute_pending_situation_id', string="Conditions d'éxecution en préparation")
|
||||
|
||||
state = fields.Selection([
|
||||
('draft', 'Brouillon'),
|
||||
@ -21,29 +22,58 @@ class GnHrContract(models.Model):
|
||||
('wait_employee_approval', "En attente de signature par le salarié"),
|
||||
('ready', 'Prête'),
|
||||
('active', 'Active'),
|
||||
('expired', 'Expiré')
|
||||
], string="État", default='draft', required=True)
|
||||
|
||||
@api.depends('situation_ids.state')
|
||||
def _compute_actual_situation_id(self):
|
||||
@api.depends('situation_ids', 'situation_ids.state')
|
||||
def _compute_active_situation_id(self):
|
||||
for contract in self:
|
||||
active_situation = contract.situation_ids.filtered(lambda s: s.state == 'active')
|
||||
if len(active_situation) > 1:
|
||||
raise ValidationError("Il ne peut y avoir qu'une condition d'exécution active à la fois.")
|
||||
if len(active_situation) == 0:
|
||||
contract.actual_situation_id = False
|
||||
elif len(active_situation) == 1:
|
||||
contract.active_situation_id = active_situation[:1]
|
||||
else:
|
||||
contract.actual_situation_id = active_situation[:1]
|
||||
contract.active_situation_id = False
|
||||
|
||||
@api.depends('situation_ids', 'situation_ids.state')
|
||||
def _compute_pending_situation_id(self):
|
||||
for contract in self:
|
||||
pending_situation = contract.situation_ids.filtered(lambda s: s.state != 'active' and s.state != 'expired')
|
||||
if len(pending_situation) > 1:
|
||||
contract.pending_situation_id = pending_situation[:1]
|
||||
#raise ValidationError("Il ne peut y avoir qu'une condition d'exécution en préparation à la fois.")
|
||||
elif len(pending_situation) == 1:
|
||||
contract.pending_situation_id = pending_situation[:1]
|
||||
else:
|
||||
contract.pending_situation_id = False
|
||||
|
||||
|
||||
# def generate_situations():
|
||||
|
||||
|
||||
# @api.depends('situation_ids')
|
||||
# def _compute_situations(self):
|
||||
# for contract in self:
|
||||
# situations = self.env['hr.contract.situation'].search(['contract_id', '=', contract.id])
|
||||
# sheets = self.env['hr.job.sheet'].search(['contract_id', '='])
|
||||
|
||||
|
||||
def action_open_contract_situation(self):
|
||||
self.ensure_one()
|
||||
action = self.env['ir.actions.actions']._for_xml_id('gn_contract_situation.action_contract_situation')
|
||||
if self.actual_situation_id:
|
||||
active_situation = self.active_situation_id
|
||||
pending_situation = self.pending_situation_id
|
||||
if active_situation:
|
||||
action.update({
|
||||
'view_mode': 'form',
|
||||
'view_id': self.env.ref('gn_contract_situation.contract_situation_view_form').id,
|
||||
'views': [(self.env.ref('gn_contract_situation.contract_situation_view_form').id, 'form')],
|
||||
'res_id': self.actual_situation_id.id,
|
||||
'res_id': active_situation.id,
|
||||
})
|
||||
elif pending_situation:
|
||||
action.update({
|
||||
'view_mode': 'tree',
|
||||
})
|
||||
else:
|
||||
default_vals = {
|
||||
@ -56,4 +86,4 @@ class GnHrContract(models.Model):
|
||||
'views': [(self.env.ref('gn_contract_situation.contract_situation_view_form').id, 'form')],
|
||||
'res_id': new_situation.id,
|
||||
})
|
||||
return action
|
||||
return action
|
||||
@ -19,14 +19,20 @@ class GnHrContractSituation(models.Model):
|
||||
# 'hr.job.sheet': 'sheet_id'
|
||||
# }
|
||||
|
||||
#Those ondelete=cascade should become rectrict once everything is solid
|
||||
contract_id = fields.Many2one('hr.contract', required=True, auto_join=True, ondelete="cascade")
|
||||
amendment_id = fields.Many2one('hr.contract.amendment', ondelete="cascade")
|
||||
sheet_id = fields.Many2one('hr.job.sheet', ondelete="cascade")
|
||||
#calendar_id = fields.Many2one('hr.employee.calendar', ondelete="cascade")
|
||||
|
||||
name = fields.Char(string="Nom", related='contract_id.name')
|
||||
employee_id = fields.Many2one('hr.employee', related='contract_id.employee_id')
|
||||
|
||||
date_from = fields.Date(string="Fin de validité", compute='_compute_date_from')
|
||||
date_to = fields.Date(string="Fin de validité", compute='_compute_date_to')
|
||||
sheet_name = fields.Char(string="Nom de la fiche de poste", related='sheet_id.name')
|
||||
amendment_name = fields.Char(string="Nom de l'avenant'", related='amendment_id.name')
|
||||
|
||||
date_from = fields.Date(string="Début de validité")#, compute='_compute_date_from')
|
||||
date_to = fields.Date(string="Fin de validité")#, compute='_compute_date_to')
|
||||
|
||||
state = fields.Selection([
|
||||
('draft', 'Brouillon'),
|
||||
@ -35,34 +41,384 @@ class GnHrContractSituation(models.Model):
|
||||
('wait_employee_approval', "En attente de signature par le salarié"),
|
||||
('ready', 'Prête'),
|
||||
('active', 'Active'),
|
||||
], string="État", default='draft', compute='_compute_state', required=True)
|
||||
('expired', "Expirée"),
|
||||
], string="État", default='draft')#, compute='_compute_state', required=True)
|
||||
|
||||
@api.depends('contract_id.state', 'amendment_id.state', 'sheet_id.state')
|
||||
def _compute_state(self):
|
||||
for record in self:
|
||||
if record.contract_id and record.contract_id.state == 'active' and \
|
||||
record.amendment_id and record.amendment_id.state == 'active' and \
|
||||
record.sheet_id and record.sheet_id.state == 'active':
|
||||
record.state = 'active'
|
||||
else:
|
||||
record.state = 'draft'
|
||||
# @api.depends('contract_id.state', 'amendment_id.state', 'sheet_id.state')
|
||||
# def _compute_state(self):
|
||||
# for situation in self:
|
||||
# objects = [situation.contract_id, situation.amendment_id, situation.sheet_id]
|
||||
# defined_states = [object.state for object in objects if object and object.state]
|
||||
# if all(state == 'active' for state in defined_states):
|
||||
# situation.state = 'active'
|
||||
|
||||
@api.depends('contract_id.date_start', 'amendment_id.date_start', 'sheet_id.date_start')
|
||||
def _compute_date_from(self):
|
||||
for situation in self:
|
||||
starts = [situation.contract_id.date_start, situation.amendment_id.date_start, situation.sheet_id.date_start]
|
||||
valid_starts = [start for start in starts if start]
|
||||
if valid_starts:
|
||||
situation.date_from = max(valid_starts)
|
||||
else:
|
||||
situation.date_from = None
|
||||
# @api.depends('contract_id.date_start', 'amendment_id.date_start', 'sheet_id.date_start')
|
||||
# def _compute_date_from(self):
|
||||
# for situation in self:
|
||||
# starts = [situation.contract_id.date_start, situation.amendment_id.date_start, situation.sheet_id.date_start, situation.calendar_id.date_start]
|
||||
# valid_starts = [start for start in starts if start]
|
||||
# if valid_starts:
|
||||
# situation.date_from = max(valid_starts)
|
||||
# else:
|
||||
# situation.date_from = None
|
||||
|
||||
@api.depends('contract_id.date_end', 'amendment_id.date_end', 'sheet_id.date_end')
|
||||
def _compute_date_to(self):
|
||||
for situation in self:
|
||||
ends = [situation.contract_id.date_end, situation.amendment_id.date_end, situation.sheet_id.date_end]
|
||||
valid_ends = [end for end in ends if end]
|
||||
if valid_ends:
|
||||
situation.date_to = min(valid_ends)
|
||||
# @api.depends('contract_id.date_end', 'amendment_id.date_end', 'sheet_id.date_end')
|
||||
# def _compute_date_to(self):
|
||||
# for situation in self:
|
||||
# ends = [situation.contract_id.date_end, situation.amendment_id.date_end, situation.sheet_id.date_end, situation.calendar_id.date_start]
|
||||
# valid_ends = [end for end in ends if end]
|
||||
# if valid_ends:
|
||||
# situation.date_to = min(valid_ends)
|
||||
# else:
|
||||
# situation.date_to = None
|
||||
|
||||
#Cron des status à repenser
|
||||
# def cron_update_situation_childs_status(self):
|
||||
# today = fields.Date.context_today(self)
|
||||
# for records in [
|
||||
# self.env['hr.contract'].search([('state', '=', 'active'), ('date_end', '<', today)]),
|
||||
# self.env['hr.contract.amendment'].search([('state', '=', 'active'), ('date_end', '<', today)]),
|
||||
# self.env['hr.job.sheet'].search([('state', '=', 'active'), ('date_end', '<', today)])
|
||||
# ]:
|
||||
# for record in records:
|
||||
# records.state = 'expired'
|
||||
|
||||
# for records in [
|
||||
# self.env['hr.contract'].search([('state', '=', 'ready'), ('date_start', '<=', today)]),
|
||||
# self.env['hr.contract.amendment'].search([('state', '=', 'ready'), ('date_start' , '<=', today)]),
|
||||
# self.env['hr.job.sheet'].search([('state', '=', 'ready'), ('date_start', '<=', today)]),
|
||||
# ]:
|
||||
# for record in records:
|
||||
# records.state = 'active'
|
||||
## Ici il faut créer 2 activités:
|
||||
# - une première activité pour signaler quand un contrat, un avenant ou une feuille de poste commencent dans 2 jours mais
|
||||
# n'est toujours pas à l'état ready
|
||||
# - une activité pour signaler qu'un des éléments est passé en status 'active', pour que les fiches de paye puissent être établis, mais qu'il attend encore telle ou telle étape.
|
||||
# dans ce cas, il faut modifier le code cron pour passer active les éléments qui ne sont pas en expired ou draft.
|
||||
|
||||
|
||||
def define_first_sheet(self):
|
||||
_logger.warning("Enter in define_first_sheet with situation id %s", self.id)
|
||||
_logger.warning("Associated contract is %s - %s", self.contract_id.id, self.contract_id.name)
|
||||
action = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Modification de la fiche de poste',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'hr.job.sheet',
|
||||
'target': 'current',
|
||||
'context': {
|
||||
'default_situation_ids': [(4, self.id)],
|
||||
'default_contract_id': self.contract_id.id,
|
||||
'default_date_start': self.contract_id.date_start,
|
||||
'default_date_end': self.contract_id.date_end,
|
||||
'default_previous_sheet_id': False,
|
||||
}
|
||||
}
|
||||
return action
|
||||
|
||||
def ask_create_or_modify(self, type, active_id, pending_id):
|
||||
_logger.warning("enter in ask_create_or_modify with situation id %s, type = %s, active_id = %s, pending_id = %s", self.id, type, active_id, pending_id)
|
||||
self.ensure_one()
|
||||
|
||||
action = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'target': 'current',
|
||||
'context': {
|
||||
#'default_situation_ids': [(4, self.id)],
|
||||
'default_contract_id': self.contract_id.id,
|
||||
#'default_date_start': new_date_start,
|
||||
#'default_date_end'contract': self.contract_id.id': self.contract_id.date_end,
|
||||
#'default_previous_sheet_id': active_id if active_id else None,
|
||||
}
|
||||
}
|
||||
|
||||
wizard = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Confirmation',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
#'active_id': active_id,
|
||||
"message": "test",
|
||||
'action': action,
|
||||
'active_id': active_id if active_id else None,
|
||||
'pending_id': pending_id if pending_id else None
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
if type == 'sheet':
|
||||
action['res_model'] = 'hr.job.sheet'
|
||||
action['name'] = "Modification de la fiche de poste"
|
||||
wizard['res_model'] = 'sheet.confirmation.wizard'
|
||||
|
||||
active_sheet = self.env['hr.job.sheet'].browse(active_id) if active_id else False
|
||||
pending_sheet = self.env['hr.job.sheet'].browse(pending_id) if pending_id else False
|
||||
if active_sheet:
|
||||
wizard['context']['message'] = (_("Il existe une fiche de poste active: %s \n\n", active_sheet.name))
|
||||
if pending_sheet:
|
||||
wizard['context']['message'] += (_("Il existe aussi une fiche de poste en préparation: %s \n\n", pending_sheet.name))
|
||||
elif pending_sheet:
|
||||
wizard['context']['message'] = (_("Il existe une fiche de poste en cours de préparation: %s \n\n", pending_sheet.name))
|
||||
wizard['context']['message'] += (_("Que voulez-vous faire ?"))
|
||||
#wizard['context']['active_id'] = None # self.contract_id.active_sheet_id.id
|
||||
|
||||
elif type == 'amendment':
|
||||
model = 'hr.contract.amendment'
|
||||
wizard_model = 'amendment.confirmation.wizard'
|
||||
action_name = "Modification de l'avenant"
|
||||
active_amendment = self.env['hr.contract.amendment'].browse(active_id) if active_id else None
|
||||
pending_amendment = self.env['hr.contract.amendment'].browse(pending_id) if pending_id else None
|
||||
if active_amendment:
|
||||
message = (_("Il existe un \navenant actif - %s - , que voulez-vous faire?
", active_amendment.name))
|
||||
if pending_amendment:
|
||||
message.append(_("Il existe aussi un avenant en préparation - %s", pending_amendment.name))
|
||||
elif pending_amendment:
|
||||
message = (_("Il existe un avenant en cours de préparation - %s", pending_amendment.name))
|
||||
active_id = self.amendment_id.id
|
||||
elif type == 'calendar':
|
||||
model = 'resource.calendar'
|
||||
wizard_model = 'calendar.confirmation.wizard'
|
||||
action_name = "Modification du planning"
|
||||
message = "Voulez-vous modifier l'emploi du temps actif?"
|
||||
active_id = self.calendar_id.id if self.calendar_id else None
|
||||
|
||||
|
||||
|
||||
_logger.warning("Associated contract when calling sheet form from situation form: %s", self.contract_id)
|
||||
|
||||
#return wizard
|
||||
wizard_create = self.env[wizard['res_model']].create({})
|
||||
wizard['res_id'] = wizard_create.id
|
||||
_logger.warning("Wizard generated: %s", wizard)
|
||||
return wizard
|
||||
|
||||
|
||||
|
||||
# def ask_for_temporary(self, type):
|
||||
# #Here we need to create a wizard and get True or False
|
||||
# if type == 'sheet':
|
||||
# res_model = 'sheet.confirmation.wizard'
|
||||
# message = "Voulez-vous modifier la fiche de poste active?"
|
||||
# elif type == 'amendment':
|
||||
# res_model = 'amendment.confirmation.wizard'
|
||||
# message = "Voulez-vous modifier l'avenant actif?"
|
||||
# elif type == 'calendar':
|
||||
# res_model = 'calendar.confirmation.wizard'
|
||||
# message = "Voulez-vous modifier l'emploi du temps actif?"
|
||||
# wizard = {
|
||||
# 'type': 'ir.actions.act_window',
|
||||
# 'name': 'Confirmation',
|
||||
# 'res_model': res_model,
|
||||
# 'view_mode': 'form',
|
||||
# 'target': 'new',
|
||||
# 'context': {
|
||||
# 'default_message': message,
|
||||
# 'active_id': self.id,
|
||||
# 'action': action,
|
||||
# },
|
||||
# }
|
||||
# if type == 'sheet':
|
||||
# # Tell Wizard its a sheet
|
||||
# return True
|
||||
# elif type == 'amendment':
|
||||
# # Tell wizard its amendment
|
||||
# return True
|
||||
# elif type == 'calendar':
|
||||
# # Tell wizard its calendar
|
||||
|
||||
def action_define_sheet(self):
|
||||
_logger.warning("Enter in action define sheet in situation %s", self.id)
|
||||
self.ensure_one()
|
||||
_logger.warning("Actual sheet_id: %s", self.sheet_id.id)
|
||||
_logger.warning("Actual contract_id: %s", self.contract_id.id)
|
||||
pending_sheet_id = self.contract_id.pending_sheet_id.id if self.contract_id.pending_sheet_id else False
|
||||
if not self.sheet_id and not pending_sheet_id:
|
||||
action = self.define_first_sheet()
|
||||
return action
|
||||
else:
|
||||
active_sheet_id = self.contract_id.active_sheet_id.id if self.contract_id.active_sheet_id else False
|
||||
|
||||
|
||||
|
||||
# Call a wizard to ask if:
|
||||
# - they want to modify the sheet in preparation (if it exists)
|
||||
# - or create a temporary sheet
|
||||
# - modify the existing sheet non-permanently (if there is none in preparation)
|
||||
_logger.warning("going to ask or create with active id: %s and pending id: %s", active_sheet_id, pending_sheet_id)
|
||||
wizard = self.ask_create_or_modify(type='sheet', active_id=active_sheet_id, pending_id=pending_sheet_id)
|
||||
return wizard
|
||||
#
|
||||
# Ask if its temporary or permanent
|
||||
# is_temporary = self.ask_for_temporary(type='sheet')
|
||||
# if is_temporary:
|
||||
|
||||
# action = {
|
||||
# 'type': 'ir.actions.act_window',
|
||||
# 'name': 'Modification de la fiche de poste',
|
||||
# 'view_mode': 'form',
|
||||
# 'res_model': 'hr.job.sheet',
|
||||
# 'target': 'current',
|
||||
# 'context': {
|
||||
# 'default_situation_ids': [(4, self.id)],
|
||||
# 'default_contract_id': self.contract_id.id,
|
||||
# 'default_date_start': new_date_start,
|
||||
# 'default_date_end': self.contract_id.date_end,
|
||||
# 'default_previous_sheet_id': self.sheet_id.id,
|
||||
# }
|
||||
# }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# _logger.warning("Actual situation has sheet_id : %s", self.sheet_id.id)
|
||||
# if not self.sheet_id or (self.sheet_id and self.sheet_id.state == 'active'):
|
||||
# tomorrow = fields.Date.context_today(self) + timedelta(days=1)
|
||||
# if not self.sheet_id:
|
||||
# new_date_start = self.contract_id.date_start
|
||||
|
||||
# elif self.sheet_id and self.sheet_id.is_default:
|
||||
# contract_start = self.contract_id.sheet_id.date_start
|
||||
# contract_end = self.contract_id.date_end
|
||||
# if tomorrow >= contract_start and tomorrow <= contract_end:
|
||||
# new_date_start = tomorrow
|
||||
# elif tomorrow < contract_start:
|
||||
# new_date_start = contract_start
|
||||
# else:
|
||||
# new_date_start = contract_end
|
||||
|
||||
|
||||
|
||||
# new_date_start = tomorrow if tomorrow >= self.contract_id.sheet_id.date_start and tomorrow <= self.contract_id.date_end \
|
||||
# else self.contract_id.date_start if tomorrow < self.contract_id.sheet_id.date_start \
|
||||
# else self.contract_id.date_end
|
||||
|
||||
# elif self.sheet_id.date_end and self.contract_id.date_end and self.sheet_id.date_end < self.contract_id.date_end:
|
||||
# new_date_start = self.sheet_id.date_end + timedelta(days=1)
|
||||
# else:
|
||||
# if self.contract_id.date_end and tomorrow > self.contract_id.date_end:
|
||||
# tomorrow = self.contract_id.date_end
|
||||
# new_date_start = tomorrow
|
||||
|
||||
#Ici, il faut traiter la gestion des situations:
|
||||
# Sile contrat a une fiche de poste valide, et qu'on crée un avenant,
|
||||
# il ne faut pas que la situation se décale il faut:
|
||||
# - réduire la date de fin de la 1ere situation avec
|
||||
# * sit1.date_from = sheet.date_start et sit1.date_to = amendment.date_start - 1
|
||||
# créer une 2e situation avec
|
||||
# * sit2.date_from = amendment.date_start et sit2.date_to = amendment.date_end
|
||||
# créer une 3e situation si amendment.date_end < sheet.date_end:
|
||||
# * sit3.date_from = amendment.date_end + 1 et sit3.date_to = sheet.date_end
|
||||
|
||||
|
||||
# action.update({
|
||||
# 'context': {
|
||||
# 'default_situation_ids': [(4, self.id)],
|
||||
# 'default_contract_id': self.contract_id.id,
|
||||
# 'default_date_start': new_date_start,
|
||||
# 'default_date_end': self.contract_id.date_end,
|
||||
# 'default_previous_sheet_id': self.sheet_id.id,
|
||||
# }
|
||||
# })
|
||||
# if self.sheet_id and self.sheet_id.state == 'active':
|
||||
# related_situations = self.contract_id.situation_ids.filtered(lambda s: s.sheet_id and s.sheet_id.state not in ['active', 'expired'])
|
||||
# pending_sheet_id = {situation.sheet_id.id for situation in related_situations}
|
||||
# _logger.warning("Pending sheet id : %s", list(pending_sheet_id)[0] if pending_sheet_id else None )
|
||||
# if len(pending_sheet_id) > 1:
|
||||
# raise ValidationError("More thant 1 sheet in preparation !")
|
||||
# elif pending_sheet_id:
|
||||
# action['res_id'] = list(pending_sheet_id)[0]
|
||||
|
||||
# return {
|
||||
# 'type': 'ir.actions.act_window',
|
||||
# 'name': 'Confirmation',
|
||||
# 'res_model': 'sheet.confirmation.wizard',
|
||||
# 'view_mode': 'form',
|
||||
# 'target': 'new',
|
||||
# 'context': {
|
||||
# 'default_message': 'Voulez-vous modifier la fiche de poste active?',
|
||||
# 'active_id': self.id,
|
||||
# 'action': action,
|
||||
# },
|
||||
# }
|
||||
# else:
|
||||
# action['res_id'] = self.sheet_id.id
|
||||
# if self.sheet_id.state == 'expired':
|
||||
# action.update({
|
||||
# 'flags': {'mode':'readonly'}
|
||||
# })
|
||||
# return action
|
||||
|
||||
|
||||
def action_define_amendment(self):
|
||||
self.ensure_one()
|
||||
action = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': "Création d'un avenant",
|
||||
'view_mode': 'form',
|
||||
'res_model': 'hr.contract.amendment',
|
||||
'target': 'current',
|
||||
'view_id': self.env.ref('gn_contract_situation.gn_contract_amendment_form_with_situation').id,
|
||||
}
|
||||
_logger.warning("Actual situation has amendment_id : %s", self.amendment_id.id)
|
||||
# Si la situation n'est pas encore associée à un avenant ou si elle est associée à un avenant actif:
|
||||
if not self.amendment_id or (self.amendment_id and self.amendment_id.state == 'active'):
|
||||
tomorrow = fields.Date.context_today(self) + timedelta(days=1)
|
||||
# Si il n'y a pas d'avenant, ou que l'avenant n'a pas de date de fin, on met la date de début par défaut au lendemain de l'exécution de l'action ou au début du contrat.
|
||||
if not self.amendment_id or not self.amendment_id.date_end:
|
||||
new_date_start = tomorrow if tomorrow < self.contract_id.date_start and ((not self.contract_id.date_end) or (tomorrow <= self.contract_id.date_end)) else self.contract_id.date_start
|
||||
# Si la situation a un avenant actif avec une date de fin définie avant la fin du contrat,
|
||||
# on met la date de début au lendemain de la fin de l'avenant actif
|
||||
elif self.amendment_id.date_end and (
|
||||
(self.contract_id.date_end and self.amendment_id.date_end < self.contract_id.date_end)
|
||||
or not self.contract_id.date_end):
|
||||
new_date_start = self.amendment_id.date_end + timedelta(days=1)
|
||||
# Le dernier cas est celui où l'avenant termine en même temps que contrat, on raise une Error pour le moment,
|
||||
# en attendant de bien concevoir l'impact sur les dates de contrat de la création d'avenant.
|
||||
else:
|
||||
situation.date_to = None
|
||||
raise ValidationError("Impossible de créer un avenant quand l'avenant précédent se termine en même temps que son contrat associé")
|
||||
# if self.contract_id.date_end and tomorrow > self.contract_id.date_end:
|
||||
# tomorrow = self.contract_id.date_end
|
||||
# new_date_start = tomorrow
|
||||
|
||||
action.update({
|
||||
'context': {
|
||||
'default_situation_ids': [(4, self.id)],
|
||||
'default_contract_id': self.contract_id.id,
|
||||
'default_date_start': new_date_start,
|
||||
'default_date_end': self.contract_id.date_end,
|
||||
'default_previous_amendment_id': self.amendment_id.id,
|
||||
}
|
||||
})
|
||||
if self.amendment_id and self.amendment_id.state == 'active':
|
||||
related_situations = self.contract_id.situation_ids.filtered(lambda s: s.amendment_id and s.amendment_id.state not in ['active', 'expired'])
|
||||
pending_amendment_id = {situation.amendment_id.id for situation in related_situations}
|
||||
_logger.warning("Pending amendment id : %s", list(pending_amendment_id)[0] if pending_amendment_id else None)
|
||||
if len(pending_amendment_id) > 1:
|
||||
raise ValidationError("More thant 1 amendment in preparation !")
|
||||
elif pending_amendment_id:
|
||||
action['res_id'] = list(pending_amendment_id)[0]
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Confirmation',
|
||||
'res_model': 'amendment.confirmation.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_message': "Voulez-vous modifier l'avenant actif?",
|
||||
'active_id': self.id,
|
||||
'action': action,
|
||||
},
|
||||
}
|
||||
else:
|
||||
action['res_id'] = self.amendment_id.id
|
||||
if self.sheet_id.state == 'expired':
|
||||
action.update({
|
||||
'flags': {'mode':'readonly'}
|
||||
})
|
||||
return action
|
||||
290
gn_contract_situation/models/gn_job_sheet.py
Normal file
290
gn_contract_situation/models/gn_job_sheet.py
Normal file
@ -0,0 +1,290 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class GnHrJobSheet(models.Model):
|
||||
_inherit = 'hr.job.sheet'
|
||||
|
||||
situation_ids = fields.One2many('hr.contract.situation', inverse_name='sheet_id', string="Conditions d'éxecution", readonly=True)
|
||||
previous_sheet_id = fields.Many2one('hr.job.sheet', string="Fiche de poste précédente", readonly=True)
|
||||
|
||||
|
||||
# sheet.pending_situation_id = False
|
||||
|
||||
# active_situation_id = fields.Many2one('hr.contract.situation', compute='_compute_active_situation_id', string="Conditions d'éxecution en vigueur")
|
||||
# pending_situation_id = fields.Many2one('hr.contract.situation', compute='_compute_pending_situation_id', string="Conditions d'éxecution en préparation")
|
||||
|
||||
# @api.depends('situation_ids', 'situation_ids.state')
|
||||
# def _compute_active_situation_id(self):
|
||||
# for sheet in self:
|
||||
# active_situation = sheet.situation_ids.filtered(lambda s: s.state == 'active')
|
||||
# if len(active_situation) > 1:
|
||||
# raise ValidationError("Il ne peut y avoir qu'une condition d'exécution active à la fois.")
|
||||
# elif len(active_situation) == 1:
|
||||
# sheet.active_situation_id = active_situation[:1]
|
||||
# else:
|
||||
# sheet.active_situation_id = False
|
||||
|
||||
# @api.depends('situation_ids', 'situation_ids.state')
|
||||
# def _compute_pending_situation_id(self):
|
||||
# for sheet in self:
|
||||
# pending_situation = sheet.situation_ids.filtered(lambda s: s.state != 'active' and s.state != 'expired')
|
||||
# if len(pending_situation) > 1:
|
||||
# sheet.pending_situation_id = pending_situation[:1]
|
||||
# #raise ValidationError("Il ne peut y avoir qu'une condition d'exécution en préparation à la fois.")
|
||||
# elif len(pending_situation) == 1:
|
||||
# sheet.pending_situation_id = pending_situation[:1]
|
||||
# else:
|
||||
# sheet.pending_situation_id = False
|
||||
|
||||
# I think this is not necessary anymore
|
||||
# ## Checks for start_date
|
||||
# def start_date_before_previous_sheet(self):
|
||||
# if self.previous_sheet_id and self.date_start and self.date_start < self.previous_sheet_id.date_start:
|
||||
# raise ValidationError("The start date cannot be before the previous sheet start date.")
|
||||
|
||||
# def start_date_equals_previous_sheet(self):
|
||||
# if self.previous_sheet_id and self.date_start and self.date_start == self.previous_sheet_id.date_start:
|
||||
# raise ValidationError("The start date cannot be the same day than the previous sheet start date.")
|
||||
|
||||
# @api.constrains('date_start')
|
||||
# def _limit_date_start(self):
|
||||
# for sheet in self:
|
||||
# sheet.start_date_before_previous_sheet()
|
||||
# sheet.start_date_equals_previous_sheet()
|
||||
# if self.previous_sheet_id:
|
||||
# self.previous_sheet_id.date_end = self.date_start - timedelta(days=1)
|
||||
|
||||
# @api.onchange('date_start')
|
||||
# def _onchange_date_start(self):
|
||||
# self.start_date_before_previous_sheet()
|
||||
# self.start_date_equals_previous_sheet()
|
||||
# if self.previous_sheet_id:
|
||||
# self.previous_sheet_id.date_end = self.date_start - timedelta(days=1)
|
||||
|
||||
|
||||
# ## Checks for end_date
|
||||
|
||||
# def end_date_before_previous_sheet(self):
|
||||
# if self.previous_sheet_id and self.previous_sheet_id.date_end and self.date_end and self.date_end < self.previous_sheet_id.date_end:
|
||||
# raise ValidationError("The end date cannot be before the previous sheet end date.")
|
||||
|
||||
# def end_date_equals_previous_sheet(self):
|
||||
# if self.previous_sheet_id and self.previous_sheet_id.date_end and self.date_end and self.date_end == self.previous_sheet_id.date_end:
|
||||
# # dans le cas où le jour de début la prise de poste est le même que celle qui est déjà active,
|
||||
# # on doit insérer ici une confirmation,
|
||||
# #pour modifier la fiche de poste précédente, et supprimer celle en cours
|
||||
# # ainsi que la nouvelle situation associée
|
||||
# _logger.warning("Wizard à insérer ici pour écraser la fiche de poste active")
|
||||
# raise ValidationError("The end date cannot be the same day than the previous sheet end date.")
|
||||
|
||||
# @api.constrains('date_end')
|
||||
# def _limit_date_end(self):
|
||||
# for sheet in self:
|
||||
# sheet.end_date_before_previous_sheet()
|
||||
# sheet.end_date_equals_previous_sheet()
|
||||
|
||||
# @api.onchange('date_end')
|
||||
# def _onchange_date_end(self):
|
||||
# self.end_date_before_previous_sheet()
|
||||
# self.end_date_equals_previous_sheet()
|
||||
# # if self.previous_sheet_id:
|
||||
# # self.previous_sheet_id.date_end = self.date_end - timedelta(days=1)
|
||||
|
||||
|
||||
class SheetDaterangeWizard(models.TransientModel):
|
||||
_name = 'sheet.daterange.wizard'
|
||||
_description = 'Select dates'
|
||||
|
||||
|
||||
|
||||
message = fields.Text(compute='_compute_message')
|
||||
is_permanent = fields.Boolean(string="Remplacement permanent", default=True, compute='_compute_permanency')
|
||||
date_start = fields.Date(string="Date de début", default=lambda self: fields.Date.context_today(self))
|
||||
date_end = fields.Date(string="Date de fin", default=lambda self: self._compute_default_date_end())
|
||||
|
||||
def _compute_default_date_end(self):
|
||||
active_id = self._context.get('active_id')
|
||||
if active_id:
|
||||
previous_sheet = self.env['hr.job.sheet'].browse(active_id)
|
||||
return previous_sheet.date_end
|
||||
return False
|
||||
|
||||
def _compute_message(self):
|
||||
_logger.warning("Message: %s", self._context.get('message'))
|
||||
for record in self:
|
||||
#_logger.warning("Message: %s", self._context.get('message'))
|
||||
record.message = self._context.get('message')
|
||||
|
||||
def _compute_permanency(self):
|
||||
for record in self:
|
||||
record.is_permanent = self._context.get('is_permanent')
|
||||
|
||||
def confirm_dates(self):
|
||||
active_id = self._context.get('active_id')
|
||||
#previous_sheet = self.env['hr.job.sheet'].browse(active_id)
|
||||
action = self._context.get('action')
|
||||
action['context'].update({
|
||||
'default_previous_sheet_id': active_id,
|
||||
'default_date_start': self.date_start,
|
||||
'default_date_end': self.date_end,
|
||||
})
|
||||
return action
|
||||
|
||||
|
||||
class SheetTemporalityWizard(models.TransientModel):
|
||||
_name = 'sheet.temporality.wizard'
|
||||
_description = 'Ask if temporary or permanent'
|
||||
|
||||
message = fields.Text(compute='_compute_message')
|
||||
|
||||
def _compute_message(self):
|
||||
_logger.warning("Message: %s", self._context.get('message'))
|
||||
for record in self:
|
||||
#_logger.warning("Message: %s", self._context.get('message'))
|
||||
record.message = self._context.get('message')
|
||||
|
||||
def is_temporary(self):
|
||||
active_id = self._context.get('active_id')
|
||||
previous_sheet = self.env['hr.job.sheet'].browse(active_id)
|
||||
action = self._context.get('action')
|
||||
action['context'].update({
|
||||
'default_previous_sheet_id': active_id,
|
||||
'default_date_start': fields.Date.context_today(self),
|
||||
'default_date_end': previous_sheet.date_end
|
||||
})
|
||||
wizard = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Confirmation',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'res_model': 'sheet.daterange.wizard',
|
||||
'context': {
|
||||
"is_permanent": False,
|
||||
"message": (_("Vous avez choisi une modification temporaire de la fiche de poste active.\nSur quelle période voulez-vous que s'applique le changement?")),
|
||||
'action': action,
|
||||
'active_id': active_id if active_id else None,
|
||||
},
|
||||
}
|
||||
|
||||
wizard_create = self.env['sheet.daterange.wizard'].create({})
|
||||
wizard['res_id'] = wizard_create.id
|
||||
_logger.warning("Wizard generated: %s", wizard)
|
||||
return wizard
|
||||
|
||||
def is_permanent(self):
|
||||
active_id = self._context.get('active_id')
|
||||
previous_sheet = self.env['hr.job.sheet'].browse(active_id)
|
||||
action = self._context.get('action')
|
||||
action['context'].update({
|
||||
'default_previous_sheet_id': active_id,
|
||||
'default_date_end': previous_sheet.date_end
|
||||
})
|
||||
wizard = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Confirmation',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'res_model': 'sheet.daterange.wizard',
|
||||
'context': {
|
||||
"is_permanent": True,
|
||||
"message": (_("Vous avez choisi une modification permanente de la fiche de poste active.\nÀ partir de quelle date voulez-vous que s'applique le changement?")),
|
||||
'action': action,
|
||||
'active_id': active_id if active_id else None,
|
||||
},
|
||||
}
|
||||
|
||||
wizard_create = self.env['sheet.daterange.wizard'].create({})
|
||||
wizard['res_id'] = wizard_create.id
|
||||
_logger.warning("Wizard generated: %s", wizard)
|
||||
return wizard
|
||||
|
||||
|
||||
class SheetConfirmationWizard(models.TransientModel):
|
||||
_name = 'sheet.confirmation.wizard'
|
||||
_description = 'Confirm Sheet Creation'
|
||||
|
||||
message = fields.Text(compute='_compute_message', precompute=True)
|
||||
|
||||
has_active_id = fields.Boolean(compute='_compute_has_active_id', precompute=True)
|
||||
has_pending_id = fields.Boolean(compute='_compute_has_pending_id', precompute=True)
|
||||
|
||||
def _compute_message(self):
|
||||
_logger.warning("Message: %s", self._context.get('message'))
|
||||
for record in self:
|
||||
#_logger.warning("Message: %s", self._context.get('message'))
|
||||
record.message = self._context.get('message')
|
||||
|
||||
def _compute_has_active_id(self):
|
||||
for record in self:
|
||||
active_id = self._context['active_id']
|
||||
record.has_active_id = True if active_id and active_id != None else False
|
||||
_logger.warning("has_active_id: %s", record.has_active_id)
|
||||
|
||||
def _compute_has_pending_id(self):
|
||||
for record in self:
|
||||
pending_id = self._context['pending_id']
|
||||
record.has_pending_id = True if pending_id and pending_id != None else False
|
||||
_logger.warning("has_pending_id: %s", record.has_pending_id)
|
||||
|
||||
def confirm_sheet_creation(self):
|
||||
active_id = self._context.get('active_id')
|
||||
previous_sheet = self.env['hr.job.sheet'].browse(active_id)
|
||||
# situation = self.env['hr.job.sheet'].browse(active_id)
|
||||
# action = self.env.context.get('action')
|
||||
# contract = self.env.context.get('contract_id')
|
||||
|
||||
# if situation:
|
||||
# #new_situation = situation.copy(default={'sheet_id': False})
|
||||
# contract_id = contract
|
||||
# action['context'].update({
|
||||
# 'default_situation_ids': [(4, new_situation.id)],
|
||||
# })
|
||||
# return action
|
||||
# else:
|
||||
# return
|
||||
action = self._context.get('action')
|
||||
action['context'].update({
|
||||
'default_previous_sheet_id': active_id,
|
||||
})
|
||||
|
||||
wizard = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Confirmation',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'res_model': 'sheet.temporality.wizard',
|
||||
'context': {
|
||||
"message": (_("La fiche de poste actuelle est: %s ,\n\nVoulez-vous créer une fiche de poste temporaire pour faire état d'un changement ponctuel de missions,\n\nou voulez-vous modifier la fiche de poste permanente du salarié?\n\n", previous_sheet.name)),
|
||||
'action': action,
|
||||
'active_id': active_id if active_id else None,
|
||||
},
|
||||
}
|
||||
|
||||
wizard_create = self.env['sheet.temporality.wizard'].create({})
|
||||
wizard['res_id'] = wizard_create.id
|
||||
_logger.warning("Wizard generated: %s", wizard)
|
||||
return wizard
|
||||
|
||||
def see_active_sheet(self):
|
||||
active_id = self._context.get('active_id')
|
||||
action = self._context.get('action')
|
||||
action['res_id'] = active_id
|
||||
action['flags'] = {'mode': 'readonly'}
|
||||
#_logger.warning("action: %s", action)
|
||||
return action
|
||||
|
||||
def continue_pending_sheet(self):
|
||||
pending_id = self._context.get('pending_id')
|
||||
action = self._context.get('action')
|
||||
action['res_id'] = pending_id
|
||||
#_logger.warning("action: %s", action)
|
||||
return action
|
||||
@ -1,3 +1,11 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_hr_contract_situation_user,hr_contract_situation_user,model_hr_contract_situation,base.group_user,1,0,0,0
|
||||
access_hr_contract_situation_admin,hr_contract_situation_admin,model_hr_contract_situation,hr_contract.group_hr_contract_manager,1,1,1,1
|
||||
access_hr_contract_situation_admin,hr_contract_situation_admin,model_hr_contract_situation,hr_contract.group_hr_contract_manager,1,1,1,1
|
||||
access_sheet_confirmation_wizard_user,sheet_confirmation_wizard_user,model_sheet_confirmation_wizard,base.group_user,1,0,0,0
|
||||
access_sheet_confirmation_wizard_admin,sheet_confirmation_wizard_admin,model_sheet_confirmation_wizard,hr_contract.group_hr_contract_manager,1,1,1,1
|
||||
access_amendment_confirmation_wizard_user,amendment_confirmation_wizard_user,model_amendment_confirmation_wizard,base.group_user,1,0,0,0
|
||||
access_amendment_confirmation_wizard_admin,amendment_confirmation_wizard_admin,model_amendment_confirmation_wizard,hr_contract.group_hr_contract_manager,1,1,1,1
|
||||
access_sheet_temporality_wizard_user,sheet_temporality_wizard_user,model_sheet_temporality_wizard,base.group_user,1,0,0,0
|
||||
access_sheet_temporality_wizard_admin,sheet_temporality_wizard_admin,model_sheet_temporality_wizard,hr_contract.group_hr_contract_manager,1,1,1,1
|
||||
access_sheet_daterange_wizard_user,sheet_daterange_wizard_user,model_sheet_daterange_wizard,base.group_user,1,0,0,0
|
||||
access_sheet_daterange_wizard_admin,sheet_daterange_wizard_admin,model_sheet_daterange_wizard,hr_contract.group_hr_contract_manager,1,1,1,1
|
||||
|
27
gn_contract_situation/views/gn_contract_amendment.xml
Normal file
27
gn_contract_situation/views/gn_contract_amendment.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="gn_contract_amendment_form_with_situation" model="ir.ui.view">
|
||||
<field name="name">hr.contract.amendment.form_with_situation</field>
|
||||
<field name="model">hr.contract.amendment</field>
|
||||
<field name="inherit_id" ref="gn_contract_amendment.gn_contract_amendment_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='date_start']" position="after">
|
||||
<field name="situation_ids"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_amendment_confirmation_wizard_form" model="ir.ui.view">
|
||||
<field name="name">amendment.confirmation.wizard.form</field>
|
||||
<field name="model">amendment.confirmation.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Confirmation">
|
||||
<field name="message" nolabel="1"/>
|
||||
<footer>
|
||||
<button name="confirm_amendment_creation" string="Confirm" type="object" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-default" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@ -9,35 +9,79 @@
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_contract_situation_view_tree" model="ir.ui.view">
|
||||
<field name="name">hr.contract.situation.tree</field>
|
||||
<field name="model">hr.contract.situation</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="États des contrats">
|
||||
<field name="employee_id"/>
|
||||
<field name="contract_id"/>
|
||||
<field name="amendment_id"/>
|
||||
<field name="sheet_id"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="state" widget="label_selection" options="{'classes': {'draft': 'default', 'wait_manager_approval': 'default', 'wait_director_approval': 'default', 'ready': 'success', 'active': 'success', 'expired': 'danger'}}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="contract_situation_view_form" model="ir.ui.view">
|
||||
<field name="name">hr.contract.situation.form</field>
|
||||
<field name="model">hr.contract.situation</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Current Contract">
|
||||
<header>
|
||||
<button name="action_define_sheet" type="object"
|
||||
groups="hr_contract.group_hr_contract_manager"
|
||||
string="Définir la fiche de poste" class="oe_highlight"
|
||||
attrs="{'invisible': [('sheet_id', '!=', False)]}"/>
|
||||
<button name="action_define_sheet" type="object"
|
||||
groups="hr_contract.group_hr_contract_manager"
|
||||
string="Modifier la fiche de poste" class="oe_highlight"
|
||||
attrs="{'invisible': [('sheet_id', '=', False)]}"/>
|
||||
<button name="action_define_amendment" type="object"
|
||||
groups="hr_contract.group_hr_contract_manager"
|
||||
string="Créer un avenant" class="oe_highlight"
|
||||
attrs="{'invisible': [('amendment_id', '!=', False)]}"/>
|
||||
<button name="action_define_amendment" type="object"
|
||||
groups="hr_contract.group_hr_contract_manager"
|
||||
string="Modifier l'avenant'" class="oe_highlight"
|
||||
attrs="{'invisible': [('amendment_id', '=', False)]}"/>
|
||||
<!--<button name="cron_update_situation_childs_status" type="object"
|
||||
groups="hr_contract.group_hr_contract_manager"
|
||||
string="Mettre à jour les états" class="oe_highlight" />-->
|
||||
<field name="state" groups="!hr_contract.group_hr_contract_manager" widget="statusbar"/>
|
||||
<field name="state" groups="hr_contract.group_hr_contract_manager" widget="statusbar" options="{'clickable': '1'}"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="employee_id" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="employee_id" placeholder="Employee"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group col="4">
|
||||
<label for="date_from" string="Period"/>
|
||||
<div>
|
||||
<field name="date_from" widget="daterange" class="oe_inline" options="{'related_end_date': 'date_to'}"/>
|
||||
-
|
||||
<field name="date_to" widget="daterange" class="oe_inline" options="{'related_start_date': 'date_from'}"/>
|
||||
<sheet class="mx-1">
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
</div>
|
||||
<field name="contract_id" domain="[('employee_id','=',employee_id),('date_start','<=',date_to),'|',('date_end','>=',date_from),('date_end','=',False)]" context="{'default_employee_id': employee_id}"/>
|
||||
<field name="amendment_id"/>
|
||||
<field name="sheet_id"/>
|
||||
</group>
|
||||
<div class="oe_title">
|
||||
<label for="employee_id" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="employee_id" placeholder="Employee"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<label for="date_from" string="Period"/>
|
||||
<div>
|
||||
<field name="date_from" widget="daterange" class="oe_inline" options="{'related_end_date': 'date_to'}"/>
|
||||
-
|
||||
<field name="date_to" widget="daterange" class="oe_inline" options="{'related_start_date': 'date_from'}"/>
|
||||
</div>
|
||||
<field name="contract_id" attrs="{'readonly': True}" domain="[('employee_id','=',employee_id),('date_start','<=',date_to),'|',('date_end','>=',date_from),('date_end','=',False)]" context="{'default_employee_id': employee_id}"/>
|
||||
<field name="amendment_id" attrs="{'readonly': True}"/>
|
||||
<field name="sheet_id" attrs="{'readonly': True}"/>
|
||||
</group>
|
||||
</sheet>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="sheet_name" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="sheet_name" placeholder="Employee"/>
|
||||
</h1>
|
||||
</div>
|
||||
</sheet>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
@ -45,7 +89,7 @@
|
||||
<record id="action_contract_situation" model="ir.actions.act_window">
|
||||
<field name="name">Contracts</field>
|
||||
<field name="res_model">hr.contract.situation</field>
|
||||
<field name="view_mode">kanban,tree,form,activity</field>
|
||||
<field name="view_mode">tree,kanban,form,activity</field>
|
||||
<field name="domain">[('employee_id', '!=', False)]</field>
|
||||
<field name="context">{'search_default_group_by_state': 1}</field>
|
||||
<field name="search_view_id" ref="hr_contract_situation_view_search"/>
|
||||
|
||||
80
gn_contract_situation/views/gn_job_sheet.xml
Normal file
80
gn_contract_situation/views/gn_job_sheet.xml
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="gn_job_sheet_form_with_situation" model="ir.ui.view">
|
||||
<field name="name">hr.job.sheet.form_with_situation</field>
|
||||
<field name="model">hr.job.sheet</field>
|
||||
<field name="inherit_id" ref="gn_job_sheet.gn_job_sheet_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[.//field[@name='date_start']]" position="after">
|
||||
<field name="situation_ids"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='state_group']" position="replace">
|
||||
<field name="state" groups="!hr_contract.group_hr_contract_manager" widget="statusbar"/>
|
||||
<field name="state" groups="hr_contract.group_hr_contract_manager" widget="statusbar"
|
||||
options="{'clickable': '1'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_sheet_confirmation_wizard_form" model="ir.ui.view">
|
||||
<field name="name">sheet.confirmation.wizard.form</field>
|
||||
<field name="model">sheet.confirmation.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Confirmation">
|
||||
<field name="message" nolabel="1"/>
|
||||
<field name='has_active_id' invisible="1"/>
|
||||
<field name='has_pending_id' invisible="1"/>
|
||||
<footer>
|
||||
<button name="confirm_sheet_creation" string="Nouvelle fiche de poste" type="object" class="btn-primary"
|
||||
attrs="{'invisible':[('has_pending_id', '=', True)]}"/>
|
||||
<button name="see_active_sheet" string="Voir la fiche de poste active" type="object" class="btn-primary"
|
||||
attrs="{'invisible':[('has_active_id', '=', False)]}"/>
|
||||
<button name="continue_pending_sheet" string="Reprendre la fiche en préparation" type="object" class="btn-primary"
|
||||
attrs="{'invisible':[('has_pending_id', '=', False)]}"/>
|
||||
<button string="Cancel" class="btn-default" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_sheet_temporality_wizard_form" model="ir.ui.view">
|
||||
<field name="name">sheet.temporality.wizard.form</field>
|
||||
<field name="model">sheet.temporality.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Temporality">
|
||||
<field name="message" nolabel="1"/>
|
||||
<footer>
|
||||
<button name="is_temporary" string="Créer une fiche de poste temporaire" type="object" class="btn-primary"/>
|
||||
<button name="is_permanent" string="Remplacer la fiche actuelle" type="object" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-default" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_sheet_daterange_wizard_form" model="ir.ui.view">
|
||||
<field name="name">sheet.daterange.wizard.form</field>
|
||||
<field name="model">sheet.daterange.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Temporality">
|
||||
<field name="message" nolabel="1"/>
|
||||
<field name='is_permanent' invisible="1"/>
|
||||
<group name="dates">
|
||||
<label for="date_start" string="Date de début" attrs="{'invisible':[('is_permanent', '=', False)]}"/>
|
||||
<label for="date_start" string="Période" attrs="{'invisible':[('is_permanent', '=', True)]}"/>
|
||||
<div attrs="{'invisible':[('is_permanent', '=', False)]}">
|
||||
<field name="date_start"/>
|
||||
</div>
|
||||
<div attrs="{'invisible':[('is_permanent', '=', True)]}">
|
||||
<field name="date_start" widget="daterange" class="oe_inline" options="{'related_end_date': 'date_end'}"/>
|
||||
-
|
||||
<field name="date_end" widget="daterange" class="oe_inline" options="{'related_start_date': 'date_start'}"/>
|
||||
</div>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="confirm_dates" string="Valider la date de début" type="object" class="btn-primary" attrs="{'invisible':[('is_permanent', '=', False)]}"/>
|
||||
<button name="confirm_dates" string="Valider la période" type="object" class="btn-primary" attrs="{'invisible':[('is_permanent', '=', True)]}"/>
|
||||
<button string="Cancel" class="btn-default" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Loading…
x
Reference in New Issue
Block a user