Skip to content
Snippets Groups Projects
Commit 66ba7a1b authored by sofiagvaladze's avatar sofiagvaladze
Browse files

[FIX] hr_contract: proceed cron action even when ValidationError occurs


The method update_state is called from cron. When the contracts are
updated couple things are checked. There are constraints set that can
throw ValidationError. As a result, none of the contract states are updated.

In this PR we do the following:
In case the ValidationError occurs when we run the cron, we update
contracts that can be updated, and silently pass the invalid contracts.

task - 3069480

bloupbloup

closes odoo/odoo#110941

Related: odoo/enterprise#36771
Signed-off-by: default avatarYannick Tivisse (yti) <yti@odoo.com>
parent f87daf1d
Branches
Tags
No related merge requests found
......@@ -50,7 +50,7 @@
<field name="model_id" ref="model_hr_contract"/>
<field name="type">ir.actions.server</field>
<field name="state">code</field>
<field name="code">model.update_state()</field>
<field name="code">model.with_context(from_cron=True).update_state()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
......
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import threading
from datetime import date
from dateutil.relativedelta import relativedelta
......@@ -9,6 +11,10 @@ from odoo.exceptions import ValidationError
from odoo.osv import expression
import logging
_logger = logging.getLogger(__name__)
class Contract(models.Model):
_name = 'hr.contract'
_description = 'Contract'
......@@ -130,6 +136,7 @@ class Contract(models.Model):
@api.model
def update_state(self):
from_cron = 'from_cron' in self.env.context
contracts = self.search([
('state', '=', 'open'), ('kanban_state', '!=', 'blocked'),
'|',
......@@ -147,20 +154,23 @@ class Contract(models.Model):
_("The contract of %s is about to expire.", contract.employee_id.name),
user_id=contract.hr_responsible_id.id or self.env.uid)
contracts.write({'kanban_state': 'blocked'})
if contracts:
contracts._safe_write_for_cron({'kanban_state': 'blocked'}, from_cron)
self.search([
contracts_to_close = self.search([
('state', '=', 'open'),
'|',
('date_end', '<=', fields.Date.to_string(date.today() + relativedelta(days=1))),
('visa_expire', '<=', fields.Date.to_string(date.today() + relativedelta(days=1))),
]).write({
'state': 'close'
})
])
self.search([('state', '=', 'draft'), ('kanban_state', '=', 'done'), ('date_start', '<=', fields.Date.to_string(date.today())),]).write({
'state': 'open'
})
if contracts_to_close:
contracts_to_close._safe_write_for_cron({'state': 'close'}, from_cron)
contracts_to_open = self.search([('state', '=', 'draft'), ('kanban_state', '=', 'done'), ('date_start', '<=', fields.Date.to_string(date.today())),])
if contracts_to_open:
contracts_to_open._safe_write_for_cron({'state': 'open'}, from_cron)
contract_ids = self.search([('date_end', '=', False), ('state', '=', 'close'), ('employee_id', '!=', False)])
# Ensure all closed contract followed by a new contract have a end date.
......@@ -172,17 +182,32 @@ class Contract(models.Model):
('date_start', '>', contract.date_start)
], order="date_start asc", limit=1)
if next_contract:
contract.date_end = next_contract.date_start - relativedelta(days=1)
contract._safe_write_for_cron({'date_end': next_contract.date_start - relativedelta(days=1)}, from_cron)
continue
next_contract = self.search([
('employee_id', '=', contract.employee_id.id),
('date_start', '>', contract.date_start)
], order="date_start asc", limit=1)
if next_contract:
contract.date_end = next_contract.date_start - relativedelta(days=1)
contract._safe_write_for_cron({'date_end': next_contract.date_start - relativedelta(days=1)}, from_cron)
return True
def _safe_write_for_cron(self, vals, from_cron=False):
if from_cron:
auto_commit = not getattr(threading.current_thread(), 'testing', False)
for contract in self:
try:
with self.env.cr.savepoint():
contract.write(vals)
except ValidationError as e:
_logger.warning(e)
else:
if auto_commit:
self.env.cr.commit()
else:
self.write(vals)
def _assign_open_contract(self):
for contract in self:
contract.employee_id.sudo().write({'contract_id': contract.id})
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment