mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
[IMP] - use terminate term instead of resiliate
This commit is contained in:
@@ -24,7 +24,7 @@
|
|||||||
'security/contract_tag.xml',
|
'security/contract_tag.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'security/contract_security.xml',
|
'security/contract_security.xml',
|
||||||
'security/contract_resiliate_reason.xml',
|
'security/contract_terminate_reason.xml',
|
||||||
'report/report_contract.xml',
|
'report/report_contract.xml',
|
||||||
'report/contract_views.xml',
|
'report/contract_views.xml',
|
||||||
'data/contract_cron.xml',
|
'data/contract_cron.xml',
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
'data/mail_template.xml',
|
'data/mail_template.xml',
|
||||||
'wizards/contract_line_wizard.xml',
|
'wizards/contract_line_wizard.xml',
|
||||||
'wizards/contract_manually_create_invoice.xml',
|
'wizards/contract_manually_create_invoice.xml',
|
||||||
'wizards/contract_contract_resiliate.xml',
|
'wizards/contract_contract_terminate.xml',
|
||||||
'views/abstract_contract_line.xml',
|
'views/abstract_contract_line.xml',
|
||||||
'views/contract.xml',
|
'views/contract.xml',
|
||||||
'views/contract_line.xml',
|
'views/contract_line.xml',
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
'views/contract_template_line.xml',
|
'views/contract_template_line.xml',
|
||||||
'views/res_partner_view.xml',
|
'views/res_partner_view.xml',
|
||||||
'views/res_config_settings.xml',
|
'views/res_config_settings.xml',
|
||||||
'views/contract_resiliate_reason.xml',
|
'views/contract_terminate_reason.xml',
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ from . import res_partner
|
|||||||
from . import contract_tag
|
from . import contract_tag
|
||||||
from . import res_company
|
from . import res_company
|
||||||
from . import res_config_settings
|
from . import res_config_settings
|
||||||
from . import contract_resiliate_reason
|
from . import contract_terminate_reason
|
||||||
|
|||||||
@@ -93,25 +93,25 @@ class ContractContract(models.Model):
|
|||||||
)
|
)
|
||||||
tag_ids = fields.Many2many(comodel_name="contract.tag", string="Tags")
|
tag_ids = fields.Many2many(comodel_name="contract.tag", string="Tags")
|
||||||
note = fields.Text(string="Notes")
|
note = fields.Text(string="Notes")
|
||||||
is_resiliated = fields.Boolean(
|
is_terminated = fields.Boolean(
|
||||||
string="Resiliated", readonly=True, copy=False
|
string="Terminated", readonly=True, copy=False
|
||||||
)
|
)
|
||||||
resiliate_reason_id = fields.Many2one(
|
terminate_reason_id = fields.Many2one(
|
||||||
comodel_name="contract.resiliate.reason",
|
comodel_name="contract.terminate.reason",
|
||||||
string="Resiliate Reason",
|
string="Termination Reason",
|
||||||
ondelete="restrict",
|
ondelete="restrict",
|
||||||
readonly=True,
|
readonly=True,
|
||||||
copy=False,
|
copy=False,
|
||||||
track_visibility="onchange",
|
track_visibility="onchange",
|
||||||
)
|
)
|
||||||
resiliate_comment = fields.Text(
|
terminate_comment = fields.Text(
|
||||||
string="Resiliate Comment",
|
string="Termination Comment",
|
||||||
readonly=True,
|
readonly=True,
|
||||||
copy=False,
|
copy=False,
|
||||||
track_visibility="onchange",
|
track_visibility="onchange",
|
||||||
)
|
)
|
||||||
resiliate_date = fields.Date(
|
terminate_date = fields.Date(
|
||||||
string="Resiliate Date",
|
string="Termination Date",
|
||||||
readonly=True,
|
readonly=True,
|
||||||
copy=False,
|
copy=False,
|
||||||
track_visibility="onchange",
|
track_visibility="onchange",
|
||||||
@@ -483,13 +483,13 @@ class ContractContract(models.Model):
|
|||||||
return contracts_to_invoice._recurring_create_invoice(date_ref)
|
return contracts_to_invoice._recurring_create_invoice(date_ref)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def action_resiliate_contract(self):
|
def action_terminate_contract(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
context = {"default_contract_id": self.id}
|
context = {"default_contract_id": self.id}
|
||||||
return {
|
return {
|
||||||
'type': 'ir.actions.act_window',
|
'type': 'ir.actions.act_window',
|
||||||
'name': _('Resiliate Contract'),
|
'name': _('Terminate Contract'),
|
||||||
'res_model': 'contract.contract.resiliate',
|
'res_model': 'contract.contract.terminate',
|
||||||
'view_type': 'form',
|
'view_type': 'form',
|
||||||
'view_mode': 'form',
|
'view_mode': 'form',
|
||||||
'target': 'new',
|
'target': 'new',
|
||||||
@@ -497,27 +497,27 @@ class ContractContract(models.Model):
|
|||||||
}
|
}
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def _resiliate_contract(
|
def _terminate_contract(
|
||||||
self, resiliate_reason_id, resiliate_comment, resiliate_date
|
self, terminate_reason_id, terminate_comment, terminate_date
|
||||||
):
|
):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
if not self.env.user.has_group("contract.can_resiliate_contract"):
|
if not self.env.user.has_group("contract.can_terminate_contract"):
|
||||||
raise UserError(_('You are not allowed to resiliate contracts.'))
|
raise UserError(_('You are not allowed to terminate contracts.'))
|
||||||
self.contract_line_ids.filtered('is_stop_allowed').stop(resiliate_date)
|
self.contract_line_ids.filtered('is_stop_allowed').stop(terminate_date)
|
||||||
self.write({
|
self.write({
|
||||||
'is_resiliated': True,
|
'is_terminated': True,
|
||||||
'resiliate_reason_id': resiliate_reason_id.id,
|
'terminate_reason_id': terminate_reason_id.id,
|
||||||
'resiliate_comment': resiliate_comment,
|
'terminate_comment': terminate_comment,
|
||||||
'resiliate_date': resiliate_date,
|
'terminate_date': terminate_date,
|
||||||
})
|
})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def action_cancel_contract_resiliation(self):
|
def action_cancel_contract_termination(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
self.write({
|
self.write({
|
||||||
'is_resiliated': False,
|
'is_terminated': False,
|
||||||
'resiliate_reason_id': False,
|
'terminate_reason_id': False,
|
||||||
'resiliate_comment': False,
|
'terminate_comment': False,
|
||||||
'resiliate_date': False,
|
'terminate_date': False,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -296,11 +296,11 @@ class ContractLine(models.Model):
|
|||||||
'successor_contract_line_id',
|
'successor_contract_line_id',
|
||||||
'predecessor_contract_line_id',
|
'predecessor_contract_line_id',
|
||||||
'is_canceled',
|
'is_canceled',
|
||||||
'contract_id.is_resiliated',
|
'contract_id.is_terminated',
|
||||||
)
|
)
|
||||||
def _compute_allowed(self):
|
def _compute_allowed(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
if rec.contract_id.is_resiliated:
|
if rec.contract_id.is_terminated:
|
||||||
rec.update({
|
rec.update({
|
||||||
'is_plan_successor_allowed': False,
|
'is_plan_successor_allowed': False,
|
||||||
'is_stop_plan_successor_allowed': False,
|
'is_stop_plan_successor_allowed': False,
|
||||||
@@ -1174,7 +1174,7 @@ class ContractLine(models.Model):
|
|||||||
).id
|
).id
|
||||||
return {
|
return {
|
||||||
'type': 'ir.actions.act_window',
|
'type': 'ir.actions.act_window',
|
||||||
'name': 'Resiliate contract line',
|
'name': 'Terminate contract line',
|
||||||
'res_model': 'contract.line.wizard',
|
'res_model': 'contract.line.wizard',
|
||||||
'view_type': 'form',
|
'view_type': 'form',
|
||||||
'view_mode': 'form',
|
'view_mode': 'form',
|
||||||
@@ -1262,7 +1262,7 @@ class ContractLine(models.Model):
|
|||||||
@api.model
|
@api.model
|
||||||
def _contract_line_to_renew_domain(self):
|
def _contract_line_to_renew_domain(self):
|
||||||
return [
|
return [
|
||||||
('contract_id.is_resiliated', '=', False),
|
('contract_id.is_terminated', '=', False),
|
||||||
('is_auto_renew', '=', True),
|
('is_auto_renew', '=', True),
|
||||||
('is_canceled', '=', False),
|
('is_canceled', '=', False),
|
||||||
('termination_notice_date', '<=', fields.Date.context_today(self)),
|
('termination_notice_date', '<=', fields.Date.context_today(self)),
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
# Copyright 2020 ACSONE SA/NV
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
|
|
||||||
from odoo import fields, models
|
|
||||||
|
|
||||||
|
|
||||||
class ContractResiliateReason(models.Model):
|
|
||||||
|
|
||||||
_name = 'contract.resiliate.reason'
|
|
||||||
_description = 'Contract Resiliation Reason'
|
|
||||||
|
|
||||||
name = fields.Char(required=True)
|
|
||||||
resiliate_comment_required = fields.Boolean(
|
|
||||||
string="Require a resiliation comment", default=True
|
|
||||||
)
|
|
||||||
15
contract/models/contract_terminate_reason.py
Normal file
15
contract/models/contract_terminate_reason.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2020 ACSONE SA/NV
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class ContractTerminateReason(models.Model):
|
||||||
|
|
||||||
|
_name = 'contract.terminate.reason'
|
||||||
|
_description = 'Contract Termination Reason'
|
||||||
|
|
||||||
|
name = fields.Char(required=True)
|
||||||
|
terminate_comment_required = fields.Boolean(
|
||||||
|
string="Require a termination comment", default=True
|
||||||
|
)
|
||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
<odoo>
|
<odoo>
|
||||||
|
|
||||||
<record model="ir.model.access" id="contract_resiliate_reason_access_manager">
|
<record model="ir.model.access" id="contract_terminate_reason_access_manager">
|
||||||
<field name="name">contract.resiliate.reason access manager</field>
|
<field name="name">contract.terminate.reason access manager</field>
|
||||||
<field name="model_id" ref="model_contract_resiliate_reason"/>
|
<field name="model_id" ref="model_contract_terminate_reason"/>
|
||||||
<field name="group_id" ref="account.group_account_manager"/>
|
<field name="group_id" ref="account.group_account_manager"/>
|
||||||
<field name="perm_read" eval="1"/>
|
<field name="perm_read" eval="1"/>
|
||||||
<field name="perm_create" eval="1"/>
|
<field name="perm_create" eval="1"/>
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
<field name="perm_unlink" eval="1"/>
|
<field name="perm_unlink" eval="1"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.model.access" id="contract_resiliate_reason_access_user">
|
<record model="ir.model.access" id="contract_terminate_reason_access_user">
|
||||||
<field name="name">contract.resiliate.reason access user</field>
|
<field name="name">contract.terminate.reason access user</field>
|
||||||
<field name="model_id" ref="model_contract_resiliate_reason"/>
|
<field name="model_id" ref="model_contract_terminate_reason"/>
|
||||||
<field name="group_id" ref="account.group_account_invoice"/>
|
<field name="group_id" ref="account.group_account_invoice"/>
|
||||||
<field name="perm_read" eval="1"/>
|
<field name="perm_read" eval="1"/>
|
||||||
<field name="perm_create" eval="1"/>
|
<field name="perm_create" eval="1"/>
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
<odoo>
|
<odoo>
|
||||||
|
|
||||||
<record id="can_resiliate_contract" model="res.groups">
|
<record id="can_terminate_contract" model="res.groups">
|
||||||
<field name="name">Contract: Can Resiliate Contracts</field>
|
<field name="name">Contract: Can Terminate Contracts</field>
|
||||||
<field name="implied_ids" eval="[(4, ref('account.group_account_invoice'))]"/>
|
<field name="implied_ids" eval="[(4, ref('account.group_account_invoice'))]"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -110,8 +110,8 @@ class TestContractBase(common.SavepointCase):
|
|||||||
)
|
)
|
||||||
cls.acct_line.product_id.is_auto_renew = True
|
cls.acct_line.product_id.is_auto_renew = True
|
||||||
cls.contract.company_id.create_new_line_at_contract_line_renew = True
|
cls.contract.company_id.create_new_line_at_contract_line_renew = True
|
||||||
cls.resiliate_reason = cls.env['contract.resiliate.reason'].create({
|
cls.terminate_reason = cls.env['contract.terminate.reason'].create({
|
||||||
'name': 'resiliate_reason'
|
'name': 'terminate_reason'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -2368,50 +2368,50 @@ class TestContract(TestContractBase):
|
|||||||
self.acct_line.recurring_next_date, to_date('2019-06-01')
|
self.acct_line.recurring_next_date, to_date('2019-06-01')
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_action_resiliate_contract(self):
|
def test_action_terminate_contract(self):
|
||||||
action = self.contract.action_resiliate_contract()
|
action = self.contract.action_terminate_contract()
|
||||||
wizard = (
|
wizard = (
|
||||||
self.env[action['res_model']]
|
self.env[action['res_model']]
|
||||||
.with_context(action['context'])
|
.with_context(action['context'])
|
||||||
.create(
|
.create(
|
||||||
{
|
{
|
||||||
'resiliate_date': '2018-03-01',
|
'terminate_date': '2018-03-01',
|
||||||
'resiliate_reason_id': self.resiliate_reason.id,
|
'terminate_reason_id': self.terminate_reason.id,
|
||||||
'resiliate_comment': 'resiliate_comment',
|
'terminate_comment': 'terminate_comment',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(wizard.contract_id, self.contract)
|
self.assertEqual(wizard.contract_id, self.contract)
|
||||||
with self.assertRaises(UserError):
|
with self.assertRaises(UserError):
|
||||||
wizard.resiliate_contract()
|
wizard.terminate_contract()
|
||||||
group_can_resiliate_contract = self.env.ref(
|
group_can_terminate_contract = self.env.ref(
|
||||||
"contract.can_resiliate_contract"
|
"contract.can_terminate_contract"
|
||||||
)
|
)
|
||||||
group_can_resiliate_contract.users |= self.env.user
|
group_can_terminate_contract.users |= self.env.user
|
||||||
wizard.resiliate_contract()
|
wizard.terminate_contract()
|
||||||
self.assertTrue(self.contract.is_resiliated)
|
self.assertTrue(self.contract.is_terminated)
|
||||||
self.assertEqual(self.contract.resiliate_date, to_date('2018-03-01'))
|
self.assertEqual(self.contract.terminate_date, to_date('2018-03-01'))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.contract.resiliate_reason_id.id, self.resiliate_reason.id
|
self.contract.terminate_reason_id.id, self.terminate_reason.id
|
||||||
)
|
)
|
||||||
self.assertEqual(self.contract.resiliate_comment, 'resiliate_comment')
|
self.assertEqual(self.contract.terminate_comment, 'terminate_comment')
|
||||||
self.contract.action_cancel_contract_resiliation()
|
self.contract.action_cancel_contract_termination()
|
||||||
self.assertFalse(self.contract.is_resiliated)
|
self.assertFalse(self.contract.is_terminated)
|
||||||
self.assertFalse(self.contract.resiliate_reason_id)
|
self.assertFalse(self.contract.terminate_reason_id)
|
||||||
self.assertFalse(self.contract.resiliate_comment)
|
self.assertFalse(self.contract.terminate_comment)
|
||||||
|
|
||||||
def test_resiliate_date_before_last_date_invoiced(self):
|
def test_terminate_date_before_last_date_invoiced(self):
|
||||||
self.contract.recurring_create_invoice()
|
self.contract.recurring_create_invoice()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.acct_line.last_date_invoiced, to_date('2018-02-14')
|
self.acct_line.last_date_invoiced, to_date('2018-02-14')
|
||||||
)
|
)
|
||||||
group_can_resiliate_contract = self.env.ref(
|
group_can_terminate_contract = self.env.ref(
|
||||||
"contract.can_resiliate_contract"
|
"contract.can_terminate_contract"
|
||||||
)
|
)
|
||||||
group_can_resiliate_contract.users |= self.env.user
|
group_can_terminate_contract.users |= self.env.user
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
self.contract._resiliate_contract(
|
self.contract._terminate_contract(
|
||||||
self.resiliate_reason,
|
self.terminate_reason,
|
||||||
'resiliate_comment',
|
'terminate_comment',
|
||||||
to_date('2018-02-13'),
|
to_date('2018-02-13'),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,38 +7,38 @@
|
|||||||
<field name="model">contract.contract</field>
|
<field name="model">contract.contract</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form>
|
<form>
|
||||||
<field name="is_resiliated" invisible="1"/>
|
<field name="is_terminated" invisible="1"/>
|
||||||
<div class="alert alert-danger" role="alert" style="margin-bottom:0px;" attrs="{'invisible': [('is_resiliated','=',False)]}">
|
<div class="alert alert-danger" role="alert" style="margin-bottom:0px;" attrs="{'invisible': [('is_terminated','=',False)]}">
|
||||||
<p>This contract was resiliated for the reason <strong><field name="resiliate_reason_id" options="{'no_open':True}"/></strong> on <field name="resiliate_date"/>.</p>
|
<p>This contract was terminated for the reason <strong><field name="terminate_reason_id" options="{'no_open':True}"/></strong> on <field name="terminate_date"/>.</p>
|
||||||
<p><field name="resiliate_comment"/></p>
|
<p><field name="terminate_comment"/></p>
|
||||||
</div>
|
</div>
|
||||||
<header>
|
<header>
|
||||||
<button name="action_contract_send"
|
<button name="action_contract_send"
|
||||||
type="object"
|
type="object"
|
||||||
string="Send by Email"
|
string="Send by Email"
|
||||||
attrs="{'invisible': [('is_resiliated','=',True)]}"
|
attrs="{'invisible': [('is_terminated','=',True)]}"
|
||||||
groups="base.group_user"/>
|
groups="base.group_user"/>
|
||||||
<button name="recurring_create_invoice"
|
<button name="recurring_create_invoice"
|
||||||
type="object"
|
type="object"
|
||||||
attrs="{'invisible': ['|', ('create_invoice_visibility', '=', False)]}"
|
attrs="{'invisible': ['|', ('create_invoice_visibility', '=', False)]}"
|
||||||
string="Create invoices"
|
string="Create invoices"
|
||||||
groups="base.group_no_one"/>
|
groups="base.group_no_one"/>
|
||||||
<button name="action_resiliate_contract"
|
<button name="action_terminate_contract"
|
||||||
type="object"
|
type="object"
|
||||||
string="Resiliate Contract"
|
string="Terminate Contract"
|
||||||
attrs="{'invisible': [('is_resiliated','=',True)]}"
|
attrs="{'invisible': [('is_terminated','=',True)]}"
|
||||||
groups="contract.can_resiliate_contract"/>
|
groups="contract.can_terminate_contract"/>
|
||||||
<button name="action_resiliate_contract"
|
<button name="action_terminate_contract"
|
||||||
type="object"
|
type="object"
|
||||||
string="Update Resiliation Details"
|
string="Update Termination Details"
|
||||||
attrs="{'invisible': [('is_resiliated','=',False)]}"
|
attrs="{'invisible': [('is_terminated','=',False)]}"
|
||||||
groups="contract.can_resiliate_contract"/>
|
groups="contract.can_terminate_contract"/>
|
||||||
<button name="action_cancel_contract_resiliation"
|
<button name="action_cancel_contract_termination"
|
||||||
type="object"
|
type="object"
|
||||||
confirm="Are you sure you want to re-activate this contract?"
|
confirm="Are you sure you want to re-activate this contract?"
|
||||||
string="Cancel Contract Resiliation"
|
string="Cancel Contract Termination"
|
||||||
attrs="{'invisible': [('is_resiliated','=',False)]}"
|
attrs="{'invisible': [('is_terminated','=',False)]}"
|
||||||
groups="contract.can_resiliate_contract"/>
|
groups="contract.can_terminate_contract"/>
|
||||||
</header>
|
</header>
|
||||||
<sheet string="Contract">
|
<sheet string="Contract">
|
||||||
<div class="oe_button_box" name="button_box">
|
<div class="oe_button_box" name="button_box">
|
||||||
@@ -60,43 +60,43 @@
|
|||||||
class="oe_edit_only"/>
|
class="oe_edit_only"/>
|
||||||
<h3>
|
<h3>
|
||||||
<field name="name" class="oe_inline"
|
<field name="name" class="oe_inline"
|
||||||
attrs="{'readonly': [('is_resiliated','=',True)]}"
|
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||||
placeholder="e.g. Contract XYZ"/>
|
placeholder="e.g. Contract XYZ"/>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<group name="main">
|
<group name="main">
|
||||||
<group>
|
<group>
|
||||||
<field name="commercial_partner_id" invisible="1"/>
|
<field name="commercial_partner_id" invisible="1"/>
|
||||||
<field name="partner_id" required="1" attrs="{'readonly': [('is_resiliated','=',True)]}"/>
|
<field name="partner_id" required="1" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||||
<field name="payment_term_id" attrs="{'readonly': [('is_resiliated','=',True)]}"/>
|
<field name="payment_term_id" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||||
<field name="user_id" attrs="{'readonly': [('is_resiliated','=',True)]}"/>
|
<field name="user_id" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="contract_template_id"
|
<field name="contract_template_id"
|
||||||
attrs="{'readonly': [('is_resiliated','=',True)]}"
|
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||||
domain="['|', ('contract_type', '=', contract_type), ('contract_type', '=', False)]"
|
domain="['|', ('contract_type', '=', contract_type), ('contract_type', '=', False)]"
|
||||||
context="{'default_contract_type': contract_type}"/>
|
context="{'default_contract_type': contract_type}"/>
|
||||||
<field name="contract_type" invisible="1"
|
<field name="contract_type" invisible="1"
|
||||||
required="1"/>
|
required="1"/>
|
||||||
<field name="fiscal_position_id" attrs="{'readonly': [('is_resiliated','=',True)]}"/>
|
<field name="fiscal_position_id" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||||
<field name="tag_ids" widget="many2many_tags"/>
|
<field name="tag_ids" widget="many2many_tags"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<group name="recurring_invoices">
|
<group name="recurring_invoices">
|
||||||
<group>
|
<group>
|
||||||
<field name="journal_id" required="1" attrs="{'readonly': [('is_resiliated','=',True)]}"/>
|
<field name="journal_id" required="1" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||||
<field name="recurring_next_date"/>
|
<field name="recurring_next_date"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="pricelist_id" attrs="{'readonly': [('is_resiliated','=',True)]}"/>
|
<field name="pricelist_id" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||||
<field name="date_end"/>
|
<field name="date_end"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page name="recurring_invoice_line"
|
<page name="recurring_invoice_line"
|
||||||
string="Recurring Invoices">
|
string="Recurring Invoices">
|
||||||
<field name="contract_line_ids" attrs="{'readonly': [('is_resiliated','=',True)]}"
|
<field name="contract_line_ids" attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||||
context="{'default_contract_type': contract_type}"/>
|
context="{'default_contract_type': contract_type}"/>
|
||||||
<field name="note"/>
|
<field name="note"/>
|
||||||
</page>
|
</page>
|
||||||
@@ -104,18 +104,18 @@
|
|||||||
<field name="create_invoice_visibility"
|
<field name="create_invoice_visibility"
|
||||||
invisible="1"/>
|
invisible="1"/>
|
||||||
<group>
|
<group>
|
||||||
<field name="code" attrs="{'readonly': [('is_resiliated','=',True)]}"/>
|
<field name="code" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||||
<field name="group_id" attrs="{'readonly': [('is_resiliated','=',True)]}"/>
|
<field name="group_id" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||||
<field name="company_id"
|
<field name="company_id"
|
||||||
attrs="{'readonly': [('is_resiliated','=',True)]}"
|
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||||
options="{'no_create': True}"
|
options="{'no_create': True}"
|
||||||
groups="base.group_multi_company"/>
|
groups="base.group_multi_company"/>
|
||||||
<field name="currency_id"
|
<field name="currency_id"
|
||||||
attrs="{'readonly': [('is_resiliated','=',True)]}"
|
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||||
options="{'no_create': True}"
|
options="{'no_create': True}"
|
||||||
groups="base.group_multi_currency"/>
|
groups="base.group_multi_currency"/>
|
||||||
<field name="invoice_partner_id"
|
<field name="invoice_partner_id"
|
||||||
attrs="{'readonly': [('is_resiliated','=',True)]}"
|
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||||
required="1"/>
|
required="1"/>
|
||||||
</group>
|
</group>
|
||||||
<group string="Legend (for the markers inside invoice lines description)"
|
<group string="Legend (for the markers inside invoice lines description)"
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
<odoo>
|
<odoo>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="contract_resiliate_reason_form_view">
|
<record model="ir.ui.view" id="contract_terminate_reason_form_view">
|
||||||
<field name="model">contract.resiliate.reason</field>
|
<field name="model">contract.terminate.reason</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form>
|
<form>
|
||||||
<sheet>
|
<sheet>
|
||||||
<group>
|
<group>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="resiliate_comment_required"/>
|
<field name="terminate_comment_required"/>
|
||||||
</group>
|
</group>
|
||||||
</sheet>
|
</sheet>
|
||||||
</form>
|
</form>
|
||||||
@@ -19,26 +19,26 @@
|
|||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
<record model="ir.ui.view" id="contract_resiliate_reason_tree_view">
|
<record model="ir.ui.view" id="contract_terminate_reason_tree_view">
|
||||||
<field name="model">contract.resiliate.reason</field>
|
<field name="model">contract.terminate.reason</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree>
|
<tree>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="resiliate_comment_required"/>
|
<field name="terminate_comment_required"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.actions.act_window" id="contract_resiliate_reason_act_window">
|
<record model="ir.actions.act_window" id="contract_terminate_reason_act_window">
|
||||||
<field name="name">Contract Resiliation Reason</field>
|
<field name="name">Contract Termination Reason</field>
|
||||||
<field name="res_model">contract.resiliate.reason</field>
|
<field name="res_model">contract.terminate.reason</field>
|
||||||
<field name="view_mode">tree,form</field>
|
<field name="view_mode">tree,form</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.ui.menu" id="contract_resiliate_reason_menu">
|
<record model="ir.ui.menu" id="contract_terminate_reason_menu">
|
||||||
<field name="name">Contract Resiliation Reason</field>
|
<field name="name">Contract Termination Reason</field>
|
||||||
<field name="parent_id" ref="menu_config_contract"/>
|
<field name="parent_id" ref="menu_config_contract"/>
|
||||||
<field name="action" ref="contract_resiliate_reason_act_window"/>
|
<field name="action" ref="contract_terminate_reason_act_window"/>
|
||||||
<field name="sequence" eval="16"/>
|
<field name="sequence" eval="16"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
from . import contract_line_wizard
|
from . import contract_line_wizard
|
||||||
from . import contract_manually_create_invoice
|
from . import contract_manually_create_invoice
|
||||||
from . import contract_contract_resiliate
|
from . import contract_contract_terminate
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
# Copyright 2020 ACSONE SA/NV
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
|
|
||||||
from odoo import api, fields, models
|
|
||||||
|
|
||||||
|
|
||||||
class ContractContractResiliate(models.TransientModel):
|
|
||||||
|
|
||||||
_name = 'contract.contract.resiliate'
|
|
||||||
_description = "Resiliate Contract Wizard"
|
|
||||||
|
|
||||||
contract_id = fields.Many2one(
|
|
||||||
comodel_name="contract.contract",
|
|
||||||
string="Contract",
|
|
||||||
required=True,
|
|
||||||
ondelete="cascade",
|
|
||||||
)
|
|
||||||
resiliate_reason_id = fields.Many2one(
|
|
||||||
comodel_name="contract.resiliate.reason",
|
|
||||||
string="Resiliate Reason",
|
|
||||||
required=True,
|
|
||||||
ondelete="cascade",
|
|
||||||
)
|
|
||||||
resiliate_comment = fields.Text(string="Resiliate Comment")
|
|
||||||
resiliate_date = fields.Date(string="Resiliate Date", required=True)
|
|
||||||
resiliate_comment_required = fields.Boolean(
|
|
||||||
related="resiliate_reason_id.resiliate_comment_required"
|
|
||||||
)
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def resiliate_contract(self):
|
|
||||||
for wizard in self:
|
|
||||||
wizard.contract_id._resiliate_contract(
|
|
||||||
wizard.resiliate_reason_id,
|
|
||||||
wizard.resiliate_comment,
|
|
||||||
wizard.resiliate_date,
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
38
contract/wizards/contract_contract_terminate.py
Normal file
38
contract/wizards/contract_contract_terminate.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Copyright 2020 ACSONE SA/NV
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class ContractContractTerminate(models.TransientModel):
|
||||||
|
|
||||||
|
_name = 'contract.contract.terminate'
|
||||||
|
_description = "Terminate Contract Wizard"
|
||||||
|
|
||||||
|
contract_id = fields.Many2one(
|
||||||
|
comodel_name="contract.contract",
|
||||||
|
string="Contract",
|
||||||
|
required=True,
|
||||||
|
ondelete="cascade",
|
||||||
|
)
|
||||||
|
terminate_reason_id = fields.Many2one(
|
||||||
|
comodel_name="contract.terminate.reason",
|
||||||
|
string="Termination Reason",
|
||||||
|
required=True,
|
||||||
|
ondelete="cascade",
|
||||||
|
)
|
||||||
|
terminate_comment = fields.Text(string="Termination Comment")
|
||||||
|
terminate_date = fields.Date(string="Termination Date", required=True)
|
||||||
|
terminate_comment_required = fields.Boolean(
|
||||||
|
related="terminate_reason_id.terminate_comment_required"
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def terminate_contract(self):
|
||||||
|
for wizard in self:
|
||||||
|
wizard.contract_id._terminate_contract(
|
||||||
|
wizard.terminate_reason_id,
|
||||||
|
wizard.terminate_comment,
|
||||||
|
wizard.terminate_date,
|
||||||
|
)
|
||||||
|
return True
|
||||||
@@ -4,22 +4,22 @@
|
|||||||
|
|
||||||
<odoo>
|
<odoo>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="contract_contract_resiliate_form_view">
|
<record model="ir.ui.view" id="contract_contract_terminate_form_view">
|
||||||
<field name="model">contract.contract.resiliate</field>
|
<field name="model">contract.contract.terminate</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Contract Contract Resiliate">
|
<form string="Contract Contract Terminate">
|
||||||
<group>
|
<group>
|
||||||
<field name="contract_id" invisible="True"/>
|
<field name="contract_id" invisible="True"/>
|
||||||
<field name="resiliate_comment_required" invisible="True"/>
|
<field name="terminate_comment_required" invisible="True"/>
|
||||||
<field name="resiliate_date"/>
|
<field name="terminate_date"/>
|
||||||
<field name="resiliate_reason_id" widget="selection"/>
|
<field name="terminate_reason_id" widget="selection"/>
|
||||||
<field name="resiliate_comment" attrs="{'required': [('resiliate_comment_required', '=', True)]}"/>
|
<field name="terminate_comment" attrs="{'required': [('terminate_comment_required', '=', True)]}"/>
|
||||||
</group>
|
</group>
|
||||||
<footer>
|
<footer>
|
||||||
<button name="resiliate_contract"
|
<button name="terminate_contract"
|
||||||
string="Resiliate Contract"
|
string="Terminate Contract"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
confirm="Are you sure you want to resiliate this contract?"
|
confirm="Are you sure you want to terminate this contract?"
|
||||||
type="object"/>
|
type="object"/>
|
||||||
<button string="Cancel"
|
<button string="Cancel"
|
||||||
class="btn-default"
|
class="btn-default"
|
||||||
@@ -18,15 +18,15 @@ class SaleOrder(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@api.constrains('state')
|
@api.constrains('state')
|
||||||
def check_contact_is_not_resiliated(self):
|
def check_contact_is_not_terminated(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
if rec.state not in (
|
if rec.state not in (
|
||||||
'sale',
|
'sale',
|
||||||
'done',
|
'done',
|
||||||
'cancel',
|
'cancel',
|
||||||
) and rec.order_line.filtered('contract_id.is_resiliated'):
|
) and rec.order_line.filtered('contract_id.is_terminated'):
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_("You can't upsell or downsell a resiliated contract")
|
_("You can't upsell or downsell a terminated contract")
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.depends('order_line.contract_id', 'state')
|
@api.depends('order_line.contract_id', 'state')
|
||||||
|
|||||||
@@ -51,14 +51,14 @@ class SaleOrderLine(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@api.constrains('contract_id')
|
@api.constrains('contract_id')
|
||||||
def check_contact_is_not_resiliated(self):
|
def check_contact_is_not_terminated(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
if (
|
if (
|
||||||
rec.order_id.state not in ('sale', 'done', 'cancel')
|
rec.order_id.state not in ('sale', 'done', 'cancel')
|
||||||
and rec.contract_id.is_resiliated
|
and rec.contract_id.is_terminated
|
||||||
):
|
):
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_("You can't upsell or downsell a resiliated contract")
|
_("You can't upsell or downsell a terminated contract")
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
|
|||||||
@@ -343,17 +343,17 @@ class TestSaleOrder(TransactionCase):
|
|||||||
self.sale.order_line.mapped('contract_id'),
|
self.sale.order_line.mapped('contract_id'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_check_contact_is_not_resiliated(self):
|
def test_check_contact_is_not_terminated(self):
|
||||||
self.contract.is_resiliated = True
|
self.contract.is_terminated = True
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
self.order_line1.contract_id = self.contract
|
self.order_line1.contract_id = self.contract
|
||||||
|
|
||||||
def test_check_contact_is_not_resiliated(self):
|
def test_check_contact_is_not_terminated(self):
|
||||||
self.order_line1.contract_id = self.contract
|
self.order_line1.contract_id = self.contract
|
||||||
self.sale.action_confirm()
|
self.sale.action_confirm()
|
||||||
self.contract.is_resiliated = True
|
self.contract.is_terminated = True
|
||||||
self.sale.action_cancel()
|
self.sale.action_cancel()
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
self.sale.action_draft()
|
self.sale.action_draft()
|
||||||
self.contract.is_resiliated = False
|
self.contract.is_terminated = False
|
||||||
self.sale.action_draft()
|
self.sale.action_draft()
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
domain="['|',('contract_template_id','=',contract_template_id),
|
domain="['|',('contract_template_id','=',contract_template_id),
|
||||||
('contract_template_id','=',False),
|
('contract_template_id','=',False),
|
||||||
('partner_id','=',parent.partner_id),
|
('partner_id','=',parent.partner_id),
|
||||||
('is_resiliated','=',False),
|
('is_terminated','=',False),
|
||||||
]"/>
|
]"/>
|
||||||
<field name="contract_line_id"
|
<field name="contract_line_id"
|
||||||
attrs="{'invisible': [('is_contract', '=', False)]}"
|
attrs="{'invisible': [('is_contract', '=', False)]}"
|
||||||
|
|||||||
Reference in New Issue
Block a user