mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
[IMP] : black, isort, prettier
This commit is contained in:
@@ -8,42 +8,42 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
'name': 'Recurring - Contracts Management',
|
||||
'version': '12.0.7.2.2',
|
||||
'category': 'Contract Management',
|
||||
'license': 'AGPL-3',
|
||||
'author': "OpenERP SA, "
|
||||
"name": "Recurring - Contracts Management",
|
||||
"version": "12.0.7.2.2",
|
||||
"category": "Contract Management",
|
||||
"license": "AGPL-3",
|
||||
"author": "OpenERP SA, "
|
||||
"Tecnativa, "
|
||||
"LasLabs, "
|
||||
"Odoo Community Association (OCA)",
|
||||
'website': 'https://github.com/oca/contract',
|
||||
'depends': ['base', 'account', 'product'],
|
||||
"website": "https://github.com/oca/contract",
|
||||
"depends": ["base", "account", "product"],
|
||||
"external_dependencies": {"python": ["dateutil"]},
|
||||
'data': [
|
||||
'security/groups.xml',
|
||||
'security/contract_tag.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'security/contract_security.xml',
|
||||
'security/contract_terminate_reason.xml',
|
||||
'report/report_contract.xml',
|
||||
'report/contract_views.xml',
|
||||
'data/contract_cron.xml',
|
||||
'data/contract_renew_cron.xml',
|
||||
'data/mail_template.xml',
|
||||
'data/ir_ui_menu.xml',
|
||||
'wizards/contract_line_wizard.xml',
|
||||
'wizards/contract_manually_create_invoice.xml',
|
||||
'wizards/contract_contract_terminate.xml',
|
||||
'views/contract_tag.xml',
|
||||
'views/assets.xml',
|
||||
'views/abstract_contract_line.xml',
|
||||
'views/contract.xml',
|
||||
'views/contract_line.xml',
|
||||
'views/contract_template.xml',
|
||||
'views/contract_template_line.xml',
|
||||
'views/res_partner_view.xml',
|
||||
'views/res_config_settings.xml',
|
||||
'views/contract_terminate_reason.xml',
|
||||
"data": [
|
||||
"security/groups.xml",
|
||||
"security/contract_tag.xml",
|
||||
"security/ir.model.access.csv",
|
||||
"security/contract_security.xml",
|
||||
"security/contract_terminate_reason.xml",
|
||||
"report/report_contract.xml",
|
||||
"report/contract_views.xml",
|
||||
"data/contract_cron.xml",
|
||||
"data/contract_renew_cron.xml",
|
||||
"data/mail_template.xml",
|
||||
"data/ir_ui_menu.xml",
|
||||
"wizards/contract_line_wizard.xml",
|
||||
"wizards/contract_manually_create_invoice.xml",
|
||||
"wizards/contract_contract_terminate.xml",
|
||||
"views/contract_tag.xml",
|
||||
"views/assets.xml",
|
||||
"views/abstract_contract_line.xml",
|
||||
"views/contract.xml",
|
||||
"views/contract_line.xml",
|
||||
"views/contract_template.xml",
|
||||
"views/contract_template_line.xml",
|
||||
"views/res_partner_view.xml",
|
||||
"views/res_config_settings.xml",
|
||||
"views/contract_terminate_reason.xml",
|
||||
],
|
||||
'installable': True,
|
||||
"installable": True,
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding='UTF-8'?>
|
||||
<?xml version="1.0" encoding='UTF-8' ?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record model="ir.cron" id="contract_cron_for_invoice">
|
||||
<field name="name">Generate Recurring Invoices from Contracts</field>
|
||||
<field name="model_id" ref="model_contract_contract"/>
|
||||
<field name="model_id" ref="model_contract_contract" />
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.cron_recurring_create_invoice()</field>
|
||||
<field name="user_id" ref="base.user_root" />
|
||||
@@ -12,5 +11,4 @@
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding='UTF-8'?>
|
||||
<?xml version="1.0" encoding='UTF-8' ?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record model="ir.cron" id="contract_line_cron_for_renew">
|
||||
<field name="name">Renew Contract lines</field>
|
||||
<field name="model_id" ref="model_contract_line"/>
|
||||
<field name="model_id" ref="model_contract_line" />
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.cron_renew_contract_line()</field>
|
||||
<field name="user_id" ref="base.user_root" />
|
||||
@@ -12,5 +11,4 @@
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<menuitem id="menu_config_contract"
|
||||
<menuitem
|
||||
id="menu_config_contract"
|
||||
name="Contracts"
|
||||
sequence="1"
|
||||
parent="account.menu_finance_configuration"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
<?xml version="1.0" ?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="email_contract_template" model="mail.template">
|
||||
<field name="name">Email Contract Template</field>
|
||||
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.name, object.user_id.email) or '')|safe}</field>
|
||||
<field name="subject">${object.company_id.name} Contract (Ref ${object.name or 'n/a'})</field>
|
||||
<field
|
||||
name="email_from"
|
||||
>${(object.user_id.email and '%s <%s>' % (object.user_id.name, object.user_id.email) or '')|safe}</field>
|
||||
<field
|
||||
name="subject"
|
||||
>${object.company_id.name} Contract (Ref ${object.name or 'n/a'})</field>
|
||||
<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="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="lang">${object.partner_id.lang}</field>
|
||||
<field name="body_html"><![CDATA[
|
||||
<field
|
||||
name="body_html"
|
||||
><![CDATA[
|
||||
<div style="font-family: 'Lucida Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
|
||||
<p>Hello ${object.partner_id.name or ''},</p>
|
||||
<p>A new contract has been created: </p>
|
||||
@@ -60,5 +65,4 @@
|
||||
</div>
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import logging
|
||||
|
||||
from openupgradelib import openupgrade
|
||||
|
||||
from odoo.tools import parse_version
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -11,22 +12,20 @@ _logger = logging.getLogger(__name__)
|
||||
|
||||
def _update_no_update_ir_cron(env):
|
||||
# Update ir.cron
|
||||
env.ref('contract.contract_cron_for_invoice').model_id = env.ref(
|
||||
'contract.model_contract_contract'
|
||||
env.ref("contract.contract_cron_for_invoice").model_id = env.ref(
|
||||
"contract.model_contract_contract"
|
||||
)
|
||||
env.ref('contract.contract_line_cron_for_renew').model_id = env.ref(
|
||||
'contract.model_contract_line'
|
||||
env.ref("contract.contract_line_cron_for_renew").model_id = env.ref(
|
||||
"contract.model_contract_line"
|
||||
)
|
||||
env.ref('contract.email_contract_template').model_id = env.ref(
|
||||
'contract.model_contract_contract'
|
||||
env.ref("contract.email_contract_template").model_id = env.ref(
|
||||
"contract.model_contract_contract"
|
||||
)
|
||||
|
||||
|
||||
def _init_last_date_invoiced_on_contract_lines(env):
|
||||
_logger.info("init last_date_invoiced field for contract lines")
|
||||
contract_lines = env["contract.line"].search(
|
||||
[("recurring_next_date", "!=", False)]
|
||||
)
|
||||
contract_lines = env["contract.line"].search([("recurring_next_date", "!=", False)])
|
||||
contract_lines._init_last_date_invoiced()
|
||||
|
||||
|
||||
@@ -43,7 +42,8 @@ def assign_salesman(env):
|
||||
will have admin as responsible.
|
||||
"""
|
||||
openupgrade.logged_query(
|
||||
env.cr, """
|
||||
env.cr,
|
||||
"""
|
||||
UPDATE contract_contract cc
|
||||
SET user_id = rp.user_id
|
||||
FROM res_partner rp
|
||||
@@ -54,7 +54,7 @@ def assign_salesman(env):
|
||||
@openupgrade.migrate()
|
||||
def migrate(env, version):
|
||||
_update_no_update_ir_cron(env)
|
||||
if parse_version(version) < parse_version('12.0.2.0.0'):
|
||||
if parse_version(version) < parse_version("12.0.2.0.0"):
|
||||
# We check the version here as this post-migration script was in
|
||||
# 12.0.2.0.0 and already done for those who used the module when
|
||||
# it was a PR
|
||||
|
||||
@@ -11,62 +11,51 @@ _logger = logging.getLogger(__name__)
|
||||
|
||||
models_to_rename = [
|
||||
# Contract Line Wizard
|
||||
('account.analytic.invoice.line.wizard', 'contract.line.wizard'),
|
||||
("account.analytic.invoice.line.wizard", "contract.line.wizard"),
|
||||
# Abstract Contract
|
||||
('account.abstract.analytic.contract', 'contract.abstract.contract'),
|
||||
("account.abstract.analytic.contract", "contract.abstract.contract"),
|
||||
# Abstract Contract Line
|
||||
(
|
||||
'account.abstract.analytic.contract.line',
|
||||
'contract.abstract.contract.line',
|
||||
),
|
||||
("account.abstract.analytic.contract.line", "contract.abstract.contract.line",),
|
||||
# Contract Line
|
||||
('account.analytic.invoice.line', 'contract.line'),
|
||||
("account.analytic.invoice.line", "contract.line"),
|
||||
# Contract Template
|
||||
('account.analytic.contract', 'contract.template'),
|
||||
("account.analytic.contract", "contract.template"),
|
||||
# Contract Template Line
|
||||
('account.analytic.contract.line', 'contract.template.line'),
|
||||
("account.analytic.contract.line", "contract.template.line"),
|
||||
]
|
||||
tables_to_rename = [
|
||||
# Contract Line
|
||||
('account_analytic_invoice_line', 'contract_line'),
|
||||
("account_analytic_invoice_line", "contract_line"),
|
||||
# Contract Template
|
||||
('account_analytic_contract', 'contract_template'),
|
||||
("account_analytic_contract", "contract_template"),
|
||||
# Contract Template Line
|
||||
('account_analytic_contract_line', 'contract_template_line'),
|
||||
("account_analytic_contract_line", "contract_template_line"),
|
||||
]
|
||||
columns_to_copy = {
|
||||
'contract_line': [
|
||||
('analytic_account_id', 'contract_id', None),
|
||||
],
|
||||
"contract_line": [("analytic_account_id", "contract_id", None),],
|
||||
}
|
||||
xmlids_to_rename = [
|
||||
(
|
||||
'contract.account_analytic_cron_for_invoice',
|
||||
'contract.contract_cron_for_invoice',
|
||||
"contract.account_analytic_cron_for_invoice",
|
||||
"contract.contract_cron_for_invoice",
|
||||
),
|
||||
(
|
||||
'contract.account_analytic_contract_manager',
|
||||
'contract.contract_template_manager',
|
||||
"contract.account_analytic_contract_manager",
|
||||
"contract.contract_template_manager",
|
||||
),
|
||||
("contract.account_analytic_contract_user", "contract.contract_template_user",),
|
||||
(
|
||||
"contract.account_analytic_invoice_line_manager",
|
||||
"contract.contract_line_manager",
|
||||
),
|
||||
("contract.account_analytic_invoice_line_user", "contract.contract_line_user",),
|
||||
(
|
||||
"contract.account_analytic_contract_line_manager",
|
||||
"contract.contract_template_line_manager",
|
||||
),
|
||||
(
|
||||
'contract.account_analytic_contract_user',
|
||||
'contract.contract_template_user',
|
||||
),
|
||||
(
|
||||
'contract.account_analytic_invoice_line_manager',
|
||||
'contract.contract_line_manager',
|
||||
),
|
||||
(
|
||||
'contract.account_analytic_invoice_line_user',
|
||||
'contract.contract_line_user',
|
||||
),
|
||||
(
|
||||
'contract.account_analytic_contract_line_manager',
|
||||
'contract.contract_template_line_manager',
|
||||
),
|
||||
(
|
||||
'contract.account_analytic_contract_line_user',
|
||||
'contract.contract_template_line_user',
|
||||
"contract.account_analytic_contract_line_user",
|
||||
"contract.contract_template_line_user",
|
||||
),
|
||||
]
|
||||
|
||||
@@ -77,33 +66,34 @@ def _get_contract_field_name(cr):
|
||||
in 12.0.2.0.0. This method used to get the contract field name in
|
||||
account_analytic_invoice_line"""
|
||||
return (
|
||||
'contract_id'
|
||||
if openupgrade.column_exists(
|
||||
cr, 'account_analytic_invoice_line', 'contract_id'
|
||||
)
|
||||
else 'analytic_account_id'
|
||||
"contract_id"
|
||||
if openupgrade.column_exists(cr, "account_analytic_invoice_line", "contract_id")
|
||||
else "analytic_account_id"
|
||||
)
|
||||
|
||||
|
||||
def create_contract_records(cr):
|
||||
contract_field_name = _get_contract_field_name(cr)
|
||||
openupgrade.logged_query(
|
||||
cr, """
|
||||
cr,
|
||||
"""
|
||||
CREATE TABLE contract_contract
|
||||
(LIKE account_analytic_account INCLUDING ALL)""",
|
||||
)
|
||||
openupgrade.logged_query(
|
||||
cr, sql.SQL("""
|
||||
cr,
|
||||
sql.SQL(
|
||||
"""
|
||||
INSERT INTO contract_contract
|
||||
SELECT * FROM account_analytic_account
|
||||
WHERE id IN (SELECT DISTINCT {} FROM contract_line)
|
||||
""").format(
|
||||
sql.Identifier(contract_field_name),
|
||||
),
|
||||
"""
|
||||
).format(sql.Identifier(contract_field_name),),
|
||||
)
|
||||
# Deactivate disabled contracts
|
||||
openupgrade.logged_query(
|
||||
cr, """UPDATE contract_contract cc
|
||||
cr,
|
||||
"""UPDATE contract_contract cc
|
||||
SET active = False
|
||||
FROM account_analytic_account aaa
|
||||
WHERE aaa.id = cc.id
|
||||
@@ -111,24 +101,31 @@ def create_contract_records(cr):
|
||||
)
|
||||
# Handle id sequence
|
||||
cr.execute("CREATE SEQUENCE IF NOT EXISTS contract_contract_id_seq")
|
||||
cr.execute("SELECT setval('contract_contract_id_seq', "
|
||||
"(SELECT MAX(id) FROM contract_contract))")
|
||||
cr.execute("ALTER TABLE contract_contract ALTER id "
|
||||
"SET DEFAULT NEXTVAL('contract_contract_id_seq')")
|
||||
cr.execute(
|
||||
"SELECT setval('contract_contract_id_seq', "
|
||||
"(SELECT MAX(id) FROM contract_contract))"
|
||||
)
|
||||
cr.execute(
|
||||
"ALTER TABLE contract_contract ALTER id "
|
||||
"SET DEFAULT NEXTVAL('contract_contract_id_seq')"
|
||||
)
|
||||
# Move common stuff from one table to the other
|
||||
mapping = [
|
||||
('ir_attachment', 'res_model', 'res_id'),
|
||||
('mail_message', 'model', 'res_id'),
|
||||
('mail_activity', 'res_model', 'res_id'),
|
||||
('mail_followers', 'res_model', 'res_id'),
|
||||
("ir_attachment", "res_model", "res_id"),
|
||||
("mail_message", "model", "res_id"),
|
||||
("mail_activity", "res_model", "res_id"),
|
||||
("mail_followers", "res_model", "res_id"),
|
||||
]
|
||||
for table, model_column, id_column in mapping:
|
||||
openupgrade.logged_query(
|
||||
cr, sql.SQL("""
|
||||
cr,
|
||||
sql.SQL(
|
||||
"""
|
||||
UPDATE {table} SET {model_column}='contract.contract'
|
||||
WHERE {model_column}='account.analytic.account'
|
||||
AND {id_column} IN (SELECT DISTINCT {col} FROM contract_line)
|
||||
""").format(
|
||||
"""
|
||||
).format(
|
||||
table=sql.Identifier(table),
|
||||
model_column=sql.Identifier(model_column),
|
||||
id_column=sql.Identifier(id_column),
|
||||
|
||||
@@ -6,68 +6,61 @@
|
||||
# Copyright 2018 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, models, fields
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class ContractAbstractContract(models.AbstractModel):
|
||||
_name = 'contract.abstract.contract'
|
||||
_description = 'Abstract Recurring Contract'
|
||||
_name = "contract.abstract.contract"
|
||||
_description = "Abstract Recurring Contract"
|
||||
|
||||
# These fields will not be synced to the contract
|
||||
NO_SYNC = ['name', 'partner_id', 'company_id']
|
||||
NO_SYNC = ["name", "partner_id", "company_id"]
|
||||
|
||||
name = fields.Char(required=True)
|
||||
# Needed for avoiding errors on several inherited behaviors
|
||||
partner_id = fields.Many2one(
|
||||
comodel_name="res.partner", string="Partner", index=True
|
||||
)
|
||||
pricelist_id = fields.Many2one(
|
||||
comodel_name='product.pricelist', string='Pricelist'
|
||||
)
|
||||
pricelist_id = fields.Many2one(comodel_name="product.pricelist", string="Pricelist")
|
||||
contract_type = fields.Selection(
|
||||
selection=[('sale', 'Customer'), ('purchase', 'Supplier')],
|
||||
default='sale',
|
||||
selection=[("sale", "Customer"), ("purchase", "Supplier")],
|
||||
default="sale",
|
||||
index=True,
|
||||
)
|
||||
|
||||
journal_id = fields.Many2one(
|
||||
'account.journal',
|
||||
string='Journal',
|
||||
"account.journal",
|
||||
string="Journal",
|
||||
default=lambda s: s._default_journal(),
|
||||
domain="[('type', '=', contract_type),"
|
||||
"('company_id', '=', company_id)]",
|
||||
domain="[('type', '=', contract_type)," "('company_id', '=', company_id)]",
|
||||
index=True,
|
||||
)
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
string='Company',
|
||||
"res.company",
|
||||
string="Company",
|
||||
required=True,
|
||||
default=lambda self: self.env['res.company']._company_default_get(
|
||||
self._name
|
||||
),
|
||||
default=lambda self: self.env["res.company"]._company_default_get(self._name),
|
||||
)
|
||||
|
||||
@api.onchange('contract_type')
|
||||
@api.onchange("contract_type")
|
||||
def _onchange_contract_type(self):
|
||||
if self.contract_type == 'purchase':
|
||||
self.contract_line_ids.filtered('automatic_price').update(
|
||||
{'automatic_price': False}
|
||||
if self.contract_type == "purchase":
|
||||
self.contract_line_ids.filtered("automatic_price").update(
|
||||
{"automatic_price": False}
|
||||
)
|
||||
self.journal_id = self.env['account.journal'].search(
|
||||
self.journal_id = self.env["account.journal"].search(
|
||||
[
|
||||
('type', '=', self.contract_type),
|
||||
('company_id', '=', self.company_id.id),
|
||||
("type", "=", self.contract_type),
|
||||
("company_id", "=", self.company_id.id),
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _default_journal(self):
|
||||
company_id = self.env.context.get(
|
||||
'company_id', self.env.user.company_id.id
|
||||
)
|
||||
company_id = self.env.context.get("company_id", self.env.user.company_id.id)
|
||||
domain = [
|
||||
('type', '=', self.contract_type),
|
||||
('company_id', '=', company_id),
|
||||
("type", "=", self.contract_type),
|
||||
("company_id", "=", company_id),
|
||||
]
|
||||
return self.env['account.journal'].search(domain, limit=1)
|
||||
return self.env["account.journal"].search(domain, limit=1)
|
||||
|
||||
@@ -6,47 +6,44 @@
|
||||
# Copyright 2018 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, models, fields
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo import api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tools.translate import _
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
|
||||
class ContractAbstractContractLine(models.AbstractModel):
|
||||
_name = 'contract.abstract.contract.line'
|
||||
_description = 'Abstract Recurring Contract Line'
|
||||
_name = "contract.abstract.contract.line"
|
||||
_description = "Abstract Recurring Contract Line"
|
||||
|
||||
product_id = fields.Many2one(
|
||||
'product.product', string='Product'
|
||||
)
|
||||
product_id = fields.Many2one("product.product", string="Product")
|
||||
|
||||
name = fields.Text(string='Description', required=True)
|
||||
name = fields.Text(string="Description", required=True)
|
||||
quantity = fields.Float(default=1.0, required=True)
|
||||
uom_id = fields.Many2one(
|
||||
'uom.uom', string='Unit of Measure'
|
||||
)
|
||||
uom_id = fields.Many2one("uom.uom", string="Unit of Measure")
|
||||
automatic_price = fields.Boolean(
|
||||
string="Auto-price?",
|
||||
help="If this is marked, the price will be obtained automatically "
|
||||
"applying the pricelist to the product. If not, you will be "
|
||||
"able to introduce a manual price",
|
||||
)
|
||||
specific_price = fields.Float(string='Specific Price')
|
||||
specific_price = fields.Float(string="Specific Price")
|
||||
price_unit = fields.Float(
|
||||
string='Unit Price',
|
||||
string="Unit Price",
|
||||
compute="_compute_price_unit",
|
||||
inverse="_inverse_price_unit",
|
||||
)
|
||||
price_subtotal = fields.Float(
|
||||
compute='_compute_price_subtotal',
|
||||
digits=dp.get_precision('Account'),
|
||||
string='Sub Total',
|
||||
compute="_compute_price_subtotal",
|
||||
digits=dp.get_precision("Account"),
|
||||
string="Sub Total",
|
||||
)
|
||||
discount = fields.Float(
|
||||
string='Discount (%)',
|
||||
digits=dp.get_precision('Discount'),
|
||||
help='Discount that is applied in generated invoices.'
|
||||
' It should be less or equal to 100',
|
||||
string="Discount (%)",
|
||||
digits=dp.get_precision("Discount"),
|
||||
help="Discount that is applied in generated invoices."
|
||||
" It should be less or equal to 100",
|
||||
)
|
||||
sequence = fields.Integer(
|
||||
string="Sequence",
|
||||
@@ -55,23 +52,23 @@ class ContractAbstractContractLine(models.AbstractModel):
|
||||
)
|
||||
recurring_rule_type = fields.Selection(
|
||||
[
|
||||
('daily', 'Day(s)'),
|
||||
('weekly', 'Week(s)'),
|
||||
('monthly', 'Month(s)'),
|
||||
('monthlylastday', 'Month(s) last day'),
|
||||
('quarterly', 'Quarter(s)'),
|
||||
('semesterly', 'Semester(s)'),
|
||||
('yearly', 'Year(s)'),
|
||||
("daily", "Day(s)"),
|
||||
("weekly", "Week(s)"),
|
||||
("monthly", "Month(s)"),
|
||||
("monthlylastday", "Month(s) last day"),
|
||||
("quarterly", "Quarter(s)"),
|
||||
("semesterly", "Semester(s)"),
|
||||
("yearly", "Year(s)"),
|
||||
],
|
||||
default='monthly',
|
||||
string='Recurrence',
|
||||
default="monthly",
|
||||
string="Recurrence",
|
||||
help="Specify Interval for automatic invoice generation.",
|
||||
required=True,
|
||||
)
|
||||
recurring_invoicing_type = fields.Selection(
|
||||
[('pre-paid', 'Pre-paid'), ('post-paid', 'Post-paid')],
|
||||
default='pre-paid',
|
||||
string='Invoicing type',
|
||||
[("pre-paid", "Pre-paid"), ("post-paid", "Post-paid")],
|
||||
default="pre-paid",
|
||||
string="Invoicing type",
|
||||
help=(
|
||||
"Specify if the invoice must be generated at the beginning "
|
||||
"(pre-paid) or end (post-paid) of the period."
|
||||
@@ -84,68 +81,63 @@ class ContractAbstractContractLine(models.AbstractModel):
|
||||
help=(
|
||||
"Number of days to offset the invoice from the period end "
|
||||
"date (in post-paid mode) or start date (in pre-paid mode)."
|
||||
)
|
||||
),
|
||||
)
|
||||
recurring_interval = fields.Integer(
|
||||
default=1,
|
||||
string='Invoice Every',
|
||||
string="Invoice Every",
|
||||
help="Invoice every (Days/Week/Month/Year)",
|
||||
required=True,
|
||||
)
|
||||
date_start = fields.Date(string='Date Start')
|
||||
recurring_next_date = fields.Date(string='Date of Next Invoice')
|
||||
last_date_invoiced = fields.Date(string='Last Date Invoiced')
|
||||
date_start = fields.Date(string="Date Start")
|
||||
recurring_next_date = fields.Date(string="Date of Next Invoice")
|
||||
last_date_invoiced = fields.Date(string="Last Date Invoiced")
|
||||
is_canceled = fields.Boolean(string="Canceled", default=False)
|
||||
is_auto_renew = fields.Boolean(string="Auto Renew", default=False)
|
||||
auto_renew_interval = fields.Integer(
|
||||
default=1,
|
||||
string='Renew Every',
|
||||
help="Renew every (Days/Week/Month/Year)",
|
||||
default=1, string="Renew Every", help="Renew every (Days/Week/Month/Year)",
|
||||
)
|
||||
auto_renew_rule_type = fields.Selection(
|
||||
[
|
||||
('daily', 'Day(s)'),
|
||||
('weekly', 'Week(s)'),
|
||||
('monthly', 'Month(s)'),
|
||||
('yearly', 'Year(s)'),
|
||||
("daily", "Day(s)"),
|
||||
("weekly", "Week(s)"),
|
||||
("monthly", "Month(s)"),
|
||||
("yearly", "Year(s)"),
|
||||
],
|
||||
default='yearly',
|
||||
string='Renewal type',
|
||||
default="yearly",
|
||||
string="Renewal type",
|
||||
help="Specify Interval for automatic renewal.",
|
||||
)
|
||||
termination_notice_interval = fields.Integer(
|
||||
default=1, string='Termination Notice Before'
|
||||
default=1, string="Termination Notice Before"
|
||||
)
|
||||
termination_notice_rule_type = fields.Selection(
|
||||
[('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)')],
|
||||
default='monthly',
|
||||
string='Termination Notice type',
|
||||
[("daily", "Day(s)"), ("weekly", "Week(s)"), ("monthly", "Month(s)")],
|
||||
default="monthly",
|
||||
string="Termination Notice type",
|
||||
)
|
||||
contract_id = fields.Many2one(
|
||||
string='Contract',
|
||||
comodel_name='contract.abstract.contract',
|
||||
string="Contract",
|
||||
comodel_name="contract.abstract.contract",
|
||||
required=True,
|
||||
ondelete='cascade',
|
||||
ondelete="cascade",
|
||||
)
|
||||
display_type = fields.Selection(
|
||||
selection=[
|
||||
('line_section', "Section"),
|
||||
('line_note', "Note"),
|
||||
],
|
||||
selection=[("line_section", "Section"), ("line_note", "Note"),],
|
||||
default=False,
|
||||
help="Technical field for UX purpose."
|
||||
help="Technical field for UX purpose.",
|
||||
)
|
||||
note_invoicing_mode = fields.Selection(
|
||||
selection=[
|
||||
('with_previous_line', 'With previous line'),
|
||||
('with_next_line', 'With next line'),
|
||||
('custom', 'Custom'),
|
||||
("with_previous_line", "With previous line"),
|
||||
("with_next_line", "With next line"),
|
||||
("custom", "Custom"),
|
||||
],
|
||||
default='with_previous_line',
|
||||
default="with_previous_line",
|
||||
help="Defines when the Note is invoiced:\n"
|
||||
"- With previous line: If the previous line can be invoiced.\n"
|
||||
"- With next line: If the next line can be invoiced.\n"
|
||||
"- Custom: Depending on the recurrence to be define."
|
||||
"- Custom: Depending on the recurrence to be define.",
|
||||
)
|
||||
is_recurring_note = fields.Boolean(compute="_compute_is_recurring_note")
|
||||
|
||||
@@ -154,8 +146,8 @@ class ContractAbstractContractLine(models.AbstractModel):
|
||||
self, recurring_invoicing_type, recurring_rule_type
|
||||
):
|
||||
if (
|
||||
recurring_invoicing_type == 'pre-paid'
|
||||
or recurring_rule_type == 'monthlylastday'
|
||||
recurring_invoicing_type == "pre-paid"
|
||||
or recurring_rule_type == "monthlylastday"
|
||||
):
|
||||
return 0
|
||||
else:
|
||||
@@ -164,26 +156,24 @@ class ContractAbstractContractLine(models.AbstractModel):
|
||||
def is_recurring_note(self):
|
||||
for record in self:
|
||||
record.is_recurring_note = (
|
||||
record.display_type == 'line_note'
|
||||
and record.note_invoicing_mode == 'custom'
|
||||
record.display_type == "line_note"
|
||||
and record.note_invoicing_mode == "custom"
|
||||
)
|
||||
|
||||
@api.depends('recurring_invoicing_type', 'recurring_rule_type')
|
||||
@api.depends("recurring_invoicing_type", "recurring_rule_type")
|
||||
def _compute_recurring_invoicing_offset(self):
|
||||
for rec in self:
|
||||
rec.recurring_invoicing_offset = (
|
||||
self._get_default_recurring_invoicing_offset(
|
||||
rec.recurring_invoicing_offset = self._get_default_recurring_invoicing_offset(
|
||||
rec.recurring_invoicing_type, rec.recurring_rule_type
|
||||
)
|
||||
)
|
||||
|
||||
@api.depends(
|
||||
'automatic_price',
|
||||
'specific_price',
|
||||
'product_id',
|
||||
'quantity',
|
||||
'contract_id.pricelist_id',
|
||||
'contract_id.partner_id',
|
||||
"automatic_price",
|
||||
"specific_price",
|
||||
"product_id",
|
||||
"quantity",
|
||||
"contract_id.pricelist_id",
|
||||
"contract_id.partner_id",
|
||||
)
|
||||
def _compute_price_unit(self):
|
||||
"""Get the specific price if no auto-price, and the price obtained
|
||||
@@ -192,20 +182,17 @@ class ContractAbstractContractLine(models.AbstractModel):
|
||||
for line in self:
|
||||
if line.automatic_price:
|
||||
pricelist = (
|
||||
line.contract_id.pricelist_id or
|
||||
line.contract_id.partner_id.with_context(
|
||||
line.contract_id.pricelist_id
|
||||
or line.contract_id.partner_id.with_context(
|
||||
force_company=line.contract_id.company_id.id,
|
||||
).property_product_pricelist
|
||||
)
|
||||
product = line.product_id.with_context(
|
||||
quantity=line.env.context.get(
|
||||
'contract_line_qty',
|
||||
line.quantity,
|
||||
),
|
||||
quantity=line.env.context.get("contract_line_qty", line.quantity,),
|
||||
pricelist=pricelist.id,
|
||||
partner=line.contract_id.partner_id.id,
|
||||
date=line.env.context.get(
|
||||
'old_date', fields.Date.context_today(line)
|
||||
"old_date", fields.Date.context_today(line)
|
||||
),
|
||||
)
|
||||
line.price_unit = product.price
|
||||
@@ -213,14 +200,14 @@ class ContractAbstractContractLine(models.AbstractModel):
|
||||
line.price_unit = line.specific_price
|
||||
|
||||
# Tip in https://github.com/odoo/odoo/issues/23891#issuecomment-376910788
|
||||
@api.onchange('price_unit')
|
||||
@api.onchange("price_unit")
|
||||
def _inverse_price_unit(self):
|
||||
"""Store the specific price in the no auto-price records."""
|
||||
for line in self.filtered(lambda x: not x.automatic_price):
|
||||
line.specific_price = line.price_unit
|
||||
|
||||
@api.multi
|
||||
@api.depends('quantity', 'price_unit', 'discount')
|
||||
@api.depends("quantity", "price_unit", "discount")
|
||||
def _compute_price_subtotal(self):
|
||||
for line in self:
|
||||
subtotal = line.quantity * line.price_unit
|
||||
@@ -233,30 +220,26 @@ class ContractAbstractContractLine(models.AbstractModel):
|
||||
line.price_subtotal = subtotal
|
||||
|
||||
@api.multi
|
||||
@api.constrains('discount')
|
||||
@api.constrains("discount")
|
||||
def _check_discount(self):
|
||||
for line in self:
|
||||
if line.discount > 100:
|
||||
raise ValidationError(
|
||||
_("Discount should be less or equal to 100")
|
||||
)
|
||||
raise ValidationError(_("Discount should be less or equal to 100"))
|
||||
|
||||
@api.multi
|
||||
@api.onchange('product_id')
|
||||
@api.onchange("product_id")
|
||||
def _onchange_product_id(self):
|
||||
if not self.product_id:
|
||||
return {'domain': {'uom_id': []}}
|
||||
return {"domain": {"uom_id": []}}
|
||||
|
||||
vals = {}
|
||||
domain = {
|
||||
'uom_id': [
|
||||
('category_id', '=', self.product_id.uom_id.category_id.id)
|
||||
]
|
||||
"uom_id": [("category_id", "=", self.product_id.uom_id.category_id.id)]
|
||||
}
|
||||
if not self.uom_id or (
|
||||
self.product_id.uom_id.category_id.id != self.uom_id.category_id.id
|
||||
):
|
||||
vals['uom_id'] = self.product_id.uom_id
|
||||
vals["uom_id"] = self.product_id.uom_id
|
||||
|
||||
date = self.recurring_next_date or fields.Date.context_today(self)
|
||||
partner = self.contract_id.partner_id or self.env.user.partner_id
|
||||
@@ -268,7 +251,7 @@ class ContractAbstractContractLine(models.AbstractModel):
|
||||
pricelist=self.contract_id.pricelist_id.id,
|
||||
uom=self.uom_id.id,
|
||||
)
|
||||
vals['name'] = self.product_id.get_product_multiline_description_sale()
|
||||
vals['price_unit'] = product.price
|
||||
vals["name"] = self.product_id.get_product_multiline_description_sale()
|
||||
vals["price_unit"] = product.price
|
||||
self.update(vals)
|
||||
return {'domain': domain}
|
||||
return {"domain": domain}
|
||||
|
||||
@@ -5,8 +5,7 @@ from odoo import fields, models
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
_inherit = 'account.invoice'
|
||||
_inherit = "account.invoice"
|
||||
|
||||
# We keep this field for migration purpose
|
||||
old_contract_id = fields.Many2one(
|
||||
'contract.contract', oldname='contract_id')
|
||||
old_contract_id = fields.Many2one("contract.contract", oldname="contract_id")
|
||||
|
||||
@@ -5,8 +5,8 @@ from odoo import fields, models
|
||||
|
||||
|
||||
class AccountInvoiceLine(models.Model):
|
||||
_inherit = 'account.invoice.line'
|
||||
_inherit = "account.invoice.line"
|
||||
|
||||
contract_line_id = fields.Many2one(
|
||||
'contract.line', string='Contract Line', index=True
|
||||
"contract.line", string="Contract Line", index=True
|
||||
)
|
||||
|
||||
@@ -7,30 +7,24 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools.translate import _
|
||||
|
||||
|
||||
class ContractContract(models.Model):
|
||||
_name = 'contract.contract'
|
||||
_name = "contract.contract"
|
||||
_description = "Contract"
|
||||
_order = 'code, name asc'
|
||||
_order = "code, name asc"
|
||||
_inherit = [
|
||||
'mail.thread',
|
||||
'mail.activity.mixin',
|
||||
'contract.abstract.contract',
|
||||
"mail.thread",
|
||||
"mail.activity.mixin",
|
||||
"contract.abstract.contract",
|
||||
]
|
||||
|
||||
active = fields.Boolean(
|
||||
default=True,
|
||||
)
|
||||
code = fields.Char(
|
||||
string="Reference",
|
||||
)
|
||||
active = fields.Boolean(default=True,)
|
||||
code = fields.Char(string="Reference",)
|
||||
group_id = fields.Many2one(
|
||||
string="Group",
|
||||
comodel_name='account.analytic.account',
|
||||
ondelete='restrict',
|
||||
string="Group", comodel_name="account.analytic.account", ondelete="restrict",
|
||||
)
|
||||
currency_id = fields.Many2one(
|
||||
compute="_compute_currency_id",
|
||||
@@ -38,70 +32,59 @@ class ContractContract(models.Model):
|
||||
comodel_name="res.currency",
|
||||
string="Currency",
|
||||
)
|
||||
manual_currency_id = fields.Many2one(
|
||||
comodel_name="res.currency",
|
||||
readonly=True,
|
||||
)
|
||||
manual_currency_id = fields.Many2one(comodel_name="res.currency", readonly=True,)
|
||||
contract_template_id = fields.Many2one(
|
||||
string='Contract Template', comodel_name='contract.template'
|
||||
string="Contract Template", comodel_name="contract.template"
|
||||
)
|
||||
contract_line_ids = fields.One2many(
|
||||
string='Contract lines',
|
||||
comodel_name='contract.line',
|
||||
inverse_name='contract_id',
|
||||
string="Contract lines",
|
||||
comodel_name="contract.line",
|
||||
inverse_name="contract_id",
|
||||
copy=True,
|
||||
)
|
||||
|
||||
user_id = fields.Many2one(
|
||||
comodel_name='res.users',
|
||||
string='Responsible',
|
||||
comodel_name="res.users",
|
||||
string="Responsible",
|
||||
index=True,
|
||||
default=lambda self: self.env.user,
|
||||
)
|
||||
create_invoice_visibility = fields.Boolean(
|
||||
compute='_compute_create_invoice_visibility'
|
||||
compute="_compute_create_invoice_visibility"
|
||||
)
|
||||
recurring_next_date = fields.Date(
|
||||
compute='_compute_recurring_next_date',
|
||||
string='Date of Next Invoice',
|
||||
compute="_compute_recurring_next_date",
|
||||
string="Date of Next Invoice",
|
||||
store=True,
|
||||
)
|
||||
date_end = fields.Date(
|
||||
compute='_compute_date_end', string='Date End', store=True
|
||||
)
|
||||
date_end = fields.Date(compute="_compute_date_end", string="Date End", store=True)
|
||||
payment_term_id = fields.Many2one(
|
||||
comodel_name='account.payment.term', string='Payment Terms', index=True
|
||||
comodel_name="account.payment.term", string="Payment Terms", index=True
|
||||
)
|
||||
invoice_count = fields.Integer(compute="_compute_invoice_count")
|
||||
fiscal_position_id = fields.Many2one(
|
||||
comodel_name='account.fiscal.position',
|
||||
string='Fiscal Position',
|
||||
ondelete='restrict',
|
||||
comodel_name="account.fiscal.position",
|
||||
string="Fiscal Position",
|
||||
ondelete="restrict",
|
||||
)
|
||||
invoice_partner_id = fields.Many2one(
|
||||
string="Invoicing contact",
|
||||
comodel_name='res.partner',
|
||||
ondelete='restrict',
|
||||
string="Invoicing contact", comodel_name="res.partner", ondelete="restrict",
|
||||
)
|
||||
partner_id = fields.Many2one(
|
||||
comodel_name='res.partner',
|
||||
inverse='_inverse_partner_id',
|
||||
required=True
|
||||
comodel_name="res.partner", inverse="_inverse_partner_id", required=True
|
||||
)
|
||||
|
||||
commercial_partner_id = fields.Many2one(
|
||||
'res.partner',
|
||||
"res.partner",
|
||||
compute_sudo=True,
|
||||
related='partner_id.commercial_partner_id',
|
||||
related="partner_id.commercial_partner_id",
|
||||
store=True,
|
||||
string='Commercial Entity',
|
||||
index=True
|
||||
string="Commercial Entity",
|
||||
index=True,
|
||||
)
|
||||
tag_ids = fields.Many2many(comodel_name="contract.tag", string="Tags")
|
||||
note = fields.Text(string="Notes")
|
||||
is_terminated = fields.Boolean(
|
||||
string="Terminated", readonly=True, copy=False
|
||||
)
|
||||
is_terminated = fields.Boolean(string="Terminated", readonly=True, copy=False)
|
||||
terminate_reason_id = fields.Many2one(
|
||||
comodel_name="contract.terminate.reason",
|
||||
string="Termination Reason",
|
||||
@@ -127,55 +110,40 @@ class ContractContract(models.Model):
|
||||
def _inverse_partner_id(self):
|
||||
for rec in self:
|
||||
if not rec.invoice_partner_id:
|
||||
rec.invoice_partner_id = rec.partner_id.address_get(
|
||||
['invoice']
|
||||
)['invoice']
|
||||
rec.invoice_partner_id = rec.partner_id.address_get(["invoice"])[
|
||||
"invoice"
|
||||
]
|
||||
|
||||
@api.multi
|
||||
def _get_related_invoices(self):
|
||||
self.ensure_one()
|
||||
|
||||
invoices = (
|
||||
self.env['account.invoice.line']
|
||||
.search(
|
||||
[
|
||||
(
|
||||
'contract_line_id',
|
||||
'in',
|
||||
self.contract_line_ids.ids,
|
||||
self.env["account.invoice.line"]
|
||||
.search([("contract_line_id", "in", self.contract_line_ids.ids,)])
|
||||
.mapped("invoice_id")
|
||||
)
|
||||
]
|
||||
)
|
||||
.mapped('invoice_id')
|
||||
)
|
||||
invoices |= self.env['account.invoice'].search(
|
||||
[('old_contract_id', '=', self.id)]
|
||||
invoices |= self.env["account.invoice"].search(
|
||||
[("old_contract_id", "=", self.id)]
|
||||
)
|
||||
return invoices
|
||||
|
||||
def _get_computed_currency(self):
|
||||
"""Helper method for returning the theoretical computed currency."""
|
||||
self.ensure_one()
|
||||
currency = self.env['res.currency']
|
||||
if any(self.contract_line_ids.mapped('automatic_price')):
|
||||
currency = self.env["res.currency"]
|
||||
if any(self.contract_line_ids.mapped("automatic_price")):
|
||||
# Use pricelist currency
|
||||
currency = (
|
||||
self.pricelist_id.currency_id or
|
||||
self.partner_id.with_context(
|
||||
self.pricelist_id.currency_id
|
||||
or self.partner_id.with_context(
|
||||
force_company=self.company_id.id,
|
||||
).property_product_pricelist.currency_id
|
||||
)
|
||||
return (
|
||||
currency or self.journal_id.currency_id or
|
||||
self.company_id.currency_id
|
||||
)
|
||||
return currency or self.journal_id.currency_id or self.company_id.currency_id
|
||||
|
||||
@api.depends(
|
||||
"manual_currency_id",
|
||||
"pricelist_id",
|
||||
"partner_id",
|
||||
"journal_id",
|
||||
"company_id",
|
||||
"manual_currency_id", "pricelist_id", "partner_id", "journal_id", "company_id",
|
||||
)
|
||||
def _compute_currency_id(self):
|
||||
for rec in self:
|
||||
@@ -203,60 +171,60 @@ class ContractContract(models.Model):
|
||||
def action_show_invoices(self):
|
||||
self.ensure_one()
|
||||
tree_view_ref = (
|
||||
'account.invoice_supplier_tree'
|
||||
if self.contract_type == 'purchase'
|
||||
else 'account.invoice_tree_with_onboarding'
|
||||
"account.invoice_supplier_tree"
|
||||
if self.contract_type == "purchase"
|
||||
else "account.invoice_tree_with_onboarding"
|
||||
)
|
||||
form_view_ref = (
|
||||
'account.invoice_supplier_form'
|
||||
if self.contract_type == 'purchase'
|
||||
else 'account.invoice_form'
|
||||
"account.invoice_supplier_form"
|
||||
if self.contract_type == "purchase"
|
||||
else "account.invoice_form"
|
||||
)
|
||||
tree_view = self.env.ref(tree_view_ref, raise_if_not_found=False)
|
||||
form_view = self.env.ref(form_view_ref, raise_if_not_found=False)
|
||||
action = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Invoices',
|
||||
'res_model': 'account.invoice',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,kanban,form,calendar,pivot,graph,activity',
|
||||
'domain': [('id', 'in', self._get_related_invoices().ids)],
|
||||
"type": "ir.actions.act_window",
|
||||
"name": "Invoices",
|
||||
"res_model": "account.invoice",
|
||||
"view_type": "form",
|
||||
"view_mode": "tree,kanban,form,calendar,pivot,graph,activity",
|
||||
"domain": [("id", "in", self._get_related_invoices().ids)],
|
||||
}
|
||||
if tree_view and form_view:
|
||||
action['views'] = [(tree_view.id, 'tree'), (form_view.id, 'form')]
|
||||
action["views"] = [(tree_view.id, "tree"), (form_view.id, "form")]
|
||||
return action
|
||||
|
||||
@api.depends('contract_line_ids.date_end')
|
||||
@api.depends("contract_line_ids.date_end")
|
||||
def _compute_date_end(self):
|
||||
for contract in self:
|
||||
contract.date_end = False
|
||||
date_end = contract.contract_line_ids.mapped('date_end')
|
||||
date_end = contract.contract_line_ids.mapped("date_end")
|
||||
if date_end and all(date_end):
|
||||
contract.date_end = max(date_end)
|
||||
|
||||
@api.depends(
|
||||
'contract_line_ids.recurring_next_date',
|
||||
'contract_line_ids.is_canceled',
|
||||
"contract_line_ids.recurring_next_date", "contract_line_ids.is_canceled",
|
||||
)
|
||||
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))
|
||||
).mapped('recurring_next_date')
|
||||
lambda l: (
|
||||
l.recurring_next_date
|
||||
and not l.is_canceled
|
||||
and (not l.display_type or l.is_recurring_note)
|
||||
)
|
||||
).mapped("recurring_next_date")
|
||||
if recurring_next_date:
|
||||
contract.recurring_next_date = min(recurring_next_date)
|
||||
|
||||
@api.depends('contract_line_ids.create_invoice_visibility')
|
||||
@api.depends("contract_line_ids.create_invoice_visibility")
|
||||
def _compute_create_invoice_visibility(self):
|
||||
for contract in self:
|
||||
contract.create_invoice_visibility = any(
|
||||
contract.contract_line_ids.mapped(
|
||||
'create_invoice_visibility'
|
||||
)
|
||||
contract.contract_line_ids.mapped("create_invoice_visibility")
|
||||
)
|
||||
|
||||
@api.onchange('contract_template_id')
|
||||
@api.onchange("contract_template_id")
|
||||
def _onchange_contract_template_id(self):
|
||||
"""Update the contract fields with that of the template.
|
||||
|
||||
@@ -269,7 +237,7 @@ class ContractContract(models.Model):
|
||||
if not contract_template_id:
|
||||
return
|
||||
for field_name, field in contract_template_id._fields.items():
|
||||
if field.name == 'contract_line_ids':
|
||||
if field.name == "contract_line_ids":
|
||||
lines = self._convert_contract_lines(contract_template_id)
|
||||
self.contract_line_ids += lines
|
||||
elif not any(
|
||||
@@ -285,7 +253,7 @@ class ContractContract(models.Model):
|
||||
if self.contract_template_id[field_name]:
|
||||
self[field_name] = self.contract_template_id[field_name]
|
||||
|
||||
@api.onchange('partner_id', 'company_id')
|
||||
@api.onchange("partner_id", "company_id")
|
||||
def _onchange_partner_id(self):
|
||||
partner = (
|
||||
self.partner_id
|
||||
@@ -294,21 +262,19 @@ class ContractContract(models.Model):
|
||||
)
|
||||
self.pricelist_id = partner.property_product_pricelist.id
|
||||
self.fiscal_position_id = partner.env[
|
||||
'account.fiscal.position'
|
||||
"account.fiscal.position"
|
||||
].get_fiscal_position(partner.id)
|
||||
if self.contract_type == 'purchase':
|
||||
if self.contract_type == "purchase":
|
||||
self.payment_term_id = partner.property_supplier_payment_term_id
|
||||
else:
|
||||
self.payment_term_id = partner.property_payment_term_id
|
||||
self.invoice_partner_id = self.partner_id.address_get(['invoice'])[
|
||||
'invoice'
|
||||
]
|
||||
self.invoice_partner_id = self.partner_id.address_get(["invoice"])["invoice"]
|
||||
return {
|
||||
'domain': {
|
||||
'invoice_partner_id': [
|
||||
'|',
|
||||
('id', 'parent_of', self.partner_id.id),
|
||||
('id', 'child_of', self.partner_id.id),
|
||||
"domain": {
|
||||
"invoice_partner_id": [
|
||||
"|",
|
||||
("id", "parent_of", self.partner_id.id),
|
||||
("id", "child_of", self.partner_id.id),
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -316,16 +282,14 @@ class ContractContract(models.Model):
|
||||
@api.multi
|
||||
def _convert_contract_lines(self, contract):
|
||||
self.ensure_one()
|
||||
new_lines = self.env['contract.line']
|
||||
contract_line_model = self.env['contract.line']
|
||||
new_lines = self.env["contract.line"]
|
||||
contract_line_model = self.env["contract.line"]
|
||||
for contract_line in contract.contract_line_ids:
|
||||
vals = contract_line._convert_to_write(contract_line.read()[0])
|
||||
# Remove template link field
|
||||
vals.pop('contract_template_id', False)
|
||||
vals['date_start'] = fields.Date.context_today(contract_line)
|
||||
vals['recurring_next_date'] = fields.Date.context_today(
|
||||
contract_line
|
||||
)
|
||||
vals.pop("contract_template_id", False)
|
||||
vals["date_start"] = fields.Date.context_today(contract_line)
|
||||
vals["recurring_next_date"] = fields.Date.context_today(contract_line)
|
||||
new_lines += contract_line_model.new(vals)
|
||||
new_lines._onchange_date_start()
|
||||
new_lines._onchange_is_auto_renew()
|
||||
@@ -338,10 +302,10 @@ class ContractContract(models.Model):
|
||||
journal = (
|
||||
self.journal_id
|
||||
if self.journal_id.type == self.contract_type
|
||||
else self.env['account.journal'].search(
|
||||
else self.env["account.journal"].search(
|
||||
[
|
||||
('type', '=', self.contract_type),
|
||||
('company_id', '=', self.company_id.id),
|
||||
("type", "=", self.contract_type),
|
||||
("company_id", "=", self.company_id.id),
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
@@ -349,56 +313,62 @@ class ContractContract(models.Model):
|
||||
if not journal:
|
||||
raise ValidationError(
|
||||
_("Please define a %s journal for the company '%s'.")
|
||||
% (self.contract_type, self.company_id.name or '')
|
||||
% (self.contract_type, self.company_id.name or "")
|
||||
)
|
||||
invoice_type = "out_invoice"
|
||||
if self.contract_type == "purchase":
|
||||
invoice_type = "in_invoice"
|
||||
vinvoice = (
|
||||
self.env["account.invoice"]
|
||||
.with_context(force_company=self.company_id.id,)
|
||||
.new(
|
||||
{
|
||||
"company_id": self.company_id.id,
|
||||
"partner_id": self.invoice_partner_id.id,
|
||||
"type": invoice_type,
|
||||
}
|
||||
)
|
||||
)
|
||||
invoice_type = 'out_invoice'
|
||||
if self.contract_type == 'purchase':
|
||||
invoice_type = 'in_invoice'
|
||||
vinvoice = self.env['account.invoice'].with_context(
|
||||
force_company=self.company_id.id,
|
||||
).new({
|
||||
'company_id': self.company_id.id,
|
||||
'partner_id': self.invoice_partner_id.id,
|
||||
'type': invoice_type,
|
||||
})
|
||||
vinvoice._onchange_partner_id()
|
||||
invoice_vals = vinvoice._convert_to_write(vinvoice._cache)
|
||||
invoice_vals.update({
|
||||
'name': self.code,
|
||||
'currency_id': self.currency_id.id,
|
||||
'date_invoice': date_invoice,
|
||||
'journal_id': journal.id,
|
||||
'origin': self.name,
|
||||
'user_id': self.user_id.id,
|
||||
})
|
||||
invoice_vals.update(
|
||||
{
|
||||
"name": self.code,
|
||||
"currency_id": self.currency_id.id,
|
||||
"date_invoice": date_invoice,
|
||||
"journal_id": journal.id,
|
||||
"origin": self.name,
|
||||
"user_id": self.user_id.id,
|
||||
}
|
||||
)
|
||||
if self.payment_term_id:
|
||||
invoice_vals['payment_term_id'] = self.payment_term_id.id
|
||||
invoice_vals["payment_term_id"] = self.payment_term_id.id
|
||||
if self.fiscal_position_id:
|
||||
invoice_vals['fiscal_position_id'] = self.fiscal_position_id.id
|
||||
invoice_vals["fiscal_position_id"] = self.fiscal_position_id.id
|
||||
return invoice_vals
|
||||
|
||||
@api.multi
|
||||
def action_contract_send(self):
|
||||
self.ensure_one()
|
||||
template = self.env.ref('contract.email_contract_template', False)
|
||||
compose_form = self.env.ref('mail.email_compose_message_wizard_form')
|
||||
template = self.env.ref("contract.email_contract_template", False)
|
||||
compose_form = self.env.ref("mail.email_compose_message_wizard_form")
|
||||
ctx = dict(
|
||||
default_model='contract.contract',
|
||||
default_model="contract.contract",
|
||||
default_res_id=self.id,
|
||||
default_use_template=bool(template),
|
||||
default_template_id=template and template.id or False,
|
||||
default_composition_mode='comment',
|
||||
default_composition_mode="comment",
|
||||
)
|
||||
return {
|
||||
'name': _('Compose Email'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.compose.message',
|
||||
'views': [(compose_form.id, 'form')],
|
||||
'view_id': compose_form.id,
|
||||
'target': 'new',
|
||||
'context': ctx,
|
||||
"name": _("Compose Email"),
|
||||
"type": "ir.actions.act_window",
|
||||
"view_type": "form",
|
||||
"view_mode": "form",
|
||||
"res_model": "mail.compose.message",
|
||||
"views": [(compose_form.id, "form")],
|
||||
"view_id": compose_form.id,
|
||||
"target": "new",
|
||||
"context": ctx,
|
||||
}
|
||||
|
||||
@api.model
|
||||
@@ -430,10 +400,8 @@ class ContractContract(models.Model):
|
||||
final_invoices_values = []
|
||||
# TODO: This call must be removed in >=13.0
|
||||
for invoice_values in invoices_values:
|
||||
final_invoices_values.append(
|
||||
self._finalize_invoice_values(invoice_values)
|
||||
)
|
||||
invoices = self.env['account.invoice'].create(final_invoices_values)
|
||||
final_invoices_values.append(self._finalize_invoice_values(invoice_values))
|
||||
invoices = self.env["account.invoice"].create(final_invoices_values)
|
||||
self._finalize_invoice_creation(invoices)
|
||||
return invoices
|
||||
|
||||
@@ -448,7 +416,7 @@ class ContractContract(models.Model):
|
||||
domain = []
|
||||
if not date_ref:
|
||||
date_ref = fields.Date.context_today(self)
|
||||
domain.extend([('recurring_next_date', '<=', date_ref)])
|
||||
domain.extend([("recurring_next_date", "<=", date_ref)])
|
||||
return domain
|
||||
|
||||
@api.multi
|
||||
@@ -462,16 +430,18 @@ class ContractContract(models.Model):
|
||||
self.ensure_one()
|
||||
|
||||
def can_be_invoiced(l):
|
||||
return (not l.is_canceled and l.recurring_next_date
|
||||
and l.recurring_next_date <= date_ref)
|
||||
return (
|
||||
not l.is_canceled
|
||||
and l.recurring_next_date
|
||||
and l.recurring_next_date <= date_ref
|
||||
)
|
||||
|
||||
lines2invoice = previous = self.env['contract.line']
|
||||
lines2invoice = previous = self.env["contract.line"]
|
||||
current_section = current_note = False
|
||||
for line in self.contract_line_ids:
|
||||
if line.display_type == 'line_section':
|
||||
if line.display_type == "line_section":
|
||||
current_section = line
|
||||
elif (line.display_type == 'line_note' and
|
||||
not line.is_recurring_note):
|
||||
elif line.display_type == "line_note" and not line.is_recurring_note:
|
||||
if line.note_invoicing_mode == "with_previous_line":
|
||||
if previous in lines2invoice:
|
||||
lines2invoice |= line
|
||||
@@ -511,12 +481,12 @@ class ContractContract(models.Model):
|
||||
continue
|
||||
invoice_values = contract._prepare_invoice(date_ref)
|
||||
for line in contract_lines:
|
||||
invoice_values.setdefault('invoice_line_ids', [])
|
||||
invoice_values.setdefault("invoice_line_ids", [])
|
||||
invoice_line_values = line._prepare_invoice_line(
|
||||
invoice_values=invoice_values,
|
||||
)
|
||||
if invoice_line_values:
|
||||
invoice_values['invoice_line_ids'].append(
|
||||
invoice_values["invoice_line_ids"].append(
|
||||
(0, 0, invoice_line_values)
|
||||
)
|
||||
invoices_values.append(invoice_values)
|
||||
@@ -533,9 +503,9 @@ class ContractContract(models.Model):
|
||||
if invoice:
|
||||
self.message_post(
|
||||
body=_(
|
||||
'Contract manually invoiced: '
|
||||
"Contract manually invoiced: "
|
||||
'<a href="#" data-oe-model="%s" data-oe-id="%s">Invoice'
|
||||
'</a>'
|
||||
"</a>"
|
||||
)
|
||||
% (invoice._name, invoice.id)
|
||||
)
|
||||
@@ -566,13 +536,13 @@ class ContractContract(models.Model):
|
||||
self.ensure_one()
|
||||
context = {"default_contract_id": self.id}
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _('Terminate Contract'),
|
||||
'res_model': 'contract.contract.terminate',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': context,
|
||||
"type": "ir.actions.act_window",
|
||||
"name": _("Terminate Contract"),
|
||||
"res_model": "contract.contract.terminate",
|
||||
"view_type": "form",
|
||||
"view_mode": "form",
|
||||
"target": "new",
|
||||
"context": context,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
@@ -581,22 +551,26 @@ class ContractContract(models.Model):
|
||||
):
|
||||
self.ensure_one()
|
||||
if not self.env.user.has_group("contract.can_terminate_contract"):
|
||||
raise UserError(_('You are not allowed to terminate contracts.'))
|
||||
self.contract_line_ids.filtered('is_stop_allowed').stop(terminate_date)
|
||||
self.write({
|
||||
'is_terminated': True,
|
||||
'terminate_reason_id': terminate_reason_id.id,
|
||||
'terminate_comment': terminate_comment,
|
||||
'terminate_date': terminate_date,
|
||||
})
|
||||
raise UserError(_("You are not allowed to terminate contracts."))
|
||||
self.contract_line_ids.filtered("is_stop_allowed").stop(terminate_date)
|
||||
self.write(
|
||||
{
|
||||
"is_terminated": True,
|
||||
"terminate_reason_id": terminate_reason_id.id,
|
||||
"terminate_comment": terminate_comment,
|
||||
"terminate_date": terminate_date,
|
||||
}
|
||||
)
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def action_cancel_contract_termination(self):
|
||||
self.ensure_one()
|
||||
self.write({
|
||||
'is_terminated': False,
|
||||
'terminate_reason_id': False,
|
||||
'terminate_comment': False,
|
||||
'terminate_date': False,
|
||||
})
|
||||
self.write(
|
||||
{
|
||||
"is_terminated": False,
|
||||
"terminate_reason_id": False,
|
||||
"terminate_comment": False,
|
||||
"terminate_date": False,
|
||||
}
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,17 +3,18 @@
|
||||
|
||||
import itertools
|
||||
from collections import namedtuple
|
||||
|
||||
from odoo.fields import Date
|
||||
|
||||
Criteria = namedtuple(
|
||||
'Criteria',
|
||||
"Criteria",
|
||||
[
|
||||
'when', # Contract line relatively to today (BEFORE, IN, AFTER)
|
||||
'has_date_end', # Is date_end set on contract line (bool)
|
||||
'has_last_date_invoiced', # Is last_date_invoiced set on contract line
|
||||
'is_auto_renew', # Is is_auto_renew set on contract line (bool)
|
||||
'has_successor', # Is contract line has_successor (bool)
|
||||
'predecessor_has_successor',
|
||||
"when", # Contract line relatively to today (BEFORE, IN, AFTER)
|
||||
"has_date_end", # Is date_end set on contract line (bool)
|
||||
"has_last_date_invoiced", # Is last_date_invoiced set on contract line
|
||||
"is_auto_renew", # Is is_auto_renew set on contract line (bool)
|
||||
"has_successor", # Is contract line has_successor (bool)
|
||||
"predecessor_has_successor",
|
||||
# Is contract line predecessor has successor (bool)
|
||||
# In almost of the cases
|
||||
# contract_line.predecessor.successor == contract_line
|
||||
@@ -23,12 +24,11 @@ Criteria = namedtuple(
|
||||
# If contract_line.predecessor.successor != False
|
||||
# and contract_line is canceled, we don't allow uncancel
|
||||
# else we re-link contract_line and its predecessor
|
||||
'canceled', # Is contract line canceled (bool)
|
||||
"canceled", # Is contract line canceled (bool)
|
||||
],
|
||||
)
|
||||
Allowed = namedtuple(
|
||||
'Allowed',
|
||||
['plan_successor', 'stop_plan_successor', 'stop', 'cancel', 'uncancel'],
|
||||
"Allowed", ["plan_successor", "stop_plan_successor", "stop", "cancel", "uncancel"],
|
||||
)
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ def _expand_none(criteria):
|
||||
variations = []
|
||||
for attribute, value in criteria._asdict().items():
|
||||
if value is None:
|
||||
if attribute == 'when':
|
||||
variations.append(['BEFORE', 'IN', 'AFTER'])
|
||||
if attribute == "when":
|
||||
variations.append(["BEFORE", "IN", "AFTER"])
|
||||
else:
|
||||
variations.append([True, False])
|
||||
else:
|
||||
@@ -53,7 +53,7 @@ def _add(matrix, criteria, allowed):
|
||||
|
||||
CRITERIA_ALLOWED_DICT = {
|
||||
Criteria(
|
||||
when='BEFORE',
|
||||
when="BEFORE",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=False,
|
||||
is_auto_renew=True,
|
||||
@@ -68,7 +68,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='BEFORE',
|
||||
when="BEFORE",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=False,
|
||||
is_auto_renew=False,
|
||||
@@ -83,7 +83,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='BEFORE',
|
||||
when="BEFORE",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=False,
|
||||
is_auto_renew=False,
|
||||
@@ -98,7 +98,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='BEFORE',
|
||||
when="BEFORE",
|
||||
has_date_end=False,
|
||||
has_last_date_invoiced=False,
|
||||
is_auto_renew=False,
|
||||
@@ -113,7 +113,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='IN',
|
||||
when="IN",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=False,
|
||||
is_auto_renew=True,
|
||||
@@ -128,7 +128,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='IN',
|
||||
when="IN",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=False,
|
||||
is_auto_renew=False,
|
||||
@@ -143,7 +143,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='IN',
|
||||
when="IN",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=False,
|
||||
is_auto_renew=False,
|
||||
@@ -158,7 +158,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='IN',
|
||||
when="IN",
|
||||
has_date_end=False,
|
||||
has_last_date_invoiced=False,
|
||||
is_auto_renew=False,
|
||||
@@ -173,7 +173,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='BEFORE',
|
||||
when="BEFORE",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=True,
|
||||
is_auto_renew=True,
|
||||
@@ -188,7 +188,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='BEFORE',
|
||||
when="BEFORE",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=True,
|
||||
is_auto_renew=False,
|
||||
@@ -203,7 +203,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='BEFORE',
|
||||
when="BEFORE",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=True,
|
||||
is_auto_renew=False,
|
||||
@@ -218,7 +218,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='BEFORE',
|
||||
when="BEFORE",
|
||||
has_date_end=False,
|
||||
has_last_date_invoiced=True,
|
||||
is_auto_renew=False,
|
||||
@@ -233,7 +233,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='IN',
|
||||
when="IN",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=True,
|
||||
is_auto_renew=True,
|
||||
@@ -248,7 +248,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='IN',
|
||||
when="IN",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=True,
|
||||
is_auto_renew=False,
|
||||
@@ -263,7 +263,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='IN',
|
||||
when="IN",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=True,
|
||||
is_auto_renew=False,
|
||||
@@ -278,7 +278,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='IN',
|
||||
when="IN",
|
||||
has_date_end=False,
|
||||
has_last_date_invoiced=True,
|
||||
is_auto_renew=False,
|
||||
@@ -293,7 +293,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='AFTER',
|
||||
when="AFTER",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=None,
|
||||
is_auto_renew=True,
|
||||
@@ -308,7 +308,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='AFTER',
|
||||
when="AFTER",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=None,
|
||||
is_auto_renew=False,
|
||||
@@ -323,7 +323,7 @@ CRITERIA_ALLOWED_DICT = {
|
||||
uncancel=False,
|
||||
),
|
||||
Criteria(
|
||||
when='AFTER',
|
||||
when="AFTER",
|
||||
has_date_end=True,
|
||||
has_last_date_invoiced=None,
|
||||
is_auto_renew=False,
|
||||
@@ -377,10 +377,10 @@ for c in CRITERIA_ALLOWED_DICT:
|
||||
def compute_when(date_start, date_end):
|
||||
today = Date.today()
|
||||
if today < date_start:
|
||||
return 'BEFORE'
|
||||
return "BEFORE"
|
||||
if date_end and today > date_end:
|
||||
return 'AFTER'
|
||||
return 'IN'
|
||||
return "AFTER"
|
||||
return "IN"
|
||||
|
||||
|
||||
def compute_criteria(
|
||||
|
||||
@@ -6,12 +6,10 @@ from odoo import fields, models
|
||||
|
||||
class ContractTag(models.Model):
|
||||
|
||||
_name = 'contract.tag'
|
||||
_description = 'Contract Tag'
|
||||
_name = "contract.tag"
|
||||
_description = "Contract Tag"
|
||||
|
||||
name = fields.Char(requirment=True)
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
string='Company',
|
||||
default=lambda self: self.env.user.company_id,
|
||||
"res.company", string="Company", default=lambda self: self.env.user.company_id,
|
||||
)
|
||||
|
||||
@@ -10,13 +10,13 @@ from odoo import fields, models
|
||||
|
||||
|
||||
class ContractTemplate(models.Model):
|
||||
_name = 'contract.template'
|
||||
_inherit = 'contract.abstract.contract'
|
||||
_name = "contract.template"
|
||||
_inherit = "contract.abstract.contract"
|
||||
_description = "Contract Template"
|
||||
|
||||
contract_line_ids = fields.One2many(
|
||||
comodel_name='contract.template.line',
|
||||
inverse_name='contract_id',
|
||||
comodel_name="contract.template.line",
|
||||
inverse_name="contract_id",
|
||||
copy=True,
|
||||
string='Contract template lines',
|
||||
string="Contract template lines",
|
||||
)
|
||||
|
||||
@@ -10,15 +10,15 @@ from odoo import fields, models
|
||||
|
||||
|
||||
class ContractTemplateLine(models.Model):
|
||||
_name = 'contract.template.line'
|
||||
_inherit = 'contract.abstract.contract.line'
|
||||
_name = "contract.template.line"
|
||||
_inherit = "contract.abstract.contract.line"
|
||||
_description = "Contract Template Line"
|
||||
_order = "sequence,id"
|
||||
|
||||
contract_id = fields.Many2one(
|
||||
string='Contract',
|
||||
comodel_name='contract.template',
|
||||
string="Contract",
|
||||
comodel_name="contract.template",
|
||||
required=True,
|
||||
ondelete='cascade',
|
||||
oldname='analytic_account_id',
|
||||
ondelete="cascade",
|
||||
oldname="analytic_account_id",
|
||||
)
|
||||
|
||||
@@ -6,8 +6,8 @@ from odoo import fields, models
|
||||
|
||||
class ContractTerminateReason(models.Model):
|
||||
|
||||
_name = 'contract.terminate.reason'
|
||||
_description = 'Contract Termination Reason'
|
||||
_name = "contract.terminate.reason"
|
||||
_description = "Contract Termination Reason"
|
||||
|
||||
name = fields.Char(required=True)
|
||||
terminate_comment_required = fields.Boolean(
|
||||
|
||||
@@ -13,7 +13,9 @@ class IrUiView(models.Model):
|
||||
# TODO Delete this method in v13; it's upstream there
|
||||
result = super()._prepare_qcontext()
|
||||
if self.env.context.get("allowed_company_ids"):
|
||||
result["res_company"] = self.env["res.company"].browse(
|
||||
self.env.context["allowed_company_ids"][0]
|
||||
).sudo()
|
||||
result["res_company"] = (
|
||||
self.env["res.company"]
|
||||
.browse(self.env.context["allowed_company_ids"][0])
|
||||
.sudo()
|
||||
)
|
||||
return result
|
||||
|
||||
@@ -6,7 +6,7 @@ from odoo import fields, models
|
||||
|
||||
class ResCompany(models.Model):
|
||||
|
||||
_inherit = 'res.company'
|
||||
_inherit = "res.company"
|
||||
|
||||
create_new_line_at_contract_line_renew = fields.Boolean(
|
||||
string="Create New Line At Contract Line Renew",
|
||||
|
||||
@@ -6,7 +6,7 @@ from odoo import fields, models
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
|
||||
_inherit = 'res.config.settings'
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
create_new_line_at_contract_line_renew = fields.Boolean(
|
||||
related="company_id.create_new_line_at_contract_line_renew",
|
||||
|
||||
@@ -5,45 +5,49 @@ from odoo import fields, models
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
_inherit = "res.partner"
|
||||
|
||||
sale_contract_count = fields.Integer(
|
||||
string='Sale Contracts',
|
||||
compute='_compute_contract_count',
|
||||
string="Sale Contracts", compute="_compute_contract_count",
|
||||
)
|
||||
purchase_contract_count = fields.Integer(
|
||||
string='Purchase Contracts',
|
||||
compute='_compute_contract_count',
|
||||
string="Purchase Contracts", compute="_compute_contract_count",
|
||||
)
|
||||
contract_ids = fields.One2many(
|
||||
comodel_name='contract.contract',
|
||||
inverse='partner_id',
|
||||
string="Contracts",
|
||||
comodel_name="contract.contract", inverse="partner_id", string="Contracts",
|
||||
)
|
||||
|
||||
def _compute_contract_count(self):
|
||||
contract_model = self.env['contract.contract']
|
||||
fetch_data = contract_model.read_group([
|
||||
('partner_id', 'child_of', self.ids)],
|
||||
['partner_id', 'contract_type'], ['partner_id', 'contract_type'],
|
||||
lazy=False)
|
||||
result = [[data['partner_id'][0], data['contract_type'],
|
||||
data['__count']] for data in fetch_data]
|
||||
contract_model = self.env["contract.contract"]
|
||||
fetch_data = contract_model.read_group(
|
||||
[("partner_id", "child_of", self.ids)],
|
||||
["partner_id", "contract_type"],
|
||||
["partner_id", "contract_type"],
|
||||
lazy=False,
|
||||
)
|
||||
result = [
|
||||
[data["partner_id"][0], data["contract_type"], data["__count"]]
|
||||
for data in fetch_data
|
||||
]
|
||||
for partner in self:
|
||||
partner_child_ids = partner.child_ids.ids + partner.ids
|
||||
partner.sale_contract_count = sum([
|
||||
r[2] for r in result
|
||||
if r[0] in partner_child_ids and r[1] == 'sale'])
|
||||
partner.purchase_contract_count = sum([
|
||||
r[2] for r in result
|
||||
if r[0] in partner_child_ids and r[1] == 'purchase'])
|
||||
partner.sale_contract_count = sum(
|
||||
[r[2] for r in result if r[0] in partner_child_ids and r[1] == "sale"]
|
||||
)
|
||||
partner.purchase_contract_count = sum(
|
||||
[
|
||||
r[2]
|
||||
for r in result
|
||||
if r[0] in partner_child_ids and r[1] == "purchase"
|
||||
]
|
||||
)
|
||||
|
||||
def act_show_contract(self):
|
||||
""" This opens contract view
|
||||
@return: the contract view
|
||||
"""
|
||||
self.ensure_one()
|
||||
contract_type = self._context.get('contract_type')
|
||||
contract_type = self._context.get("contract_type")
|
||||
|
||||
res = self._get_act_window_contract_xml(contract_type)
|
||||
res.update(
|
||||
@@ -57,11 +61,11 @@ class ResPartner(models.Model):
|
||||
return res
|
||||
|
||||
def _get_act_window_contract_xml(self, contract_type):
|
||||
if contract_type == 'purchase':
|
||||
return self.env['ir.actions.act_window'].for_xml_id(
|
||||
'contract', 'action_supplier_contract'
|
||||
if contract_type == "purchase":
|
||||
return self.env["ir.actions.act_window"].for_xml_id(
|
||||
"contract", "action_supplier_contract"
|
||||
)
|
||||
else:
|
||||
return self.env['ir.actions.act_window'].for_xml_id(
|
||||
'contract', 'action_customer_contract'
|
||||
return self.env["ir.actions.act_window"].for_xml_id(
|
||||
"contract", "action_customer_contract"
|
||||
)
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<report
|
||||
id="report_contract"
|
||||
model="contract.contract"
|
||||
string="Contract"
|
||||
report_type="qweb-pdf"
|
||||
name="contract.report_contract_document"
|
||||
file="contract.report_contract"/>
|
||||
|
||||
file="contract.report_contract"
|
||||
/>
|
||||
</odoo>
|
||||
|
||||
@@ -1,80 +1,125 @@
|
||||
<?xml version="1.0" ?>
|
||||
<odoo>
|
||||
|
||||
<template id="report_contract_document">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-set="o" t-value="o.with_context(lang=o.partner_id.lang)" />
|
||||
<t t-set="address">
|
||||
<p id="partner_info"><strong>Partner:</strong></p>
|
||||
<div t-field="o.partner_id"
|
||||
t-options='{"widget": "contact", "fields": ["address", "name", "phone", "mobile", "fax", "email"], "no_marker": true, "phone_icons": true}'/>
|
||||
<p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
|
||||
<p id="partner_info">
|
||||
<strong>Partner:</strong>
|
||||
</p>
|
||||
<div
|
||||
t-field="o.partner_id"
|
||||
t-options='{"widget": "contact", "fields": ["address", "name", "phone", "mobile", "fax", "email"], "no_marker": true, "phone_icons": true}'
|
||||
/>
|
||||
<p t-if="o.partner_id.vat">VAT: <span
|
||||
t-field="o.partner_id.vat"
|
||||
/></p>
|
||||
</t>
|
||||
<div class="page">
|
||||
<div class="oe_structure"/>
|
||||
<div class="oe_structure" />
|
||||
<div class="row" id="header_info">
|
||||
<div class="col-3">
|
||||
<strong>Responsible: </strong><p t-field="o.user_id"/>
|
||||
<strong>Contract: </strong><p t-field="o.code"/>
|
||||
<strong>Responsible: </strong>
|
||||
<p t-field="o.user_id" />
|
||||
<strong>Contract: </strong>
|
||||
<p t-field="o.code" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="invoice_info">
|
||||
<t t-set="total" t-value="0"/>
|
||||
<t t-set="total" t-value="0" />
|
||||
<div class="col-12">
|
||||
<t t-set="total" t-value="0"/>
|
||||
<p id="services_info"><strong>Recurring Items</strong></p>
|
||||
<t t-set="total" t-value="0" />
|
||||
<p id="services_info">
|
||||
<strong>Recurring Items</strong>
|
||||
</p>
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><strong>Description</strong></th>
|
||||
<th class="text-right"><strong>Quantity</strong></th>
|
||||
<th class="text-right"><strong>Unit Price</strong></th>
|
||||
<th class="text-right"><strong>Price</strong></th>
|
||||
<th class="text-right"><strong>Date Start</strong></th>
|
||||
<th>
|
||||
<strong>Description</strong>
|
||||
</th>
|
||||
<th class="text-right">
|
||||
<strong>Quantity</strong>
|
||||
</th>
|
||||
<th class="text-right">
|
||||
<strong>Unit Price</strong>
|
||||
</th>
|
||||
<th class="text-right">
|
||||
<strong>Price</strong>
|
||||
</th>
|
||||
<th class="text-right">
|
||||
<strong>Date Start</strong>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-set="current_subtotal" t-value="0"/>
|
||||
<t t-set="current_subtotal" t-value="0" />
|
||||
<t t-foreach="o.contract_line_ids" t-as="l">
|
||||
<t t-set="current_subtotal" t-value="current_subtotal + l.price_subtotal"/>
|
||||
<tr t-att-class="'bg-200 font-weight-bold o_line_section' if l.display_type == 'line_section' else 'font-italic o_line_note' if l.display_type == 'line_note' else ''">
|
||||
<t
|
||||
t-set="current_subtotal"
|
||||
t-value="current_subtotal + l.price_subtotal"
|
||||
/>
|
||||
<tr
|
||||
t-att-class="'bg-200 font-weight-bold o_line_section' if l.display_type == 'line_section' else 'font-italic o_line_note' if l.display_type == 'line_note' else ''"
|
||||
>
|
||||
<t t-if="not l.display_type">
|
||||
<td>
|
||||
<span t-field="l.name"/>
|
||||
<span t-field="l.name" />
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-field="l.quantity"/>
|
||||
<span t-field="l.quantity" />
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-field="l.price_unit" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
|
||||
<span
|
||||
t-field="l.price_unit"
|
||||
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
|
||||
/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-field="l.price_subtotal" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
|
||||
<span
|
||||
t-field="l.price_subtotal"
|
||||
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
|
||||
/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-field="l.date_start"/>
|
||||
<span t-field="l.date_start" />
|
||||
</td>
|
||||
<t t-set="total" t-value="total + l.price_subtotal"/>
|
||||
<t
|
||||
t-set="total"
|
||||
t-value="total + l.price_subtotal"
|
||||
/>
|
||||
</t>
|
||||
<t t-if="l.display_type == 'line_section'">
|
||||
<t
|
||||
t-if="l.display_type == 'line_section'"
|
||||
>
|
||||
<td colspan="99">
|
||||
<span t-field="l.name"/>
|
||||
<span t-field="l.name" />
|
||||
</td>
|
||||
<t t-set="current_section" t-value="l"/>
|
||||
<t t-set="current_subtotal" t-value="0"/>
|
||||
<t
|
||||
t-set="current_section"
|
||||
t-value="l"
|
||||
/>
|
||||
<t
|
||||
t-set="current_subtotal"
|
||||
t-value="0"
|
||||
/>
|
||||
</t>
|
||||
<t t-if="l.display_type == 'line_note'">
|
||||
<td colspan="99">
|
||||
<span t-field="l.name"/>
|
||||
<span t-field="l.name" />
|
||||
</td>
|
||||
</t>
|
||||
</tr>
|
||||
<t t-if="current_section and (l_last or o.contract_line_ids[l_index+1].display_type == 'line_section')">
|
||||
<t
|
||||
t-if="current_section and (l_last or o.contract_line_ids[l_index+1].display_type == 'line_section')"
|
||||
>
|
||||
<tr class="is-subtotal text-right">
|
||||
<td colspan="99">
|
||||
<strong class="mr16">Subtotal</strong>
|
||||
<strong
|
||||
class="mr16"
|
||||
>Subtotal</strong>
|
||||
<span
|
||||
t-esc="current_subtotal"
|
||||
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
|
||||
@@ -91,9 +136,14 @@
|
||||
<div class="col-4 ml-auto">
|
||||
<table class="table table-sm">
|
||||
<tr class="border-black o_subtotal" style="">
|
||||
<td><strong>Total</strong></td>
|
||||
<td>
|
||||
<strong>Total</strong>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="total" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
|
||||
<span
|
||||
t-esc="total"
|
||||
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -101,10 +151,12 @@
|
||||
</div>
|
||||
<div>
|
||||
<div class="row mt-4" id="note">
|
||||
<div><strong>Notes: </strong></div>
|
||||
<div>
|
||||
<strong>Notes: </strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<p t-field="o.note"/>
|
||||
<p t-field="o.note" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -112,5 +164,4 @@
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="rule_contract_contract_multi_company" model="ir.rule">
|
||||
<field name="name">Contract contract multi-company</field>
|
||||
<field name="model_id" ref="model_contract_contract"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
|
||||
<field name="model_id" ref="model_contract_contract" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="rule_contract_line_multi_company" model="ir.rule">
|
||||
<field name="name">Contract line multi-company</field>
|
||||
<field name="model_id" ref="model_contract_line"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|', ('contract_id.company_id', '=', False), ('contract_id.company_id', 'child_of', [user.company_id.id])]</field>
|
||||
<field name="model_id" ref="model_contract_line" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|', ('contract_id.company_id', '=', False), ('contract_id.company_id', 'child_of', [user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="rule_contract_template_multi_company" model="ir.rule">
|
||||
<field name="name">Contract template multi-company</field>
|
||||
<field name="model_id" ref="model_contract_template"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
|
||||
<field name="model_id" ref="model_contract_template" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="rule_contract_template_line_multi_company" model="ir.rule">
|
||||
<field name="name">Contract template line multi-company</field>
|
||||
<field name="model_id" ref="model_contract_template_line"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|', ('contract_id.company_id', '=', False), ('contract_id.company_id', 'child_of', [user.company_id.id])]</field>
|
||||
<field name="model_id" ref="model_contract_template_line" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|', ('contract_id.company_id', '=', False), ('contract_id.company_id', 'child_of', [user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2019 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record model="ir.model.access" id="contract_tag_access">
|
||||
<field name="name">contract.tag access</field>
|
||||
<field name="model_id" ref="model_contract_tag"/>
|
||||
<field name="group_id" ref="account.group_account_invoice"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
<field name="model_id" ref="model_contract_tag" />
|
||||
<field name="group_id" ref="account.group_account_invoice" />
|
||||
<field name="perm_read" eval="1" />
|
||||
<field name="perm_create" eval="1" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
</record>
|
||||
|
||||
<record id="contract_tag_multi_company_rule" model="ir.rule">
|
||||
<field name="name">Contract tag multi-company</field>
|
||||
<field name="model_id" ref="model_contract_tag"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
|
||||
<field name="model_id" ref="model_contract_tag" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,27 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record model="ir.model.access" id="contract_terminate_reason_access_manager">
|
||||
<field name="name">contract.terminate.reason access manager</field>
|
||||
<field name="model_id" ref="model_contract_terminate_reason"/>
|
||||
<field name="group_id" ref="account.group_account_manager"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
<field name="model_id" ref="model_contract_terminate_reason" />
|
||||
<field name="group_id" ref="account.group_account_manager" />
|
||||
<field name="perm_read" eval="1" />
|
||||
<field name="perm_create" eval="1" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="contract_terminate_reason_access_user">
|
||||
<field name="name">contract.terminate.reason access user</field>
|
||||
<field name="model_id" ref="model_contract_terminate_reason"/>
|
||||
<field name="group_id" ref="account.group_account_invoice"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
<field name="model_id" ref="model_contract_terminate_reason" />
|
||||
<field name="group_id" ref="account.group_account_invoice" />
|
||||
<field name="perm_read" eval="1" />
|
||||
<field name="perm_create" eval="1" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="can_terminate_contract" model="res.groups">
|
||||
<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>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -8,31 +8,31 @@ 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) {
|
||||
odoo.define("contract.section_and_note_backend", function(require) {
|
||||
"use strict";
|
||||
|
||||
var fieldRegistry = require('web.field_registry');
|
||||
var section_and_note_one2many = fieldRegistry.get('section_and_note_one2many');
|
||||
var fieldRegistry = require("web.field_registry");
|
||||
var section_and_note_one2many = fieldRegistry.get("section_and_note_one2many");
|
||||
|
||||
section_and_note_one2many.include({
|
||||
_getRenderer: function () {
|
||||
_getRenderer: function() {
|
||||
var result = this._super.apply(this, arguments);
|
||||
if (this.view.arch.tag === 'tree') {
|
||||
if (this.view.arch.tag === "tree") {
|
||||
result.include({
|
||||
_renderBodyCell: function (record, node, index, options) {
|
||||
_renderBodyCell: function(record, node, index, options) {
|
||||
var $cell = this._super.apply(this, arguments);
|
||||
|
||||
var isSection = record.data.display_type === 'line_section';
|
||||
var isNote = record.data.display_type === 'line_note';
|
||||
var isSection = record.data.display_type === "line_section";
|
||||
var isNote = record.data.display_type === "line_note";
|
||||
|
||||
if (isSection || isNote) {
|
||||
$cell.removeClass('o_invisible_modifier');
|
||||
$cell.removeClass("o_invisible_modifier");
|
||||
}
|
||||
return $cell;
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
return result
|
||||
return result;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,89 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<!--FORM view-->
|
||||
<record id="contract_abstract_contract_line_form_view" model="ir.ui.view">
|
||||
<field name="name">contract.abstract.contract.line form view (in contract)</field>
|
||||
<field
|
||||
name="name"
|
||||
>contract.abstract.contract.line form view (in contract)</field>
|
||||
<field name="model">contract.abstract.contract.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="display_type" invisible="1"/>
|
||||
<header attrs="{'invisible': [('display_type', '!=', False)]}"/>
|
||||
<field name="display_type" invisible="1" />
|
||||
<header attrs="{'invisible': [('display_type', '!=', False)]}" />
|
||||
<sheet>
|
||||
<field name="specific_price" invisible="1"/>
|
||||
<group col="4" attrs="{'invisible': [('display_type', '!=', False)]}">
|
||||
<field colspan="4"
|
||||
<field name="specific_price" invisible="1" />
|
||||
<group
|
||||
col="4"
|
||||
attrs="{'invisible': [('display_type', '!=', False)]}"
|
||||
>
|
||||
<field
|
||||
colspan="4"
|
||||
name="product_id"
|
||||
attrs="{'required': [('display_type', '=', False)]}"/>
|
||||
<label for="quantity"/>
|
||||
attrs="{'required': [('display_type', '=', False)]}"
|
||||
/>
|
||||
<label for="quantity" />
|
||||
<div class="o_row">
|
||||
<field name="quantity" class="oe_inline"/>
|
||||
<field name="uom_id"
|
||||
<field name="quantity" class="oe_inline" />
|
||||
<field
|
||||
name="uom_id"
|
||||
class="oe_inline"
|
||||
groups="uom.group_uom"
|
||||
attrs="{'required': [('display_type', '=', False)]}"/>
|
||||
attrs="{'required': [('display_type', '=', False)]}"
|
||||
/>
|
||||
</div>
|
||||
<field colspan="2" name="automatic_price"/>
|
||||
<field colspan="2" name="price_unit"
|
||||
attrs="{'readonly': [('automatic_price', '=', True)]}"/>
|
||||
<field colspan="2" name="discount" groups="base.group_no_one"/>
|
||||
<field colspan="2" name="automatic_price" />
|
||||
<field
|
||||
colspan="2"
|
||||
name="price_unit"
|
||||
attrs="{'readonly': [('automatic_price', '=', True)]}"
|
||||
/>
|
||||
<field colspan="2" name="discount" groups="base.group_no_one" />
|
||||
</group>
|
||||
|
||||
<label for="name" string="Description" attrs="{'invisible': [('display_type', '!=', False)]}"/>
|
||||
<label for="name" string="Section" attrs="{'invisible': [('display_type', '!=', 'line_section')]}"/>
|
||||
<label for="name" string="Note" attrs="{'invisible': [('display_type', '!=', 'line_note')]}"/>
|
||||
<field name="name" nolabel="1"/>
|
||||
|
||||
<group name="note_invoicing_mode" attrs="{'invisible': [('display_type', '!=', 'line_note')]}">
|
||||
<field name="note_invoicing_mode" widget="radio"/>
|
||||
<label
|
||||
for="name"
|
||||
string="Description"
|
||||
attrs="{'invisible': [('display_type', '!=', False)]}"
|
||||
/>
|
||||
<label
|
||||
for="name"
|
||||
string="Section"
|
||||
attrs="{'invisible': [('display_type', '!=', 'line_section')]}"
|
||||
/>
|
||||
<label
|
||||
for="name"
|
||||
string="Note"
|
||||
attrs="{'invisible': [('display_type', '!=', 'line_note')]}"
|
||||
/>
|
||||
<field name="name" nolabel="1" />
|
||||
<group
|
||||
name="note_invoicing_mode"
|
||||
attrs="{'invisible': [('display_type', '!=', 'line_note')]}"
|
||||
>
|
||||
<field name="note_invoicing_mode" widget="radio" />
|
||||
</group>
|
||||
|
||||
<group col="4" attrs="{'invisible': [('display_type', '!=', False)]}">
|
||||
<field colspan="2" name="is_auto_renew"/>
|
||||
<field colspan="2" name="is_canceled" invisible="1"/>
|
||||
<group
|
||||
col="4"
|
||||
attrs="{'invisible': [('display_type', '!=', False)]}"
|
||||
>
|
||||
<field colspan="2" name="is_auto_renew" />
|
||||
<field colspan="2" name="is_canceled" invisible="1" />
|
||||
</group>
|
||||
<group attrs="{'invisible':['|', ('is_auto_renew', '=', False), ('display_type', '!=', False)]}">
|
||||
<group
|
||||
attrs="{'invisible':['|', ('is_auto_renew', '=', False), ('display_type', '!=', False)]}"
|
||||
>
|
||||
<group>
|
||||
<label for="auto_renew_interval"/>
|
||||
<label for="auto_renew_interval" />
|
||||
<div>
|
||||
<field name="auto_renew_interval"
|
||||
class="oe_inline" nolabel="1"
|
||||
attrs="{'required':[('is_auto_renew', '=', True)]}"/>
|
||||
<field name="auto_renew_rule_type"
|
||||
class="oe_inline" nolabel="1"
|
||||
attrs="{'required':[('is_auto_renew', '=', True)]}"/>
|
||||
<field
|
||||
name="auto_renew_interval"
|
||||
class="oe_inline"
|
||||
nolabel="1"
|
||||
attrs="{'required':[('is_auto_renew', '=', True)]}"
|
||||
/>
|
||||
<field
|
||||
name="auto_renew_rule_type"
|
||||
class="oe_inline"
|
||||
nolabel="1"
|
||||
attrs="{'required':[('is_auto_renew', '=', True)]}"
|
||||
/>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<label for="termination_notice_interval"/>
|
||||
<label for="termination_notice_interval" />
|
||||
<div>
|
||||
<field name="termination_notice_interval"
|
||||
class="oe_inline" nolabel="1"
|
||||
attrs="{'required':[('is_auto_renew', '=', True)]}"/>
|
||||
<field name="termination_notice_rule_type"
|
||||
class="oe_inline" nolabel="1"
|
||||
attrs="{'required':[('is_auto_renew', '=', True)]}"/>
|
||||
<field
|
||||
name="termination_notice_interval"
|
||||
class="oe_inline"
|
||||
nolabel="1"
|
||||
attrs="{'required':[('is_auto_renew', '=', True)]}"
|
||||
/>
|
||||
<field
|
||||
name="termination_notice_rule_type"
|
||||
class="oe_inline"
|
||||
nolabel="1"
|
||||
attrs="{'required':[('is_auto_renew', '=', True)]}"
|
||||
/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<group name="recurrence_info" attrs="{'invisible': ['|', ('display_type', '=', 'line_section'), '&', ('display_type', '=', 'line_note'), ('note_invoicing_mode', '!=', 'custom')]}">
|
||||
<group
|
||||
name="recurrence_info"
|
||||
attrs="{'invisible': ['|', ('display_type', '=', 'line_section'), '&', ('display_type', '=', 'line_note'), ('note_invoicing_mode', '!=', 'custom')]}"
|
||||
>
|
||||
<group>
|
||||
<label for="recurring_interval"/>
|
||||
<label for="recurring_interval" />
|
||||
<div class="o_row">
|
||||
<field name="recurring_interval"
|
||||
class="oe_inline" nolabel="1"/>
|
||||
<field name="recurring_rule_type"
|
||||
class="oe_inline" nolabel="1"/>
|
||||
<field
|
||||
name="recurring_interval"
|
||||
class="oe_inline"
|
||||
nolabel="1"
|
||||
/>
|
||||
<field
|
||||
name="recurring_rule_type"
|
||||
class="oe_inline"
|
||||
nolabel="1"
|
||||
/>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<field name="recurring_invoicing_type"/>
|
||||
<field name="recurring_invoicing_offset"/>
|
||||
<field name="recurring_invoicing_type" />
|
||||
<field name="recurring_invoicing_offset" />
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 Tecnativa - Ernesto Tejeda
|
||||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
<template id="assets_backend" name="contract assets" inherit_id="web.assets_backend">
|
||||
<template
|
||||
id="assets_backend"
|
||||
name="contract assets"
|
||||
inherit_id="web.assets_backend"
|
||||
>
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/contract/static/src/js/section_and_note_fields_backend.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/contract/static/src/js/section_and_note_fields_backend.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
||||
@@ -1,202 +1,317 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<!--Main FORM view-->
|
||||
<record id="contract_contract_form_view" model="ir.ui.view">
|
||||
<field name="name">contract.contract form view (in contract)</field>
|
||||
<field name="model">contract.contract</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="is_terminated" invisible="1"/>
|
||||
<div class="alert alert-danger" role="alert" style="margin-bottom:0px;" attrs="{'invisible': [('is_terminated','=',False)]}">
|
||||
<field name="is_terminated" invisible="1" />
|
||||
<div
|
||||
class="alert alert-danger"
|
||||
role="alert"
|
||||
style="margin-bottom:0px;"
|
||||
attrs="{'invisible': [('is_terminated','=',False)]}"
|
||||
>
|
||||
<p>
|
||||
This contract was terminated for the reason
|
||||
<strong>
|
||||
<field name="terminate_reason_id" options="{'no_open':True}"/>
|
||||
<field
|
||||
name="terminate_reason_id"
|
||||
options="{'no_open':True}"
|
||||
/>
|
||||
</strong>
|
||||
on
|
||||
<field name="terminate_date"/>
|
||||
<field name="terminate_date" />
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
<field name="terminate_comment"/>
|
||||
<field name="terminate_comment" />
|
||||
</p>
|
||||
</div>
|
||||
<header>
|
||||
<button name="action_contract_send"
|
||||
<button
|
||||
name="action_contract_send"
|
||||
type="object"
|
||||
string="Send by Email"
|
||||
attrs="{'invisible': [('is_terminated','=',True)]}"
|
||||
groups="base.group_user"/>
|
||||
<button name="recurring_create_invoice"
|
||||
groups="base.group_user"
|
||||
/>
|
||||
<button
|
||||
name="recurring_create_invoice"
|
||||
type="object"
|
||||
attrs="{'invisible': ['|', ('create_invoice_visibility', '=', False)]}"
|
||||
string="Create invoices"
|
||||
groups="base.group_no_one"/>
|
||||
<button name="action_terminate_contract"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
<button
|
||||
name="action_terminate_contract"
|
||||
type="object"
|
||||
string="Terminate Contract"
|
||||
attrs="{'invisible': [('is_terminated','=',True)]}"
|
||||
groups="contract.can_terminate_contract"/>
|
||||
<button name="action_terminate_contract"
|
||||
groups="contract.can_terminate_contract"
|
||||
/>
|
||||
<button
|
||||
name="action_terminate_contract"
|
||||
type="object"
|
||||
string="Update Termination Details"
|
||||
attrs="{'invisible': [('is_terminated','=',False)]}"
|
||||
groups="contract.can_terminate_contract"/>
|
||||
<button name="action_cancel_contract_termination"
|
||||
groups="contract.can_terminate_contract"
|
||||
/>
|
||||
<button
|
||||
name="action_cancel_contract_termination"
|
||||
type="object"
|
||||
confirm="Are you sure you want to re-activate this contract?"
|
||||
string="Cancel Contract Termination"
|
||||
attrs="{'invisible': [('is_terminated','=',False)]}"
|
||||
groups="contract.can_terminate_contract"/>
|
||||
groups="contract.can_terminate_contract"
|
||||
/>
|
||||
</header>
|
||||
<sheet string="Contract">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="object"
|
||||
name="toggle_active" icon="fa-archive">
|
||||
<field name="active" widget="boolean_button"
|
||||
options="{"terminology": "archive"}"/>
|
||||
<button
|
||||
class="oe_stat_button"
|
||||
type="object"
|
||||
name="toggle_active"
|
||||
icon="fa-archive"
|
||||
>
|
||||
<field
|
||||
name="active"
|
||||
widget="boolean_button"
|
||||
options="{"terminology": "archive"}"
|
||||
/>
|
||||
</button>
|
||||
<button name="action_show_invoices"
|
||||
type="object" icon="fa-list"
|
||||
class="oe_stat_button">
|
||||
<field string="Invoices"
|
||||
<button
|
||||
name="action_show_invoices"
|
||||
type="object"
|
||||
icon="fa-list"
|
||||
class="oe_stat_button"
|
||||
>
|
||||
<field
|
||||
string="Invoices"
|
||||
name="invoice_count"
|
||||
widget="statinfo"/>
|
||||
widget="statinfo"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" string="Contract Name"
|
||||
class="oe_edit_only"/>
|
||||
<label for="name" string="Contract Name" class="oe_edit_only" />
|
||||
<h3>
|
||||
<field name="name" class="oe_inline"
|
||||
<field
|
||||
name="name"
|
||||
class="oe_inline"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
placeholder="e.g. Contract XYZ"/>
|
||||
placeholder="e.g. Contract XYZ"
|
||||
/>
|
||||
</h3>
|
||||
</div>
|
||||
<group name="main">
|
||||
<group>
|
||||
<field name="commercial_partner_id" invisible="1"/>
|
||||
<field name="partner_id" required="1" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||
<field name="payment_term_id" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||
<field name="user_id" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||
<field name="commercial_partner_id" invisible="1" />
|
||||
<field
|
||||
name="partner_id"
|
||||
required="1"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
/>
|
||||
<field
|
||||
name="payment_term_id"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
/>
|
||||
<field
|
||||
name="user_id"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="contract_template_id"
|
||||
<field
|
||||
name="contract_template_id"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
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="tag_ids" widget="many2many_tags"/>
|
||||
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="tag_ids" widget="many2many_tags" />
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="recurring_invoices">
|
||||
<group>
|
||||
<field name="journal_id" required="1" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||
<field name="recurring_next_date"/>
|
||||
<field
|
||||
name="journal_id"
|
||||
required="1"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
/>
|
||||
<field name="recurring_next_date" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="pricelist_id" attrs="{'readonly': [('is_terminated','=',True)]}"/>
|
||||
<field name="date_end"/>
|
||||
<field
|
||||
name="pricelist_id"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
/>
|
||||
<field name="date_end" />
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page name="recurring_invoice_line"
|
||||
string="Recurring Invoices">
|
||||
<field name="contract_line_ids"
|
||||
<page name="recurring_invoice_line" string="Recurring Invoices">
|
||||
<field
|
||||
name="contract_line_ids"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
widget="section_and_note_one2many"
|
||||
context="{'default_contract_type': contract_type}">
|
||||
<tree decoration-muted="is_canceled"
|
||||
decoration-info="create_invoice_visibility and not is_canceled">
|
||||
context="{'default_contract_type': contract_type}"
|
||||
>
|
||||
<tree
|
||||
decoration-muted="is_canceled"
|
||||
decoration-info="create_invoice_visibility and not is_canceled"
|
||||
>
|
||||
<control>
|
||||
<create string="Add a line"/>
|
||||
<create string="Add a section" context="{'default_display_type': 'line_section'}"/>
|
||||
<create string="Add a note" context="{'default_display_type': 'line_note'}"/>
|
||||
<create string="Add a line" />
|
||||
<create
|
||||
string="Add a section"
|
||||
context="{'default_display_type': 'line_section'}"
|
||||
/>
|
||||
<create
|
||||
string="Add a note"
|
||||
context="{'default_display_type': 'line_note'}"
|
||||
/>
|
||||
</control>
|
||||
<field name="display_type" invisible="1"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="product_id"/>
|
||||
<field name="name" widget="section_and_note_text"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="analytic_tag_ids" widget="many2many_tags" groups="analytic.group_analytic_tags"/>
|
||||
<field name="quantity"/>
|
||||
<field name="uom_id"/>
|
||||
<field name="automatic_price" attrs="{'column_invisible': [('parent.contract_type', '=', 'purchase')]}"/>
|
||||
<field name="price_unit"
|
||||
attrs="{'readonly': [('automatic_price', '=', True)]}"/>
|
||||
<field name="specific_price" invisible="1"/>
|
||||
<field name="discount" groups="base.group_no_one"/>
|
||||
<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="date_end"/>
|
||||
<field name="recurring_next_date" required="1"/>
|
||||
<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"/>
|
||||
<button name="action_plan_successor"
|
||||
string="Plan Start" type="object"
|
||||
<field name="display_type" invisible="1" />
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="product_id" />
|
||||
<field name="name" widget="section_and_note_text" />
|
||||
<field
|
||||
name="analytic_account_id"
|
||||
groups="analytic.group_analytic_accounting"
|
||||
/>
|
||||
<field
|
||||
name="analytic_tag_ids"
|
||||
widget="many2many_tags"
|
||||
groups="analytic.group_analytic_tags"
|
||||
/>
|
||||
<field name="quantity" />
|
||||
<field name="uom_id" />
|
||||
<field
|
||||
name="automatic_price"
|
||||
attrs="{'column_invisible': [('parent.contract_type', '=', 'purchase')]}"
|
||||
/>
|
||||
<field
|
||||
name="price_unit"
|
||||
attrs="{'readonly': [('automatic_price', '=', True)]}"
|
||||
/>
|
||||
<field name="specific_price" invisible="1" />
|
||||
<field name="discount" groups="base.group_no_one" />
|
||||
<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="date_end" />
|
||||
<field name="recurring_next_date" required="1" />
|
||||
<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" />
|
||||
<button
|
||||
name="action_plan_successor"
|
||||
string="Plan Start"
|
||||
type="object"
|
||||
icon="fa-calendar text-success"
|
||||
attrs="{'invisible': [('is_plan_successor_allowed', '=', False)]}"/>
|
||||
<button name="action_stop_plan_successor"
|
||||
attrs="{'invisible': [('is_plan_successor_allowed', '=', False)]}"
|
||||
/>
|
||||
<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)]}"/>
|
||||
<button name="action_stop" string="Stop"
|
||||
attrs="{'invisible': [('is_stop_plan_successor_allowed', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="action_stop"
|
||||
string="Stop"
|
||||
type="object"
|
||||
icon="fa-stop text-danger"
|
||||
attrs="{'invisible': [('is_stop_allowed', '=', False)]}"/>
|
||||
<button name="cancel" string="Cancel"
|
||||
attrs="{'invisible': [('is_stop_allowed', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="cancel"
|
||||
string="Cancel"
|
||||
type="object"
|
||||
icon="fa-ban text-danger"
|
||||
confirm="Are you sure you want to cancel this line"
|
||||
attrs="{'invisible': [('is_cancel_allowed', '=', False)]}"/>
|
||||
<button name="action_uncancel"
|
||||
string="Un-cancel" type="object"
|
||||
attrs="{'invisible': [('is_cancel_allowed', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="action_uncancel"
|
||||
string="Un-cancel"
|
||||
type="object"
|
||||
icon="fa-ban text-success"
|
||||
attrs="{'invisible': [('is_un_cancel_allowed', '=', False)]}"/>
|
||||
<button name="renew" string="Renew"
|
||||
attrs="{'invisible': [('is_un_cancel_allowed', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="renew"
|
||||
string="Renew"
|
||||
type="object"
|
||||
icon="fa-fast-forward text-success"
|
||||
groups="base.group_no_one"
|
||||
attrs="{'invisible': [('is_auto_renew', '=', False)]}"/>
|
||||
attrs="{'invisible': [('is_auto_renew', '=', False)]}"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="note"/>
|
||||
<field name="note" />
|
||||
</page>
|
||||
<page name="info" string="Other Information">
|
||||
<field name="create_invoice_visibility"
|
||||
invisible="1"/>
|
||||
<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="company_id"
|
||||
<field
|
||||
name="code"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
/>
|
||||
<field
|
||||
name="group_id"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
/>
|
||||
<field
|
||||
name="company_id"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
options="{'no_create': True}"
|
||||
groups="base.group_multi_company"/>
|
||||
<field name="currency_id"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
<field
|
||||
name="currency_id"
|
||||
groups="base.group_multi_currency"
|
||||
/>
|
||||
<field
|
||||
name="invoice_partner_id"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
options="{'no_create': True}"
|
||||
groups="base.group_multi_currency"/>
|
||||
<field name="invoice_partner_id"
|
||||
attrs="{'readonly': [('is_terminated','=',True)]}"
|
||||
required="1"/>
|
||||
required="1"
|
||||
/>
|
||||
</group>
|
||||
<group string="Legend (for the markers inside invoice lines description)"
|
||||
name="group_legend">
|
||||
<group
|
||||
string="Legend (for the markers inside invoice lines description)"
|
||||
name="group_legend"
|
||||
>
|
||||
<p colspan="2">
|
||||
<strong>#START#</strong>
|
||||
: Start
|
||||
@@ -216,108 +331,123 @@
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
<field name="activity_ids" widget="mail_activity"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
<field name="message_follower_ids" widget="mail_followers" />
|
||||
<field name="activity_ids" widget="mail_activity" />
|
||||
<field name="message_ids" widget="mail_thread" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--Customer FORM view-->
|
||||
<record id="contract_contract_customer_form_view" model="ir.ui.view">
|
||||
<field name="name">contract.contract customer form view (in contract)</field>
|
||||
<field name="model">contract.contract</field>
|
||||
<field name="inherit_id" ref="contract_contract_form_view"/>
|
||||
<field name="inherit_id" ref="contract_contract_form_view" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="priority" eval="20" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="partner_id" position="attributes">
|
||||
<attribute name="string">Customer</attribute>
|
||||
<attribute name="domain">[('customer', '=', True)]</attribute>
|
||||
<attribute name="context">{'default_customer': True, 'default_supplier': False}</attribute>
|
||||
<attribute
|
||||
name="context"
|
||||
>{'default_customer': True, 'default_supplier': False}</attribute>
|
||||
</field>
|
||||
<field name="journal_id" position="attributes">
|
||||
<attribute name="domain">[('type', '=', 'sale'),('company_id', '=', company_id)]</attribute>
|
||||
<attribute
|
||||
name="domain"
|
||||
>[('type', '=', 'sale'),('company_id', '=', company_id)]</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--Supplier FORM view-->
|
||||
<record id="contract_contract_supplier_form_view" model="ir.ui.view">
|
||||
<field name="name">contract.contract supplier form view (in contract)</field>
|
||||
<field name="model">contract.contract</field>
|
||||
<field name="inherit_id" ref="contract_contract_form_view"/>
|
||||
<field name="inherit_id" ref="contract_contract_form_view" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="priority" eval="20" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="partner_id" position="attributes">
|
||||
<attribute name="string">Supplier</attribute>
|
||||
<attribute name="domain">[('supplier', '=', True)]</attribute>
|
||||
<attribute name="context">{'default_customer': False, 'default_supplier': True}</attribute>
|
||||
<attribute
|
||||
name="context"
|
||||
>{'default_customer': False, 'default_supplier': True}</attribute>
|
||||
</field>
|
||||
<field name="journal_id" position="attributes">
|
||||
<attribute name="domain">[('type', '=', 'purchase'),('company_id', '=', company_id)]</attribute>
|
||||
<attribute
|
||||
name="domain"
|
||||
>[('type', '=', 'purchase'),('company_id', '=', company_id)]</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--TREE view-->
|
||||
<record id="contract_contract_tree_view" model="ir.ui.view">
|
||||
<field name="name">contract.contract tree view (in contract)</field>
|
||||
<field name="model">contract.contract</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name" string="Name"/>
|
||||
<field name="code"/>
|
||||
<field name="journal_id" groups="account.group_account_user"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="name" string="Name" />
|
||||
<field name="code" />
|
||||
<field name="journal_id" groups="account.group_account_user" />
|
||||
<field name="partner_id" />
|
||||
<field name="active" invisible="1" />
|
||||
<field name="company_id" groups="base.group_multi_company" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--SEARCH view-->
|
||||
<record id="contract_contract_search_view" model="ir.ui.view">
|
||||
<field name="name">contract.contract search view (in contract)</field>
|
||||
<field name="model">contract.contract</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"
|
||||
filter_domain="['|', ('name','ilike',self), ('code','ilike',self)]"/>
|
||||
<field name="journal_id"/>
|
||||
<field name="pricelist_id"/>
|
||||
<separator/>
|
||||
<separator/>
|
||||
<filter name="not_finished"
|
||||
<field
|
||||
name="name"
|
||||
filter_domain="['|', ('name','ilike',self), ('code','ilike',self)]"
|
||||
/>
|
||||
<field name="journal_id" />
|
||||
<field name="pricelist_id" />
|
||||
<separator />
|
||||
<separator />
|
||||
<filter
|
||||
name="not_finished"
|
||||
string="In progress"
|
||||
domain="['|', ('date_end', '>=', context_today().strftime('%Y-%m-%d')), '&', ('date_end', '=', False), ('recurring_next_date', '!=', False)]"
|
||||
/>
|
||||
<filter name="finished"
|
||||
<filter
|
||||
name="finished"
|
||||
string="Finished"
|
||||
domain="[('date_end', '<', context_today().strftime('%Y-%m-%d')), ('recurring_next_date', '=', False)]"
|
||||
/>
|
||||
<field name="partner_id"/>
|
||||
<field name="commercial_partner_id"/>
|
||||
<filter string="Archived"
|
||||
<field name="partner_id" />
|
||||
<field name="commercial_partner_id" />
|
||||
<filter
|
||||
string="Archived"
|
||||
domain="[('active', '=', False)]"
|
||||
name="inactive"/>
|
||||
name="inactive"
|
||||
/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Associated Partner"
|
||||
<filter
|
||||
string="Associated Partner"
|
||||
name="group_by_partner"
|
||||
domain="[]"
|
||||
context="{'group_by':'partner_id'}"/>
|
||||
<filter name="commercial_partner_groupby"
|
||||
context="{'group_by':'partner_id'}"
|
||||
/>
|
||||
<filter
|
||||
name="commercial_partner_groupby"
|
||||
string="Commercial Entity"
|
||||
context="{'group_by': 'commercial_partner_id'}"/>
|
||||
<filter name="group_by_next_invoice"
|
||||
context="{'group_by': 'commercial_partner_id'}"
|
||||
/>
|
||||
<filter
|
||||
name="group_by_next_invoice"
|
||||
string="Next Invoice"
|
||||
domain="[('recurring_next_date', '!=', False)]"
|
||||
context="{'group_by':'recurring_next_date'}"
|
||||
/>
|
||||
<filter name="group_by_date_end"
|
||||
<filter
|
||||
name="group_by_date_end"
|
||||
string="Date End"
|
||||
domain="[]"
|
||||
context="{'group_by':'date_end'}"
|
||||
@@ -326,7 +456,6 @@
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--ACTION customer contracts-->
|
||||
<record id="action_customer_contract" model="ir.actions.act_window">
|
||||
<field name="name">Customer Contracts</field>
|
||||
@@ -339,34 +468,31 @@
|
||||
'search_default_not_finished':1,
|
||||
'default_contract_type': 'sale'}
|
||||
</field>
|
||||
<field name="search_view_id" ref="contract_contract_search_view"/>
|
||||
<field name="search_view_id" ref="contract_contract_search_view" />
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new contract.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_customer_contract_view_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="sequence" eval="1" />
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="contract_contract_tree_view"/>
|
||||
<field name="act_window_id" ref="action_customer_contract"/>
|
||||
<field name="view_id" ref="contract_contract_tree_view" />
|
||||
<field name="act_window_id" ref="action_customer_contract" />
|
||||
</record>
|
||||
|
||||
<record id="action_customer_contract_view_form" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="sequence" eval="2" />
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="contract_contract_customer_form_view"/>
|
||||
<field name="act_window_id" ref="action_customer_contract"/>
|
||||
<field name="view_id" ref="contract_contract_customer_form_view" />
|
||||
<field name="act_window_id" ref="action_customer_contract" />
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_contract_contract_customer"
|
||||
<menuitem
|
||||
id="menu_contract_contract_customer"
|
||||
parent="account.menu_finance_receivables"
|
||||
action="action_customer_contract"
|
||||
sequence="99"
|
||||
/>
|
||||
|
||||
<!--ACTION supplier contracts-->
|
||||
<record id="action_supplier_contract" model="ir.actions.act_window">
|
||||
<field name="name">Supplier Contracts</field>
|
||||
@@ -379,32 +505,29 @@
|
||||
'search_default_not_finished':1,
|
||||
'default_contract_type': 'purchase'}
|
||||
</field>
|
||||
<field name="search_view_id" ref="contract_contract_search_view"/>
|
||||
<field name="search_view_id" ref="contract_contract_search_view" />
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new contract.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_supplier_contract_view_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="sequence" eval="1" />
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="contract_contract_tree_view"/>
|
||||
<field name="act_window_id" ref="action_supplier_contract"/>
|
||||
<field name="view_id" ref="contract_contract_tree_view" />
|
||||
<field name="act_window_id" ref="action_supplier_contract" />
|
||||
</record>
|
||||
|
||||
<record id="action_supplier_contract_view_form" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="sequence" eval="2" />
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="contract_contract_supplier_form_view"/>
|
||||
<field name="act_window_id" ref="action_supplier_contract"/>
|
||||
<field name="view_id" ref="contract_contract_supplier_form_view" />
|
||||
<field name="act_window_id" ref="action_supplier_contract" />
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_contract_contract_supplier"
|
||||
<menuitem
|
||||
id="menu_contract_contract_supplier"
|
||||
parent="account.menu_finance_payables"
|
||||
action="action_supplier_contract"
|
||||
sequence="99"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,74 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<!--FORM view-->
|
||||
<record id="contract_line_form_view" model="ir.ui.view">
|
||||
<field name="name">contract.line form view (in contract)</field>
|
||||
<field name="model">contract.line</field>
|
||||
<field name="inherit_id" ref="contract_abstract_contract_line_form_view"/>
|
||||
<field name="inherit_id" ref="contract_abstract_contract_line_form_view" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<header position="inside">
|
||||
<field name="state" widget="statusbar"/>
|
||||
<field name="state" widget="statusbar" />
|
||||
</header>
|
||||
<group name="recurrence_info" position="inside">
|
||||
<group>
|
||||
<field name="create_invoice_visibility" invisible="1"/>
|
||||
<field name="date_start" required="1"/>
|
||||
<field name="next_period_date_start"/>
|
||||
<field name="recurring_next_date"/>
|
||||
<field name="create_invoice_visibility" invisible="1" />
|
||||
<field name="date_start" required="1" />
|
||||
<field name="next_period_date_start" />
|
||||
<field name="recurring_next_date" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="date_end"
|
||||
attrs="{'required': [('is_auto_renew', '=', True)]}"/>
|
||||
<field name="next_period_date_end"/>
|
||||
<field
|
||||
name="date_end"
|
||||
attrs="{'required': [('is_auto_renew', '=', True)]}"
|
||||
/>
|
||||
<field name="next_period_date_end" />
|
||||
</group>
|
||||
<group groups="base.group_no_one">
|
||||
<field name="last_date_invoiced" readonly="True"/>
|
||||
<field name="termination_notice_date" readonly="True"/>
|
||||
<field name="last_date_invoiced" readonly="True" />
|
||||
<field name="termination_notice_date" readonly="True" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="manual_renew_needed"/>
|
||||
<field name="manual_renew_needed" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="predecessor_contract_line_id"/>
|
||||
<field name="predecessor_contract_line_id" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="successor_contract_line_id"/>
|
||||
<field name="successor_contract_line_id" />
|
||||
</group>
|
||||
</group>
|
||||
<group name="recurrence_info" position="after">
|
||||
<group name="analytic"
|
||||
<group
|
||||
name="analytic"
|
||||
groups="analytic.group_analytic_accounting,analytic.group_analytic_tags"
|
||||
attrs="{'invisible': [('display_type', '!=', False)]}">
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="analytic_tag_ids" widget="many2many_tags" groups="analytic.group_analytic_tags"/>
|
||||
attrs="{'invisible': [('display_type', '!=', False)]}"
|
||||
>
|
||||
<field
|
||||
name="analytic_account_id"
|
||||
groups="analytic.group_analytic_accounting"
|
||||
/>
|
||||
<field
|
||||
name="analytic_tag_ids"
|
||||
widget="many2many_tags"
|
||||
groups="analytic.group_analytic_tags"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--Customer FORM view-->
|
||||
<record id="contract_line_customer_form_view" model="ir.ui.view">
|
||||
<field name="name">contract.line customer form view (in contract)</field>
|
||||
<field name="model">contract.line</field>
|
||||
<field name="inherit_id" ref="contract_line_form_view"/>
|
||||
<field name="inherit_id" ref="contract_line_form_view" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="priority" eval="20" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="product_id" position="attributes">
|
||||
<attribute name="domain">[('sale_ok', '=', True)]</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--Supplier FORM view-->
|
||||
<record id="contract_line_supplier_form_view" model="ir.ui.view">
|
||||
<field name="name">contract.line supplier form view (in contract)</field>
|
||||
<field name="model">contract.line</field>
|
||||
<field name="inherit_id" ref="contract_line_form_view"/>
|
||||
<field name="inherit_id" ref="contract_line_form_view" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="priority" eval="20" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="product_id" position="attributes">
|
||||
<attribute name="domain">[('purchase_ok', '=', True)]</attribute>
|
||||
@@ -78,99 +86,111 @@
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- TODO: Delete this view in migration to v13 or further migrations -->
|
||||
<!--TREE view-->
|
||||
<record id="contract_line_tree_view" model="ir.ui.view">
|
||||
<field name="name">contract.line tree view (in contract)</field>
|
||||
<field name="model">contract.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-muted="is_canceled"
|
||||
decoration-info="create_invoice_visibility and not is_canceled">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="product_id"/>
|
||||
<field name="name"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="analytic_tag_ids" widget="many2many_tags" groups="analytic.group_analytic_tags"/>
|
||||
<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="discount"
|
||||
groups="base.group_no_one"/>
|
||||
<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="date_end"/>
|
||||
<field name="recurring_next_date"
|
||||
required="1"/>
|
||||
<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"/>
|
||||
<button name="action_plan_successor"
|
||||
string="Plan Start" type="object"
|
||||
<tree
|
||||
decoration-muted="is_canceled"
|
||||
decoration-info="create_invoice_visibility and not is_canceled"
|
||||
>
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="product_id" />
|
||||
<field name="name" />
|
||||
<field
|
||||
name="analytic_account_id"
|
||||
groups="analytic.group_analytic_accounting"
|
||||
/>
|
||||
<field
|
||||
name="analytic_tag_ids"
|
||||
widget="many2many_tags"
|
||||
groups="analytic.group_analytic_tags"
|
||||
/>
|
||||
<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="discount" groups="base.group_no_one" />
|
||||
<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="date_end" />
|
||||
<field name="recurring_next_date" required="1" />
|
||||
<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" />
|
||||
<button
|
||||
name="action_plan_successor"
|
||||
string="Plan Start"
|
||||
type="object"
|
||||
icon="fa-calendar text-success"
|
||||
attrs="{'invisible': [('is_plan_successor_allowed', '=', False)]}"/>
|
||||
<button name="action_stop_plan_successor"
|
||||
attrs="{'invisible': [('is_plan_successor_allowed', '=', False)]}"
|
||||
/>
|
||||
<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)]}"/>
|
||||
<button name="action_stop" string="Stop"
|
||||
attrs="{'invisible': [('is_stop_plan_successor_allowed', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="action_stop"
|
||||
string="Stop"
|
||||
type="object"
|
||||
icon="fa-stop text-danger"
|
||||
attrs="{'invisible': [('is_stop_allowed', '=', False)]}"/>
|
||||
<button name="cancel" string="Cancel"
|
||||
attrs="{'invisible': [('is_stop_allowed', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="cancel"
|
||||
string="Cancel"
|
||||
type="object"
|
||||
icon="fa-ban text-danger"
|
||||
confirm="Are you sure you want to cancel this line"
|
||||
attrs="{'invisible': [('is_cancel_allowed', '=', False)]}"/>
|
||||
<button name="action_uncancel"
|
||||
string="Un-cancel" type="object"
|
||||
attrs="{'invisible': [('is_cancel_allowed', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="action_uncancel"
|
||||
string="Un-cancel"
|
||||
type="object"
|
||||
icon="fa-ban text-success"
|
||||
attrs="{'invisible': [('is_un_cancel_allowed', '=', False)]}"/>
|
||||
<button name="renew" string="Renew"
|
||||
attrs="{'invisible': [('is_un_cancel_allowed', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="renew"
|
||||
string="Renew"
|
||||
type="object"
|
||||
icon="fa-fast-forward text-success"
|
||||
groups="base.group_no_one"
|
||||
attrs="{'invisible': [('is_auto_renew', '=', False)]}"/>
|
||||
attrs="{'invisible': [('is_auto_renew', '=', False)]}"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--Supplier TREE view-->
|
||||
<record id="contract_line_supplier_tree_view" model="ir.ui.view">
|
||||
<field name="name">contract.line supplier tree view (in contract)</field>
|
||||
<field name="model">contract.line</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="inherit_id" ref="contract_line_tree_view"/>
|
||||
<field name="priority" eval="20" />
|
||||
<field name="inherit_id" ref="contract_line_tree_view" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="automatic_price" position="attributes">
|
||||
<attribute name="invisible">True</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,45 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="contract_tag_form_view" model="ir.ui.view">
|
||||
<field name="model">contract.tag</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="company_id" options="{'no_create': True}"
|
||||
groups="base.group_multi_company"/>
|
||||
<field name="name" />
|
||||
<field
|
||||
name="company_id"
|
||||
options="{'no_create': True}"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="contract_tag_tree_view">
|
||||
<field name="model">contract.tag</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="company_id" options="{'no_create': True}"
|
||||
groups="base.group_multi_company"/>
|
||||
<field name="name" />
|
||||
<field
|
||||
name="company_id"
|
||||
options="{'no_create': True}"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="contract_tag_act_window">
|
||||
<field name="name">Contract Tags</field>
|
||||
<field name="res_model">contract.tag</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.menu" id="contract_tag_menu">
|
||||
<field name="name">Contract Tag</field>
|
||||
<field name="parent_id" ref="menu_config_contract"/>
|
||||
<field name="action" ref="contract_tag_act_window"/>
|
||||
<field name="sequence" eval="16"/>
|
||||
<field name="parent_id" ref="menu_config_contract" />
|
||||
<field name="action" ref="contract_tag_act_window" />
|
||||
<field name="sequence" eval="16" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<!--FORM view-->
|
||||
<record id="contract_template_form_view" model="ir.ui.view">
|
||||
<field name="name">contract.template form view (in contract)</field>
|
||||
@@ -8,44 +7,63 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contract Template">
|
||||
<group name="name">
|
||||
<field name="name"/>
|
||||
<field name="name" />
|
||||
</group>
|
||||
<group name="group_main">
|
||||
<group name="group_main_left">
|
||||
<field name="contract_type" />
|
||||
<field name="journal_id" />
|
||||
<field name="pricelist_id" />
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<field
|
||||
name="company_id"
|
||||
options="{'no_create': True}"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
<group name="group_invoice_lines" string="Contract Template Lines">
|
||||
<field name="contract_line_ids"
|
||||
<field
|
||||
name="contract_line_ids"
|
||||
widget="section_and_note_one2many"
|
||||
nolabel="1">
|
||||
nolabel="1"
|
||||
>
|
||||
<tree>
|
||||
<control>
|
||||
<create string="Add a line"/>
|
||||
<create string="Add a section" context="{'default_display_type': 'line_section'}"/>
|
||||
<create string="Add a note" context="{'default_display_type': 'line_note'}"/>
|
||||
<create string="Add a line" />
|
||||
<create
|
||||
string="Add a section"
|
||||
context="{'default_display_type': 'line_section'}"
|
||||
/>
|
||||
<create
|
||||
string="Add a note"
|
||||
context="{'default_display_type': 'line_note'}"
|
||||
/>
|
||||
</control>
|
||||
<field name="display_type" invisible="1"/>
|
||||
<field name="display_type" invisible="1" />
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="product_id" />
|
||||
<field name="name" widget="section_and_note_text"/>
|
||||
<field name="name" widget="section_and_note_text" />
|
||||
<field name="quantity" />
|
||||
<field name="uom_id" />
|
||||
<field name="automatic_price" attrs="{'column_invisible': [('parent.contract_type','=','purchase')]}"/>
|
||||
<field name="price_unit" attrs="{'readonly': [('automatic_price', '=', True)]}"/>
|
||||
<field name="specific_price" invisible="1"/>
|
||||
<field
|
||||
name="automatic_price"
|
||||
attrs="{'column_invisible': [('parent.contract_type','=','purchase')]}"
|
||||
/>
|
||||
<field
|
||||
name="price_unit"
|
||||
attrs="{'readonly': [('automatic_price', '=', True)]}"
|
||||
/>
|
||||
<field name="specific_price" invisible="1" />
|
||||
<field name="discount" groups="base.group_no_one" />
|
||||
<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" invisible="1" />
|
||||
<field name="recurring_interval" invisible="1" />
|
||||
<field name="recurring_invoicing_type" invisible="1" />
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<group name="group_legend"
|
||||
<group
|
||||
name="group_legend"
|
||||
string="Legend (for the markers inside invoice lines description)"
|
||||
>
|
||||
<p> <strong>#START#</strong>: Start date of the invoiced period</p>
|
||||
@@ -54,7 +72,6 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--TREE view-->
|
||||
<record id="contract_template_tree_view" model="ir.ui.view">
|
||||
<field name="name">contract.template tree view (in contract)</field>
|
||||
@@ -67,7 +84,6 @@
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--SEARCH view-->
|
||||
<record id="contract_template_search_view" model="ir.ui.view">
|
||||
<field name="name">contract.template search view (in contract)</field>
|
||||
@@ -78,40 +94,41 @@
|
||||
<field name="contract_type" />
|
||||
<field name="pricelist_id" />
|
||||
<field name="journal_id" />
|
||||
<filter name="contract_type"
|
||||
<filter
|
||||
name="contract_type"
|
||||
string="Contract Type"
|
||||
context="{'group_by': 'contract_type'}"
|
||||
/>
|
||||
<filter name="pricelist_id"
|
||||
<filter
|
||||
name="pricelist_id"
|
||||
string="Pricelist"
|
||||
context="{'group_by': 'pricelist_id'}"
|
||||
/>
|
||||
<filter name="journal_id"
|
||||
<filter
|
||||
name="journal_id"
|
||||
string="Journal"
|
||||
context="{'group_by': 'journal_id'}"
|
||||
/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--ACTION-->
|
||||
<record id="contract_template_action" model="ir.actions.act_window">
|
||||
<field name="name">Contract Templates</field>
|
||||
<field name="res_model">contract.template</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="contract_template_search_view"/>
|
||||
<field name="search_view_id" ref="contract_template_search_view" />
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new contract template.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="contract_template_menu"
|
||||
<menuitem
|
||||
id="contract_template_menu"
|
||||
parent="menu_config_contract"
|
||||
action="contract_template_action"
|
||||
sequence="1"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<!--FORM view-->
|
||||
<record id="contract_template_line_form_view" model="ir.ui.view">
|
||||
<field name="name">contract.template.line form view (in contract)</field>
|
||||
<field name="model">contract.template.line</field>
|
||||
<field name="inherit_id" ref="contract_abstract_contract_line_form_view"/>
|
||||
<field name="inherit_id" ref="contract_abstract_contract_line_form_view" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<form position="attributes">
|
||||
@@ -13,5 +12,4 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,45 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="contract_terminate_reason_form_view">
|
||||
<field name="model">contract.terminate.reason</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="terminate_comment_required"/>
|
||||
<field name="name" />
|
||||
<field name="terminate_comment_required" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="contract_terminate_reason_tree_view">
|
||||
<field name="model">contract.terminate.reason</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="terminate_comment_required"/>
|
||||
<field name="name" />
|
||||
<field name="terminate_comment_required" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="contract_terminate_reason_act_window">
|
||||
<field name="name">Contract Termination Reason</field>
|
||||
<field name="res_model">contract.terminate.reason</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.menu" id="contract_terminate_reason_menu">
|
||||
<field name="name">Contract Termination Reason</field>
|
||||
<field name="parent_id" ref="menu_config_contract"/>
|
||||
<field name="action" ref="contract_terminate_reason_act_window"/>
|
||||
<field name="sequence" eval="16"/>
|
||||
<field name="parent_id" ref="menu_config_contract" />
|
||||
<field name="action" ref="contract_terminate_reason_act_window" />
|
||||
<field name="sequence" eval="16" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,28 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2019 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="res_config_settings_form_view">
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<label for="create_new_line_at_contract_line_renew" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,36 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2017 Carlos Dauden <carlos.dauden@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
|
||||
<record id="view_partner_form" model="ir.ui.view">
|
||||
<field name="inherit_id" ref="base.view_partner_form" />
|
||||
<field name="model">res.partner</field>
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_invoice'))]"/>
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_invoice'))]" />
|
||||
<field type="xml" name="arch">
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button name="act_show_contract" type="object" class="oe_stat_button"
|
||||
icon="fa-book" context="{'default_contract_type': 'sale', 'contract_type': 'sale'}"
|
||||
<button
|
||||
name="act_show_contract"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-book"
|
||||
context="{'default_contract_type': 'sale', 'contract_type': 'sale'}"
|
||||
attrs="{'invisible': [('customer','=',False)]}"
|
||||
help="Show the sale contracts for this partner">
|
||||
<field name="sale_contract_count" widget="statinfo" string="Sale Contracts"/>
|
||||
help="Show the sale contracts for this partner"
|
||||
>
|
||||
<field
|
||||
name="sale_contract_count"
|
||||
widget="statinfo"
|
||||
string="Sale Contracts"
|
||||
/>
|
||||
</button>
|
||||
<button name="act_show_contract" type="object" class="oe_stat_button"
|
||||
icon="fa-book" context="{'default_contract_type': 'purchase', 'contract_type': 'purchase'}"
|
||||
<button
|
||||
name="act_show_contract"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-book"
|
||||
context="{'default_contract_type': 'purchase', 'contract_type': 'purchase'}"
|
||||
attrs="{'invisible': [('supplier','=',False)]}"
|
||||
help="Show the purchase contracts for this partner">
|
||||
<field name="purchase_contract_count" widget="statinfo" string="Purchase Contracts"/>
|
||||
help="Show the purchase contracts for this partner"
|
||||
>
|
||||
<field
|
||||
name="purchase_contract_count"
|
||||
widget="statinfo"
|
||||
string="Purchase Contracts"
|
||||
/>
|
||||
</button>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_res_partner_filter" model="ir.ui.view">
|
||||
<field name="inherit_id" ref="base.view_res_partner_filter" />
|
||||
<field name="model">res.partner</field>
|
||||
<field type="xml" name="arch">
|
||||
<filter name="inactive" position="after">
|
||||
<separator/>
|
||||
<separator />
|
||||
<filter
|
||||
name="filter_running_contract"
|
||||
string="With running contracts"
|
||||
@@ -39,5 +55,4 @@
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -6,7 +6,7 @@ from odoo import api, fields, models
|
||||
|
||||
class ContractContractTerminate(models.TransientModel):
|
||||
|
||||
_name = 'contract.contract.terminate'
|
||||
_name = "contract.contract.terminate"
|
||||
_description = "Terminate Contract Wizard"
|
||||
|
||||
contract_id = fields.Many2one(
|
||||
|
||||
@@ -1,34 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="contract_contract_terminate_form_view">
|
||||
<field name="model">contract.contract.terminate</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contract Contract Terminate">
|
||||
<group>
|
||||
<field name="contract_id" invisible="True"/>
|
||||
<field name="terminate_comment_required" invisible="True"/>
|
||||
<field name="terminate_date"/>
|
||||
<field name="terminate_reason_id" widget="selection"/>
|
||||
<field name="terminate_comment" attrs="{'required': [('terminate_comment_required', '=', True)]}"/>
|
||||
<field name="contract_id" invisible="True" />
|
||||
<field name="terminate_comment_required" invisible="True" />
|
||||
<field name="terminate_date" />
|
||||
<field name="terminate_reason_id" widget="selection" />
|
||||
<field
|
||||
name="terminate_comment"
|
||||
attrs="{'required': [('terminate_comment_required', '=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="terminate_contract"
|
||||
<button
|
||||
name="terminate_contract"
|
||||
string="Terminate Contract"
|
||||
class="btn-primary"
|
||||
confirm="Are you sure you want to terminate this contract?"
|
||||
type="object"/>
|
||||
<button string="Cancel"
|
||||
class="btn-default"
|
||||
special="cancel"/>
|
||||
type="object"
|
||||
/>
|
||||
<button string="Cancel" class="btn-default" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -6,12 +6,12 @@ from odoo import api, fields, models
|
||||
|
||||
class ContractLineWizard(models.TransientModel):
|
||||
|
||||
_name = 'contract.line.wizard'
|
||||
_description = 'Contract Line Wizard'
|
||||
_name = "contract.line.wizard"
|
||||
_description = "Contract Line Wizard"
|
||||
|
||||
date_start = fields.Date(string='Date Start')
|
||||
date_end = fields.Date(string='Date End')
|
||||
recurring_next_date = fields.Date(string='Next Invoice Date')
|
||||
date_start = fields.Date(string="Date Start")
|
||||
date_end = fields.Date(string="Date End")
|
||||
recurring_next_date = fields.Date(string="Next Invoice Date")
|
||||
is_auto_renew = fields.Boolean(string="Auto Renew", default=False)
|
||||
manual_renew_needed = fields.Boolean(
|
||||
string="Manual renew needed",
|
||||
|
||||
@@ -1,100 +1,114 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2018 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="contract_line_wizard_stop_form_view">
|
||||
<field name="name">contract.line.stop.wizard.form (in contract)</field>
|
||||
<field name="model">contract.line.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group>
|
||||
<field name="contract_line_id" invisible="True"/>
|
||||
<field string="Stop Date" name="date_end" required="True"/>
|
||||
<field string="Is suspension without end date" name="manual_renew_needed"/>
|
||||
<field name="contract_line_id" invisible="True" />
|
||||
<field string="Stop Date" name="date_end" required="True" />
|
||||
<field
|
||||
string="Is suspension without end date"
|
||||
name="manual_renew_needed"
|
||||
/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="stop"
|
||||
<button
|
||||
name="stop"
|
||||
string="Validate"
|
||||
class="btn-primary"
|
||||
type="object"/>
|
||||
<button string="Cancel"
|
||||
class="btn-default"
|
||||
special="cancel"/>
|
||||
type="object"
|
||||
/>
|
||||
<button string="Cancel" class="btn-default" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="contract_line_wizard_plan_successor_form_view">
|
||||
<field name="name">contract.line.plan_successor.wizard.form (in contract)</field>
|
||||
<field
|
||||
name="name"
|
||||
>contract.line.plan_successor.wizard.form (in contract)</field>
|
||||
<field name="model">contract.line.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<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="is_auto_renew"/>
|
||||
<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="is_auto_renew" />
|
||||
</group>
|
||||
<footer>
|
||||
<button name="plan_successor"
|
||||
<button
|
||||
name="plan_successor"
|
||||
string="Validate"
|
||||
class="btn-primary"
|
||||
type="object"/>
|
||||
<button string="Cancel"
|
||||
class="btn-default"
|
||||
special="cancel"/>
|
||||
type="object"
|
||||
/>
|
||||
<button string="Cancel" class="btn-default" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="contract_line_wizard_stop_plan_successor_form_view">
|
||||
<field name="name">contract.line.stop_plan_successor.wizard.form (in contract)</field>
|
||||
<field
|
||||
name="name"
|
||||
>contract.line.stop_plan_successor.wizard.form (in contract)</field>
|
||||
<field name="model">contract.line.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group>
|
||||
<field name="contract_line_id" invisible="True"/>
|
||||
<field string="Suspension Start Date" name="date_start" required="True"/>
|
||||
<field string="Suspension End Date" name="date_end" required="True"/>
|
||||
<field name="is_auto_renew" invisible="1"/>
|
||||
<field name="contract_line_id" invisible="True" />
|
||||
<field
|
||||
string="Suspension Start Date"
|
||||
name="date_start"
|
||||
required="True"
|
||||
/>
|
||||
<field
|
||||
string="Suspension End Date"
|
||||
name="date_end"
|
||||
required="True"
|
||||
/>
|
||||
<field name="is_auto_renew" invisible="1" />
|
||||
</group>
|
||||
<footer>
|
||||
<button name="stop_plan_successor"
|
||||
<button
|
||||
name="stop_plan_successor"
|
||||
string="Validate"
|
||||
class="btn-primary"
|
||||
type="object"/>
|
||||
<button string="Cancel"
|
||||
class="btn-default"
|
||||
special="cancel"/>
|
||||
type="object"
|
||||
/>
|
||||
<button string="Cancel" class="btn-default" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="contract_line_wizard_uncancel_form_view">
|
||||
<field name="name">contract.line.stop_plan_successor.wizard.form (in contract)</field>
|
||||
<field
|
||||
name="name"
|
||||
>contract.line.stop_plan_successor.wizard.form (in contract)</field>
|
||||
<field name="model">contract.line.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group>
|
||||
<field name="contract_line_id" invisible="True"/>
|
||||
<field name="recurring_next_date" required="True"/>
|
||||
<field name="contract_line_id" invisible="True" />
|
||||
<field name="recurring_next_date" required="True" />
|
||||
</group>
|
||||
<footer>
|
||||
<button name="uncancel"
|
||||
<button
|
||||
name="uncancel"
|
||||
string="Validate"
|
||||
class="btn-primary"
|
||||
type="object"/>
|
||||
<button string="Cancel"
|
||||
class="btn-default"
|
||||
special="cancel"/>
|
||||
type="object"
|
||||
/>
|
||||
<button string="Cancel" class="btn-default" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,40 +1,38 @@
|
||||
# Copyright 2019 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo import _, api, fields, models
|
||||
|
||||
|
||||
class ContractManuallyCreateInvoice(models.TransientModel):
|
||||
|
||||
_name = 'contract.manually.create.invoice'
|
||||
_description = 'Contract Manually Create Invoice Wizard'
|
||||
_name = "contract.manually.create.invoice"
|
||||
_description = "Contract Manually Create Invoice Wizard"
|
||||
|
||||
invoice_date = fields.Date(string="Invoice Date", required=True)
|
||||
contract_to_invoice_count = fields.Integer(
|
||||
compute="_compute_contract_to_invoice_ids"
|
||||
)
|
||||
contract_to_invoice_ids = fields.Many2many(
|
||||
comodel_name="contract.contract",
|
||||
compute="_compute_contract_to_invoice_ids",
|
||||
comodel_name="contract.contract", compute="_compute_contract_to_invoice_ids",
|
||||
)
|
||||
contract_type = fields.Selection(
|
||||
selection=[('sale', 'Customer'), ('purchase', 'Supplier')],
|
||||
default='sale',
|
||||
selection=[("sale", "Customer"), ("purchase", "Supplier")],
|
||||
default="sale",
|
||||
required=True,
|
||||
)
|
||||
|
||||
@api.depends('invoice_date')
|
||||
@api.depends("invoice_date")
|
||||
def _compute_contract_to_invoice_ids(self):
|
||||
if not self.invoice_date:
|
||||
# trick to show no invoice when no date has been entered yet
|
||||
contract_to_invoice_domain = [('id', '=', False)]
|
||||
contract_to_invoice_domain = [("id", "=", False)]
|
||||
else:
|
||||
contract_to_invoice_domain = self.env[
|
||||
'contract.contract'
|
||||
"contract.contract"
|
||||
]._get_contracts_to_invoice_domain(self.invoice_date)
|
||||
self.contract_to_invoice_ids = self.env['contract.contract'].search(
|
||||
contract_to_invoice_domain
|
||||
+ [('contract_type', '=', self.contract_type)]
|
||||
self.contract_to_invoice_ids = self.env["contract.contract"].search(
|
||||
contract_to_invoice_domain + [("contract_type", "=", self.contract_type)]
|
||||
)
|
||||
self.contract_to_invoice_count = len(self.contract_to_invoice_ids)
|
||||
|
||||
@@ -45,7 +43,7 @@ class ContractManuallyCreateInvoice(models.TransientModel):
|
||||
"type": "ir.actions.act_window",
|
||||
"name": _("Contracts to invoice"),
|
||||
"res_model": "contract.contract",
|
||||
"domain": [('id', 'in', self.contract_to_invoice_ids.ids)],
|
||||
"domain": [("id", "in", self.contract_to_invoice_ids.ids)],
|
||||
"view_mode": "tree,form",
|
||||
"context": self.env.context,
|
||||
}
|
||||
@@ -53,14 +51,14 @@ class ContractManuallyCreateInvoice(models.TransientModel):
|
||||
@api.multi
|
||||
def create_invoice(self):
|
||||
self.ensure_one()
|
||||
invoices = self.env['account.invoice']
|
||||
invoices = self.env["account.invoice"]
|
||||
for contract in self.contract_to_invoice_ids:
|
||||
invoices |= contract.recurring_create_invoice()
|
||||
return {
|
||||
"type": "ir.actions.act_window",
|
||||
"name": _("Invoices"),
|
||||
"res_model": "account.invoice",
|
||||
"domain": [('id', 'in', invoices.ids)],
|
||||
"domain": [("id", "in", invoices.ids)],
|
||||
"view_mode": "tree,form",
|
||||
"context": self.env.context,
|
||||
}
|
||||
|
||||
@@ -1,79 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2019 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="contract_manually_create_invoice_form_view">
|
||||
<field name="model">contract.manually.create.invoice</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contract Manually Create Invoice">
|
||||
<group>
|
||||
<group>
|
||||
<field name="invoice_date"/>
|
||||
<field name="contract_type" invisible="1"/>
|
||||
<field name="invoice_date" />
|
||||
<field name="contract_type" invisible="1" />
|
||||
</group>
|
||||
<group>
|
||||
<button name="action_show_contract_to_invoice" type="object"
|
||||
<button
|
||||
name="action_show_contract_to_invoice"
|
||||
type="object"
|
||||
class="btn-link"
|
||||
attrs="{'invisible': [('contract_to_invoice_count', '=', 0)]}">
|
||||
<field name="contract_to_invoice_count"/>
|
||||
<span attrs="{'invisible': [('contract_to_invoice_count', '>', 1)]}">
|
||||
attrs="{'invisible': [('contract_to_invoice_count', '=', 0)]}"
|
||||
>
|
||||
<field name="contract_to_invoice_count" />
|
||||
<span
|
||||
attrs="{'invisible': [('contract_to_invoice_count', '>', 1)]}"
|
||||
>
|
||||
contract to invoice
|
||||
</span>
|
||||
<span attrs="{'invisible': [('contract_to_invoice_count', '<', 1)]}">
|
||||
<span
|
||||
attrs="{'invisible': [('contract_to_invoice_count', '<', 1)]}"
|
||||
>
|
||||
contracts to invoice
|
||||
</span>
|
||||
</button>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="create_invoice"
|
||||
<button
|
||||
name="create_invoice"
|
||||
attrs="{'invisible': [('contract_to_invoice_count', '=', 0)]}"
|
||||
string="Create Invoices"
|
||||
class="btn-primary"
|
||||
type="object"/>
|
||||
<button string="Cancel"
|
||||
class="btn-default"
|
||||
special="cancel"/>
|
||||
type="object"
|
||||
/>
|
||||
<button string="Cancel" class="btn-default" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window"
|
||||
id="sale_contract_manually_create_invoice_act_window">
|
||||
<record
|
||||
model="ir.actions.act_window"
|
||||
id="sale_contract_manually_create_invoice_act_window"
|
||||
>
|
||||
<field name="name">Manually Invoice Sale Contracts</field>
|
||||
<field name="res_model">contract.manually.create.invoice</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="context">{'default_contract_type': 'sale'}</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.menu" id="sale_contract_manually_create_invoice_menu">
|
||||
<field name="name">Manually Invoice Sale Contracts</field>
|
||||
<field name="parent_id" ref="account.menu_finance_receivables"/>
|
||||
<field name="groups_id" eval="[(6, 0, [ref('account.group_account_manager')])]"/>
|
||||
<field name="action"
|
||||
ref="sale_contract_manually_create_invoice_act_window"/>
|
||||
<field name="sequence" eval="999"/>
|
||||
<field name="parent_id" ref="account.menu_finance_receivables" />
|
||||
<field
|
||||
name="groups_id"
|
||||
eval="[(6, 0, [ref('account.group_account_manager')])]"
|
||||
/>
|
||||
<field name="action" ref="sale_contract_manually_create_invoice_act_window" />
|
||||
<field name="sequence" eval="999" />
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window"
|
||||
id="purchase_contract_manually_create_invoice_act_window">
|
||||
<record
|
||||
model="ir.actions.act_window"
|
||||
id="purchase_contract_manually_create_invoice_act_window"
|
||||
>
|
||||
<field name="name">Manually Invoice Purchase Contracts</field>
|
||||
<field name="res_model">contract.manually.create.invoice</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="context">{'default_contract_type': 'purchase'}</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.menu" id="purchase_contract_manually_create_invoice_menu">
|
||||
<field name="name">Manually Invoice Purchase Contracts</field>
|
||||
<field name="parent_id" ref="account.menu_finance_payables"/>
|
||||
<field name="groups_id" eval="[(6, 0, [ref('account.group_account_manager')])]"/>
|
||||
<field name="action"
|
||||
ref="purchase_contract_manually_create_invoice_act_window"/>
|
||||
<field name="sequence" eval="999"/>
|
||||
<field name="parent_id" ref="account.menu_finance_payables" />
|
||||
<field
|
||||
name="groups_id"
|
||||
eval="[(6, 0, [ref('account.group_account_manager')])]"
|
||||
/>
|
||||
<field
|
||||
name="action"
|
||||
ref="purchase_contract_manually_create_invoice_act_window"
|
||||
/>
|
||||
<field name="sequence" eval="999" />
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
2
setup/.setuptools-odoo-make-default-ignore
Normal file
2
setup/.setuptools-odoo-make-default-ignore
Normal file
@@ -0,0 +1,2 @@
|
||||
# addons listed in this file are ignored by
|
||||
# setuptools-odoo-make-default (one addon per line)
|
||||
2
setup/README
Normal file
2
setup/README
Normal file
@@ -0,0 +1,2 @@
|
||||
To learn more about this directory, please visit
|
||||
https://pypi.python.org/pypi/setuptools-odoo
|
||||
1
setup/contract/odoo/addons/contract
Symbolic link
1
setup/contract/odoo/addons/contract
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../contract
|
||||
6
setup/contract/setup.py
Normal file
6
setup/contract/setup.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['setuptools-odoo'],
|
||||
odoo_addon=True,
|
||||
)
|
||||
Reference in New Issue
Block a user