[MIG] contract: Migration to 17.0

This commit is contained in:
Christopher Rogos
2024-03-27 17:12:44 +00:00
parent fcaddfcb46
commit d1cb9312ae
22 changed files with 268 additions and 350 deletions

View File

@@ -11,7 +11,7 @@
{
"name": "Recurring - Contracts Management",
"version": "16.0.2.7.0",
"version": "17.0.1.0.0",
"category": "Contract Management",
"license": "AGPL-3",
"author": "Tecnativa, ACSONE SA/NV, Odoo Community Association (OCA)",
@@ -47,11 +47,8 @@
"views/contract_portal_templates.xml",
],
"assets": {
"web.assets_backend": [
"contract/static/src/js/section_and_note_fields_backend.js",
],
"web.assets_frontend": ["contract/static/src/scss/frontend.scss"],
"web.assets_tests": ["contract/static/src/js/contract_portal_tour.js"],
"web.assets_tests": ["contract/static/src/js/contract_portal_tour.esm.js"],
},
"installable": True,
}

View File

@@ -11,8 +11,10 @@
<field name="partner_to">{{ object.partner_id.id }}</field>
<field name="model_id" ref="model_contract_contract" />
<field name="auto_delete" eval="True" />
<field name="report_template" ref="contract.report_contract" />
<field name="report_name">Contract</field>
<field
name="report_template_ids"
eval="[(4, ref('contract.report_contract'))]"
/>
<field name="lang">{{ object.partner_id.lang }}</field>
<field name="body_html" type="html">
<div

View File

@@ -1,33 +0,0 @@
# © 2023 initOS GmbH
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import json
import logging
_logger = logging.getLogger(__name__)
def migrate(cr, version):
"""Migrate analytic account from contract line to analytic distribution"""
_logger.info("Migrating analytic distribution for contract.line")
cr.execute(
"""
SELECT id, analytic_account_id, analytic_distribution
FROM contract_line
WHERE analytic_account_id IS NOT NULL
"""
)
for line_id, analytic_account_id, analytic_distribution in cr.fetchall():
analytic_account_id = str(analytic_account_id)
if analytic_distribution:
analytic_distribution[analytic_account_id] = (
analytic_distribution.get(analytic_account_id, 0) + 100
)
else:
analytic_distribution = {analytic_account_id: 100}
cr.execute(
"UPDATE contract_line SET analytic_distribution = %s WHERE id = %s",
(json.dumps(analytic_distribution), line_id),
)

View File

@@ -38,8 +38,8 @@ class ContractAbstractContractLine(models.AbstractModel):
# Just to have a currency_id here - will get overwriten in contract.line
# model with the related currency from the contract
currency_id = fields.Many2one("res.currency")
specific_price = fields.Monetary()
price_unit = fields.Monetary(
specific_price = fields.Float()
price_unit = fields.Float(
string="Unit Price",
compute="_compute_price_unit",
inverse="_inverse_price_unit",

View File

@@ -156,7 +156,7 @@ class ContractContract(models.Model):
).write(vals)
self._modification_mail_send()
else:
res = super(ContractContract, self).write(vals)
res = super().write(vals)
return res
@api.model
@@ -186,13 +186,15 @@ class ContractContract(models.Model):
)
if modification_ids_not_sent:
if not self.env.context.get("skip_modification_mail"):
record.with_context(
default_subtype_id=self.env.ref(
"contract.mail_message_subtype_contract_modification"
).id,
).message_post_with_template(
self.env.ref("contract.mail_template_contract_modification").id,
email_layout_xmlid="contract.template_contract_modification",
subtype_id = self.env["ir.model.data"]._xmlid_to_res_id(
"contract.mail_message_subtype_contract_modification"
)
template_id = self.env.ref(
"contract.mail_template_contract_modification"
)
record.message_post_with_source(
template_id,
subtype_id=subtype_id,
)
modification_ids_not_sent.write({"sent": True})
@@ -318,10 +320,10 @@ class ContractContract(models.Model):
def _compute_recurring_next_date(self):
for contract in self:
recurring_next_date = contract.contract_line_ids.filtered(
lambda l: (
l.recurring_next_date
and not l.is_canceled
and (not l.display_type or l.is_recurring_note)
lambda line: (
line.recurring_next_date
and not line.is_canceled
and (not line.display_type or line.is_recurring_note)
)
).mapped("recurring_next_date")
# we give priority to computation from date_start if modified
@@ -622,7 +624,8 @@ class ContractContract(models.Model):
body=(
_(
(
"%(msg)s by contract <a href=# data-oe-model=contract.contract"
"%(msg)s by contract <a href=#"
" data-oe-model=contract.contract"
" data-oe-id=%(contract_id)d>%(contract)s</a>."
),
msg=move._creation_message(),
@@ -672,8 +675,11 @@ class ContractContract(models.Model):
# Invoice by companies, so assignation emails get correct context
for company in companies:
contracts_to_invoice = contracts.filtered(
lambda c: c.company_id == company
and (not c.date_end or c.recurring_next_date <= c.date_end)
lambda contract, comp=company: contract.company_id == comp
and (
not contract.date_end
or contract.recurring_next_date <= contract.date_end
)
).with_company(company)
_recurring_create_func(contracts_to_invoice, date_ref)
return True

View File

@@ -876,14 +876,11 @@ class ContractLine(models.Model):
if not all(self.mapped("is_cancel_allowed")):
raise ValidationError(_("Cancel not allowed for this line"))
for contract in self.mapped("contract_id"):
lines = self.filtered(lambda l, c=contract: l.contract_id == c)
lines = self.filtered(lambda line, c=contract: line.contract_id == c)
msg = _(
"Contract line canceled: %s",
"<br/>- ".join(
[
"<strong>%(product)s</strong>" % {"product": name}
for name in lines.mapped("name")
]
[f"<strong>{name}</strong>" for name in lines.mapped("name")]
),
)
contract.message_post(body=msg)
@@ -896,14 +893,11 @@ class ContractLine(models.Model):
if not all(self.mapped("is_un_cancel_allowed")):
raise ValidationError(_("Un-cancel not allowed for this line"))
for contract in self.mapped("contract_id"):
lines = self.filtered(lambda l, c=contract: l.contract_id == c)
lines = self.filtered(lambda line, c=contract: line.contract_id == c)
msg = _(
"Contract line Un-canceled: %s",
"<br/>- ".join(
[
"<strong>%(product)s</strong>" % {"product": name}
for name in lines.mapped("name")
]
[f"<strong>{name}</strong>" for name in lines.mapped("name")]
),
)
contract.message_post(body=msg)

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

View File

@@ -0,0 +1,18 @@
/** @odoo-module **/
import {registry} from "@web/core/registry";
registry.category("web_tour.tours").add("contract_portal_tour", {
test: true,
url: "/my",
steps: () => [
{
content: "Go /my/contracts url",
trigger: 'a[href*="/my/contracts"]',
},
{
content: "Go to Contract item",
trigger: ".tr_contract_link:eq(0)",
},
],
});

View File

@@ -1,23 +0,0 @@
odoo.define("contract.tour", function (require) {
"use strict";
var tour = require("web_tour.tour");
tour.register(
"contract_portal_tour",
{
test: true,
url: "/my",
},
[
{
content: "Go /my/contracts url",
trigger: 'a[href*="/my/contracts"]',
},
{
content: "Go to Contract item",
trigger: ".tr_contract_link:eq(0)",
},
]
);
});

View File

@@ -1,39 +0,0 @@
/* Copyright 2020 Tecnativa - Ernesto Tejeda
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
*/
/*
If in the sub-tree view where the sections and notes are to be used
there are fields that have defined in the XML attrs = {'invisible': ....}
and this condition is met, then an extra space appears in the rows
corresponding to the sections and lines.
This js was written to deal with that problem, but a solution based on
this can be applied directly to Odoo*/
odoo.define("contract.section_and_note_backend", function (require) {
"use strict";
require("account.section_and_note_backend");
var fieldRegistry = require("web.field_registry");
var section_and_note_one2many = fieldRegistry.get("section_and_note_one2many");
section_and_note_one2many.include({
_getRenderer: function () {
var result = this._super.apply(this, arguments);
if (this.view.arch.tag === "tree") {
result.include({
_renderBodyCell: function (record) {
var $cell = this._super.apply(this, arguments);
var isSection = record.data.display_type === "line_section";
var isNote = record.data.display_type === "line_note";
if (isSection || isNote) {
$cell.removeClass("o_invisible_modifier");
}
return $cell;
},
});
}
return result;
},
});
});

View File

@@ -857,25 +857,15 @@ class TestContract(TestContractBase):
max_date_end,
):
return (
"Error in case %s:"
"date_start: %s, "
"date_end: %s, "
"last_date_invoiced: %s, "
"recurring_next_date: %s, "
"recurring_invoicing_type: %s, "
"recurring_rule_type: %s, "
"recurring_interval: %s, "
"max_date_end: %s, "
) % (
case,
date_start,
date_end,
last_date_invoiced,
recurring_next_date,
recurring_invoicing_type,
recurring_rule_type,
recurring_interval,
max_date_end,
f"Error in case {case}:"
f"date_start: {date_start}, "
f"date_end: {date_end}, "
f"last_date_invoiced: {last_date_invoiced}, "
f"recurring_next_date: {recurring_next_date}, "
f"recurring_invoicing_type: {recurring_invoicing_type}, "
f"recurring_rule_type: {recurring_rule_type}, "
f"recurring_interval: {recurring_interval}, "
f"max_date_end: {max_date_end}, "
)
Result = namedtuple(

View File

@@ -8,12 +8,16 @@ class ContractMulticompanyCase(TestContractBase):
@classmethod
def setUpClass(cls):
super().setUpClass()
chart_template = cls.env.ref("l10n_generic_coa.configurable_chart_template")
cls.company_obj = cls.env["res.company"]
cls.company_1 = cls.env.ref("base.main_company")
vals = {"name": "Company 2"}
cls.company_2 = cls.company_obj.create(vals)
chart_template.try_loading(company=cls.company_2)
chart_template = cls.env["account.chart.template"]._guess_chart_template(
cls.company_2.country_id
)
cls.env["account.chart.template"].try_loading(
chart_template, company=cls.company_2, install_demo=False
)
cls.env.user.company_ids |= cls.company_2
cls.contract_mc = (

View File

@@ -1,12 +1,12 @@
# Copyright 2020 Tecnativa - Víctor Martínez
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl)
import odoo.tests
from odoo import http
from odoo.tests import HttpCase, tagged
@odoo.tests.tagged("post_install", "-at_install")
class TestContractPortal(odoo.tests.HttpCase):
@tagged("post_install", "-at_install")
class TestContractPortal(HttpCase):
def test_tour(self):
partner = self.env["res.partner"].create({"name": "partner test contract"})
contract = self.env["contract.contract"].create(
@@ -14,12 +14,7 @@ class TestContractPortal(odoo.tests.HttpCase):
)
user_portal = self.env.ref("base.demo_user0")
contract.message_subscribe(partner_ids=user_portal.partner_id.ids)
self.browser_js(
"/",
"odoo.__DEBUG__.services['web_tour.tour'].run('contract_portal_tour')",
"odoo.__DEBUG__.services['web_tour.tour'].tours.contract_portal_tour.ready",
login="portal",
)
self.start_tour("/", "contract_portal_tour", login="portal")
# Contract access
self.authenticate("portal", "portal")
http.root.session_store.save(self.session)

View File

@@ -9,7 +9,7 @@
<field name="arch" type="xml">
<form>
<field name="display_type" invisible="1" />
<header attrs="{'invisible': [('display_type', '!=', False)]}" />
<header invisible="display_type" />
<sheet>
<field name="specific_price" invisible="1" />
<field name="currency_id" invisible="1" />
@@ -17,23 +17,23 @@
<group>
<field
name="product_id"
attrs="{'required': [('display_type', '=', 'product')],'invisible': [('display_type', '!=', False)]}"
required="display_type == 'product'"
invisible="display_type"
/>
</group>
<group attrs="{'invisible': [('display_type', '!=', False)]}">
<group invisible="display_type">
<group>
<field name="automatic_price" />
<field
name="price_unit"
attrs="{'readonly': [('automatic_price', '=', True)]}"
/>
<field name="price_unit" readonly="automatic_price" />
<field name="quantity" />
</group>
<group>
<field
name="uom_id"
groups="uom.group_uom"
attrs="{'required': [('display_type', '=', False)]}"
required="not display_type"
/>
<field
name="discount"
@@ -42,45 +42,41 @@
<field name="price_subtotal" readonly="1" />
</group>
</group>
<label
for="name"
string="Description"
attrs="{'invisible': [('display_type', '!=', False)]}"
/>
<label for="name" string="Description" invisible="display_type" />
<label
for="name"
string="Section"
attrs="{'invisible': [('display_type', '!=', 'line_section')]}"
invisible="display_type != 'line_section'"
/>
<label
for="name"
string="Note"
attrs="{'invisible': [('display_type', '!=', 'line_note')]}"
invisible="display_type != 'line_note'"
/>
<field name="name" nolabel="1" />
<group
name="note_invoicing_mode"
attrs="{'invisible': [('display_type', '!=', 'line_note')]}"
invisible="display_type != 'line_note'"
>
<field name="note_invoicing_mode" widget="radio" />
</group>
<group attrs="{'invisible': [('display_type', '!=', False)]}">
<group invisible="display_type">
<field name="is_auto_renew" />
<field name="is_canceled" invisible="1" />
</group>
<group
attrs="{'invisible':['|', ('is_auto_renew', '=', False), ('display_type', '!=', False)]}"
>
<group invisible="not is_auto_renew or display_type">
<group>
<label for="auto_renew_interval" />
<div class="o_row">
<field
name="auto_renew_interval"
attrs="{'required':[('is_auto_renew', '=', True)]}"
class="oe_inline"
required="is_auto_renew"
/>
<field
name="auto_renew_rule_type"
attrs="{'required':[('is_auto_renew', '=', True)]}"
class="oe_inline"
required="is_auto_renew"
/>
</div>
</group>
@@ -90,19 +86,19 @@
<field
name="termination_notice_interval"
class="oe_inline"
attrs="{'required':[('is_auto_renew', '=', True)]}"
required="is_auto_renew"
/>
<field
name="termination_notice_rule_type"
class="oe_inline"
attrs="{'required':[('is_auto_renew', '=', True)]}"
required="is_auto_renew"
/>
</div>
</group>
</group>
<group
name="recurrence_info"
attrs="{'invisible': ['|', ('display_type', '=', 'line_section'), '&amp;', ('display_type', '=', 'line_note'), ('note_invoicing_mode', '!=', 'custom')]}"
invisible="display_type == 'line_section' or (display_type == 'line_note' and note_invoicing_mode != 'custom')"
>
<group>
<label for="recurring_interval" />

View File

@@ -7,11 +7,12 @@
<field name="arch" type="xml">
<form>
<field name="is_terminated" invisible="1" />
<field name="company_id" invisible="1" />
<div
class="alert alert-danger"
role="alert"
style="margin-bottom:0px;"
attrs="{'invisible': [('is_terminated','=',False)]}"
invisible="not is_terminated"
>
<p>
This contract was terminated for the reason
@@ -34,13 +35,13 @@
name="action_contract_send"
type="object"
string="Send by Email"
attrs="{'invisible': [('is_terminated','=',True)]}"
invisible="is_terminated"
groups="base.group_user"
/>
<button
name="recurring_create_invoice"
type="object"
attrs="{'invisible': ['|', ('create_invoice_visibility', '=', False),('generation_type','!=','invoice')]}"
invisible="not create_invoice_visibility and generation_type != 'invoice'"
string="Create invoices"
groups="base.group_no_one"
/>
@@ -48,14 +49,14 @@
name="action_terminate_contract"
type="object"
string="Terminate Contract"
attrs="{'invisible': [('is_terminated','=',True)]}"
invisible="is_terminated"
groups="contract.can_terminate_contract"
/>
<button
name="action_terminate_contract"
type="object"
string="Update Termination Details"
attrs="{'invisible': [('is_terminated','=',False)]}"
invisible="not is_terminated"
groups="contract.can_terminate_contract"
/>
<button
@@ -63,7 +64,7 @@
type="object"
confirm="Are you sure you want to re-activate this contract?"
string="Cancel Contract Termination"
attrs="{'invisible': [('is_terminated','=',False)]}"
invisible="not is_terminated"
groups="contract.can_terminate_contract"
/>
<button type="object" string="Preview" name="action_preview" />
@@ -76,7 +77,7 @@
type="object"
icon="fa-list"
class="oe_stat_button"
attrs="{'invisible': [('generation_type','!=','invoice')]}"
invisible="generation_type != 'invoice'"
>
<field
string="Invoices"
@@ -89,7 +90,7 @@
name="web_ribbon"
title="Archived"
bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
invisible="active"
/>
<div class="oe_title">
<label for="name" string="Contract Name" class="oe_edit_only" />
@@ -97,7 +98,7 @@
<field
name="name"
class="oe_inline"
attrs="{'readonly': [('is_terminated','=',True)]}"
readonly="is_terminated"
placeholder="e.g. Contract XYZ"
/>
</h3>
@@ -108,37 +109,25 @@
<field
name="partner_id"
required="1"
attrs="{'readonly': [('is_terminated','=',True)]}"
/>
<field
name="pricelist_id"
attrs="{'readonly': [('is_terminated','=',True)]}"
/>
<field
name="payment_term_id"
attrs="{'readonly': [('is_terminated','=',True)]}"
/>
<field
name="user_id"
attrs="{'readonly': [('is_terminated','=',True)]}"
readonly="is_terminated"
/>
<field name="pricelist_id" readonly="is_terminated" />
<field name="payment_term_id" readonly="is_terminated" />
<field name="user_id" readonly="is_terminated" />
</group>
<group>
<field
name="contract_template_id"
attrs="{'readonly': [('is_terminated','=',True)]}"
readonly="is_terminated"
domain="['|', ('contract_type', '=', contract_type), ('contract_type', '=', False)]"
context="{'default_contract_type': contract_type}"
/>
<field name="contract_type" invisible="1" required="1" />
<field
name="fiscal_position_id"
attrs="{'readonly': [('is_terminated','=',True)]}"
/>
<field name="fiscal_position_id" readonly="is_terminated" />
<field
name="journal_id"
required="1"
attrs="{'readonly': [('is_terminated','=',True)]}"
readonly="is_terminated"
/>
<field
name="tag_ids"
@@ -148,38 +137,36 @@
</group>
</group>
<group name="recurring_invoices">
<field
name="line_recurrence"
class="oe_inline"
attrs="{'readonly': [('line_recurrence', '=', True), ('invoice_count', '!=', 0)]}"
/>
<label for="line_recurrence" />
<group attrs="{'invisible': [('line_recurrence', '=', True)]}">
<group>
<field
name="line_recurrence"
class="oe_inline"
readonly="line_recurrence and invoice_count != 0"
/>
</group>
<group invisible="line_recurrence">
<label for="recurring_interval" />
<div class="o_row">
<field
name="recurring_interval"
attrs="{'required': [('line_recurrence', '=', False)]}"
required="not line_recurrence"
class="oe_inline"
nolabel="1"
/>
<field
name="recurring_rule_type"
attrs="{'required': [('line_recurrence', '=', False)]}"
required="not line_recurrence"
class="oe_inline"
nolabel="1"
/>
</div>
<field
name="recurring_invoicing_type"
attrs="{'required': [('line_recurrence', '=', False)]}"
required="not line_recurrence"
/>
</group>
<group attrs="{'invisible': [('line_recurrence', '=', True)]}">
<field
name="date_start"
attrs="{'required': [('line_recurrence', '=', False)]}"
/>
<group invisible="line_recurrence">
<field name="date_start" required="not line_recurrence" />
<field name="date_end" />
<field name="recurring_next_date" />
</group>
@@ -191,7 +178,8 @@
<page name="recurring_invoice_line" string="Recurring Invoices">
<field
name="contract_line_fixed_ids"
attrs="{'readonly': [('is_terminated','=',True)], 'invisible': [('line_recurrence', '=', True)]}"
readonly="is_terminated"
invisible="line_recurrence"
widget="section_and_note_one2many"
context="{'default_contract_type': contract_type, 'default_recurring_rule_type': recurring_rule_type, 'default_recurring_invoicing_type': recurring_invoicing_type, 'default_recurring_interval': recurring_interval, 'default_date_start': date_start, 'default_recurring_next_date': recurring_next_date}"
>
@@ -211,13 +199,16 @@
context="{'default_display_type': 'line_note'}"
/>
</control>
<field name="currency_id" invisible="1" />
<field name="display_type" invisible="1" />
<field name="currency_id" column_invisible="True" />
<field
name="display_type"
column_invisible="True"
/>
<field name="sequence" widget="handle" />
<field name="product_id" />
<field
name="product_uom_category_id"
invisible="1"
column_invisible="True"
/>
<field name="name" widget="section_and_note_text" />
<field
@@ -229,26 +220,38 @@
<field name="uom_id" />
<field
name="automatic_price"
attrs="{'column_invisible': [('parent.contract_type', '=', 'purchase')]}"
column_invisible="parent.contract_type == 'purchase'"
/>
<field
name="price_unit"
attrs="{'readonly': [('automatic_price', '=', True)]}"
readonly="automatic_price"
/>
<field
name="specific_price"
column_invisible="True"
/>
<field name="specific_price" invisible="1" />
<field
name="discount"
groups="product.group_discount_per_so_line"
/>
<field name="price_subtotal" />
<field name="recurring_interval" invisible="1" />
<field name="recurring_rule_type" invisible="1" />
<field
name="recurring_interval"
column_invisible="True"
/>
<field
name="recurring_rule_type"
column_invisible="True"
/>
<field
name="recurring_invoicing_type"
invisible="1"
column_invisible="True"
/>
<field name="recurring_next_date" invisible="1" />
<field name="date_start" invisible="1" />
<field
name="recurring_next_date"
column_invisible="True"
/>
<field name="date_start" column_invisible="True" />
<field name="date_end" />
<field
name="last_date_invoiced"
@@ -256,21 +259,31 @@
/>
<field
name="create_invoice_visibility"
invisible="1"
column_invisible="True"
/>
<field
name="is_plan_successor_allowed"
invisible="1"
column_invisible="True"
/>
<field name="is_stop_allowed" invisible="1" />
<field name="is_cancel_allowed" invisible="1" />
<field name="is_un_cancel_allowed" invisible="1" />
<field name="is_canceled" invisible="1" />
<field
name="is_stop_allowed"
column_invisible="True"
/>
<field
name="is_cancel_allowed"
column_invisible="True"
/>
<field
name="is_un_cancel_allowed"
column_invisible="True"
/>
<field name="is_canceled" column_invisible="True" />
</tree>
</field>
<field
name="contract_line_ids"
attrs="{'readonly': [('is_terminated','=',True)], 'invisible': [('line_recurrence', '=', False)]}"
readonly="is_terminated"
invisible="not line_recurrence"
widget="section_and_note_one2many"
context="{'default_contract_type': contract_type}"
>
@@ -289,8 +302,11 @@
context="{'default_display_type': 'line_note'}"
/>
</control>
<field name="currency_id" invisible="1" />
<field name="display_type" invisible="1" />
<field name="currency_id" column_invisible="True" />
<field
name="display_type"
column_invisible="True"
/>
<field name="sequence" widget="handle" />
<field name="product_id" />
<field name="name" widget="section_and_note_text" />
@@ -303,23 +319,32 @@
<field name="uom_id" />
<field
name="automatic_price"
attrs="{'column_invisible': [('parent.contract_type', '=', 'purchase')]}"
column_invisible="parent.contract_type == 'purchase'"
/>
<field
name="price_unit"
attrs="{'readonly': [('automatic_price', '=', True)]}"
readonly="automatic_price"
/>
<field
name="specific_price"
column_invisible="True"
/>
<field name="specific_price" invisible="1" />
<field
name="discount"
groups="product.group_discount_per_so_line"
/>
<field name="price_subtotal" />
<field name="recurring_interval" invisible="1" />
<field name="recurring_rule_type" invisible="1" />
<field
name="recurring_interval"
column_invisible="True"
/>
<field
name="recurring_rule_type"
column_invisible="True"
/>
<field
name="recurring_invoicing_type"
invisible="1"
column_invisible="True"
/>
<field name="date_start" required="1" />
<field name="date_end" />
@@ -330,41 +355,53 @@
/>
<field
name="create_invoice_visibility"
invisible="1"
column_invisible="True"
/>
<field
name="is_plan_successor_allowed"
invisible="1"
column_invisible="True"
/>
<field
name="is_stop_plan_successor_allowed"
invisible="1"
column_invisible="True"
/>
<field name="is_stop_allowed" invisible="1" />
<field name="is_cancel_allowed" invisible="1" />
<field name="is_un_cancel_allowed" invisible="1" />
<field name="is_auto_renew" invisible="1" />
<field name="is_canceled" invisible="1" />
<field
name="is_stop_allowed"
column_invisible="True"
/>
<field
name="is_cancel_allowed"
column_invisible="True"
/>
<field
name="is_un_cancel_allowed"
column_invisible="True"
/>
<field
name="is_auto_renew"
column_invisible="True"
/>
<field name="is_canceled" column_invisible="True" />
<button
name="action_plan_successor"
string="Plan Start"
type="object"
icon="fa-calendar text-success"
attrs="{'invisible': [('is_plan_successor_allowed', '=', False)]}"
invisible="not is_plan_successor_allowed"
/>
<button
name="action_stop_plan_successor"
string="Stop Plan Successor"
type="object"
icon="fa-pause text-muted"
attrs="{'invisible': [('is_stop_plan_successor_allowed', '=', False)]}"
invisible="not is_stop_plan_successor_allowed"
/>
<button
name="action_stop"
string="Stop"
type="object"
icon="fa-stop text-danger"
attrs="{'invisible': [('is_stop_allowed', '=', False)]}"
invisible="not is_stop_allowed"
/>
<button
name="cancel"
@@ -372,14 +409,14 @@
type="object"
icon="fa-ban text-danger"
confirm="Are you sure you want to cancel this line"
attrs="{'invisible': [('is_cancel_allowed', '=', False)]}"
invisible="not is_cancel_allowed"
/>
<button
name="action_uncancel"
string="Un-cancel"
type="object"
icon="fa-ban text-success"
attrs="{'invisible': [('is_un_cancel_allowed', '=', False)]}"
invisible="not is_un_cancel_allowed"
/>
<button
name="renew"
@@ -387,17 +424,14 @@
type="object"
icon="fa-fast-forward text-success"
groups="base.group_no_one"
attrs="{'invisible': [('is_auto_renew', '=', False)]}"
invisible="not is_auto_renew"
/>
</tree>
</field>
<field name="note" />
</page>
<page name="modications" string="Modifications">
<field
name="modification_ids"
attrs="{'readonly': [('is_terminated','=',True)]}"
>
<field name="modification_ids" readonly="is_terminated">
<tree editable="bottom">
<field name="date" />
<field name="description" />
@@ -408,17 +442,11 @@
<page name="info" string="Other Information">
<field name="create_invoice_visibility" invisible="1" />
<group>
<field
name="code"
attrs="{'readonly': [('is_terminated','=',True)]}"
/>
<field
name="group_id"
attrs="{'readonly': [('is_terminated','=',True)]}"
/>
<field name="code" readonly="is_terminated" />
<field name="group_id" readonly="is_terminated" />
<field
name="company_id"
attrs="{'readonly': [('is_terminated','=',True)]}"
readonly="is_terminated"
options="{'no_create': True}"
groups="base.group_multi_company"
/>
@@ -428,7 +456,7 @@
/>
<field
name="invoice_partner_id"
attrs="{'readonly': [('is_terminated','=',True)]}"
readonly="is_terminated"
required="1"
/>
</group>
@@ -515,7 +543,7 @@
widget="many2many_tags"
options="{'color_field': 'color'}"
/>
<field name="active" invisible="1" />
<field name="active" column_invisible="True" />
<field name="company_id" groups="base.group_multi_company" />
</tree>
</field>

View File

@@ -21,10 +21,7 @@
<field name="recurring_next_date" />
</group>
<group>
<field
name="date_end"
attrs="{'required': [('is_auto_renew', '=', True)]}"
/>
<field name="date_end" required="is_auto_renew" />
<field name="next_period_date_end" />
</group>
<group groups="base.group_no_one">
@@ -45,7 +42,7 @@
<group
name="analytic"
groups="analytic.group_analytic_accounting"
attrs="{'invisible': [('display_type', '!=', False)]}"
invisible="display_type"
>
<field
name="analytic_distribution"
@@ -106,48 +103,45 @@
<field name="quantity" />
<field name="uom_id" />
<field name="automatic_price" />
<field
name="price_unit"
attrs="{'readonly': [('automatic_price', '=', True)]}"
/>
<field name="specific_price" invisible="1" />
<field name="price_unit" readonly="automatic_price" />
<field name="specific_price" column_invisible="True" />
<field name="discount" groups="product.group_discount_per_so_line" />
<field name="price_subtotal" />
<field name="recurring_interval" invisible="1" />
<field name="recurring_rule_type" invisible="1" />
<field name="recurring_invoicing_type" invisible="1" />
<field name="date_start" required="1" />
<field name="recurring_interval" column_invisible="True" />
<field name="recurring_rule_type" column_invisible="True" />
<field name="recurring_invoicing_type" column_invisible="True" />
<field name="date_start" column_invisible="True" />
<field name="date_end" />
<field name="recurring_next_date" required="1" />
<field name="recurring_next_date" column_invisible="True" />
<field name="last_date_invoiced" groups="base.group_no_one" />
<field name="create_invoice_visibility" invisible="1" />
<field name="is_plan_successor_allowed" invisible="1" />
<field name="is_stop_plan_successor_allowed" invisible="1" />
<field name="is_stop_allowed" invisible="1" />
<field name="is_cancel_allowed" invisible="1" />
<field name="is_un_cancel_allowed" invisible="1" />
<field name="is_auto_renew" invisible="1" />
<field name="is_canceled" invisible="1" />
<field name="create_invoice_visibility" column_invisible="True" />
<field name="is_plan_successor_allowed" column_invisible="True" />
<field name="is_stop_plan_successor_allowed" column_invisible="True" />
<field name="is_stop_allowed" column_invisible="True" />
<field name="is_cancel_allowed" column_invisible="True" />
<field name="is_un_cancel_allowed" column_invisible="True" />
<field name="is_auto_renew" column_invisible="True" />
<field name="is_canceled" column_invisible="True" />
<button
name="action_plan_successor"
title="Plan Start"
type="object"
icon="fa-calendar text-success"
attrs="{'invisible': [('is_plan_successor_allowed', '=', False)]}"
invisible="not is_plan_successor_allowed"
/>
<button
name="action_stop_plan_successor"
title="Stop Plan Successor"
type="object"
icon="fa-pause text-muted"
attrs="{'invisible': [('is_stop_plan_successor_allowed', '=', False)]}"
invisible="not is_stop_plan_successor_allowed"
/>
<button
name="action_stop"
title="Stop"
type="object"
icon="fa-stop text-danger"
attrs="{'invisible': [('is_stop_allowed', '=', False)]}"
invisible="not is_stop_allowed"
/>
<button
name="cancel"
@@ -155,14 +149,14 @@
type="object"
icon="fa-ban text-danger"
confirm="Are you sure you want to cancel this line"
attrs="{'invisible': [('is_cancel_allowed', '=', False)]}"
invisible="not is_cancel_allowed"
/>
<button
name="action_uncancel"
title="Un-cancel"
type="object"
icon="fa-ban text-success"
attrs="{'invisible': [('is_un_cancel_allowed', '=', False)]}"
invisible="not is_un_cancel_allowed"
/>
<button
name="renew"
@@ -170,7 +164,7 @@
type="object"
icon="fa-fast-forward text-success"
groups="base.group_no_one"
attrs="{'invisible': [('is_auto_renew', '=', False)]}"
invisible="not is_auto_renew"
/>
</tree>
</field>

View File

@@ -12,6 +12,7 @@
<group name="group_main">
<group name="group_main_left">
<field name="contract_type" />
<field name="company_id" invisible="1" />
<field name="journal_id" />
<field name="pricelist_id" />
<field
@@ -40,29 +41,30 @@
context="{'default_display_type': 'line_note'}"
/>
</control>
<field name="display_type" invisible="1" />
<field name="display_type" column_invisible="True" />
<field name="sequence" widget="handle" />
<field name="product_id" />
<field name="name" widget="section_and_note_text" />
<field name="quantity" />
<field name="is_auto_renew" column_invisible="True" />
<field name="uom_id" />
<field
name="automatic_price"
attrs="{'column_invisible': [('parent.contract_type','=','purchase')]}"
column_invisible="parent.contract_type == 'purchase' and not is_auto_renew"
/>
<field
name="price_unit"
attrs="{'readonly': [('automatic_price', '=', True)]}"
/>
<field name="specific_price" invisible="1" />
<field name="price_unit" readonly="automatic_price" />
<field name="specific_price" column_invisible="True" />
<field
name="discount"
groups="product.group_discount_per_so_line"
/>
<field name="price_subtotal" />
<field name="recurring_rule_type" invisible="1" />
<field name="recurring_interval" invisible="1" />
<field name="recurring_invoicing_type" invisible="1" />
<field name="recurring_rule_type" column_invisible="True" />
<field name="recurring_interval" column_invisible="True" />
<field
name="recurring_invoicing_type"
column_invisible="True"
/>
</tree>
</field>
</group>

View File

@@ -6,18 +6,13 @@
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[@data-key='account']" position="inside">
<h2>Contract</h2>
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="create_new_line_at_contract_line_renew" />
</div>
<div class="o_setting_right_pane">
<label for="create_new_line_at_contract_line_renew" />
</div>
</div>
</div>
<xpath expr="//app[@name='account']" position="inside">
<block class="row mt16 o_settings_container" title="Contract">
<setting class="col-12 col-lg-6 o_setting_box">
<field name="create_new_line_at_contract_line_renew" />
<label for="create_new_line_at_contract_line_renew" />
</setting>
</block>
</xpath>
</field>
</record>

View File

@@ -19,7 +19,7 @@
groups="account.group_account_invoice"
icon="fa-book"
context="{'default_contract_type': 'sale', 'contract_type': 'sale'}"
attrs="{'invisible': [('customer_rank','=',0)]}"
invisible="customer_rank == 0"
help="Show the sale contracts for this partner"
>
<field
@@ -40,7 +40,7 @@
groups="account.group_account_invoice"
icon="fa-book"
context="{'default_contract_type': 'purchase', 'contract_type': 'purchase'}"
attrs="{'invisible': [('supplier_rank','=',0)]}"
invisible="supplier_rank == 0"
help="Show the purchase contracts for this partner"
>
<field

View File

@@ -13,7 +13,7 @@
<field name="terminate_reason_id" widget="selection" />
<field
name="terminate_comment"
attrs="{'required': [('terminate_comment_required', '=', True)]}"
required="terminate_comment_required"
/>
</group>
<footer>

View File

@@ -37,10 +37,7 @@
<group>
<field name="contract_line_id" invisible="True" />
<field name="date_start" required="True" />
<field
name="date_end"
attrs="{'required': [('is_auto_renew', '=', True)]}"
/>
<field name="date_end" required="is_auto_renew" />
<field name="is_auto_renew" />
</group>
<footer>

View File

@@ -16,17 +16,13 @@
name="action_show_contract_to_invoice"
type="object"
class="btn-link"
attrs="{'invisible': [('contract_to_invoice_count', '=', 0)]}"
invisible="contract_to_invoice_count == 0"
>
<field name="contract_to_invoice_count" />
<span
attrs="{'invisible': [('contract_to_invoice_count', '&gt;', 1)]}"
>
<span invisible="contract_to_invoice_count > 1">
contract to invoice
</span>
<span
attrs="{'invisible': [('contract_to_invoice_count', '&lt;=', 1)]}"
>
<span invisible="contract_to_invoice_count &lt;= 1">
contracts to invoice
</span>
</button>
@@ -35,7 +31,7 @@
<footer>
<button
name="create_invoice"
attrs="{'invisible': [('contract_to_invoice_count', '=', 0)]}"
invisible="contract_to_invoice_count == 0"
string="Create Invoices"
class="btn-primary"
type="object"