odoo-addon-contract 17.0.1.4.4__py3-none-any.whl → 18.0.2.0.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odoo/addons/contract/README.rst +14 -10
- odoo/addons/contract/__manifest__.py +3 -10
- odoo/addons/contract/controllers/main.py +1 -8
- odoo/addons/contract/data/contract_cron.xml +0 -2
- odoo/addons/contract/data/mail_template.xml +18 -17
- odoo/addons/contract/data/template_mail_notification.xml +1 -1
- odoo/addons/contract/i18n/am.po +141 -821
- odoo/addons/contract/i18n/ar.po +141 -821
- odoo/addons/contract/i18n/bg.po +141 -821
- odoo/addons/contract/i18n/bs.po +141 -821
- odoo/addons/contract/i18n/ca.po +831 -901
- odoo/addons/contract/i18n/ca_ES.po +141 -821
- odoo/addons/contract/i18n/contract.pot +140 -818
- odoo/addons/contract/i18n/cs.po +141 -821
- odoo/addons/contract/i18n/da.po +141 -821
- odoo/addons/contract/i18n/de.po +708 -954
- odoo/addons/contract/i18n/el_GR.po +141 -821
- odoo/addons/contract/i18n/en_GB.po +141 -821
- odoo/addons/contract/i18n/es.po +710 -948
- odoo/addons/contract/i18n/es_AR.po +548 -880
- odoo/addons/contract/i18n/es_CL.po +141 -821
- odoo/addons/contract/i18n/es_CO.po +141 -821
- odoo/addons/contract/i18n/es_CR.po +141 -821
- odoo/addons/contract/i18n/es_DO.po +141 -821
- odoo/addons/contract/i18n/es_EC.po +141 -821
- odoo/addons/contract/i18n/es_MX.po +141 -821
- odoo/addons/contract/i18n/es_PY.po +141 -821
- odoo/addons/contract/i18n/es_VE.po +141 -821
- odoo/addons/contract/i18n/et.po +141 -821
- odoo/addons/contract/i18n/eu.po +141 -821
- odoo/addons/contract/i18n/fa.po +141 -821
- odoo/addons/contract/i18n/fi.po +419 -850
- odoo/addons/contract/i18n/fr.po +706 -951
- odoo/addons/contract/i18n/fr_CA.po +141 -821
- odoo/addons/contract/i18n/fr_CH.po +141 -821
- odoo/addons/contract/i18n/fr_FR.po +449 -850
- odoo/addons/contract/i18n/gl.po +252 -846
- odoo/addons/contract/i18n/gl_ES.po +141 -821
- odoo/addons/contract/i18n/he.po +141 -821
- odoo/addons/contract/i18n/hi_IN.po +186 -831
- odoo/addons/contract/i18n/hr.po +206 -837
- odoo/addons/contract/i18n/hr_HR.po +218 -839
- odoo/addons/contract/i18n/hu.po +141 -821
- odoo/addons/contract/i18n/id.po +141 -821
- odoo/addons/contract/i18n/it.po +746 -900
- odoo/addons/contract/i18n/ja.po +141 -821
- odoo/addons/contract/i18n/ko.po +141 -821
- odoo/addons/contract/i18n/lt.po +141 -821
- odoo/addons/contract/i18n/lt_LT.po +141 -821
- odoo/addons/contract/i18n/lv.po +141 -821
- odoo/addons/contract/i18n/mk.po +141 -821
- odoo/addons/contract/i18n/mn.po +141 -821
- odoo/addons/contract/i18n/nb.po +141 -821
- odoo/addons/contract/i18n/nb_NO.po +141 -821
- odoo/addons/contract/i18n/nl.po +694 -953
- odoo/addons/contract/i18n/nl_BE.po +141 -821
- odoo/addons/contract/i18n/nl_NL.po +186 -831
- odoo/addons/contract/i18n/pl.po +141 -821
- odoo/addons/contract/i18n/pt.po +410 -839
- odoo/addons/contract/i18n/pt_BR.po +701 -949
- odoo/addons/contract/i18n/pt_PT.po +141 -821
- odoo/addons/contract/i18n/ro.po +141 -821
- odoo/addons/contract/i18n/ru.po +186 -831
- odoo/addons/contract/i18n/sk.po +141 -821
- odoo/addons/contract/i18n/sk_SK.po +141 -821
- odoo/addons/contract/i18n/sl.po +141 -821
- odoo/addons/contract/i18n/sr.po +141 -821
- odoo/addons/contract/i18n/sr@latin.po +141 -821
- odoo/addons/contract/i18n/sv.po +780 -934
- odoo/addons/contract/i18n/th.po +141 -821
- odoo/addons/contract/i18n/tr.po +556 -877
- odoo/addons/contract/i18n/tr_TR.po +216 -838
- odoo/addons/contract/i18n/uk.po +141 -821
- odoo/addons/contract/i18n/vi.po +141 -821
- odoo/addons/contract/i18n/vi_VN.po +141 -821
- odoo/addons/contract/i18n/zh_CN.po +407 -845
- odoo/addons/contract/i18n/zh_TW.po +145 -822
- odoo/addons/contract/migrations/18.0.2.0.0/end-migrate.py +27 -0
- odoo/addons/contract/migrations/18.0.2.0.0/pre-migrate.py +94 -0
- odoo/addons/contract/models/__init__.py +2 -6
- odoo/addons/contract/models/account_move.py +0 -8
- odoo/addons/contract/models/account_move_line.py +14 -0
- odoo/addons/contract/models/contract.py +272 -308
- odoo/addons/contract/models/contract_line.py +37 -859
- odoo/addons/contract/models/{contract_recurrency_mixin.py → contract_recurring_mixin.py} +101 -82
- odoo/addons/contract/models/contract_tag.py +1 -3
- odoo/addons/contract/models/contract_template.py +81 -2
- odoo/addons/contract/models/contract_template_line.py +250 -3
- odoo/addons/contract/report/contract_views.xml +0 -2
- odoo/addons/contract/report/report_contract.xml +13 -13
- odoo/addons/contract/security/contract_security.xml +6 -15
- odoo/addons/contract/security/contract_tag.xml +1 -3
- odoo/addons/contract/security/ir.model.access.csv +0 -2
- odoo/addons/contract/static/description/index.html +24 -18
- odoo/addons/contract/static/src/js/contract_portal_tour.esm.js +6 -4
- odoo/addons/contract/tests/test_contract.py +82 -928
- odoo/addons/contract/tests/test_multicompany.py +5 -4
- odoo/addons/contract/tests/test_portal.py +6 -3
- odoo/addons/contract/views/contract.xml +92 -235
- odoo/addons/contract/views/contract_line.xml +48 -117
- odoo/addons/contract/views/contract_portal_templates.xml +181 -222
- odoo/addons/contract/views/contract_tag.xml +3 -3
- odoo/addons/contract/views/contract_template.xml +100 -72
- odoo/addons/contract/views/contract_template_line.xml +76 -5
- odoo/addons/contract/views/res_config_settings.xml +5 -6
- odoo/addons/contract/views/res_partner_view.xml +0 -5
- odoo/addons/contract/wizards/__init__.py +0 -2
- odoo/addons/contract/wizards/contract_manually_create_invoice.py +6 -6
- odoo/addons/contract/wizards/contract_manually_create_invoice.xml +2 -3
- {odoo_addon_contract-17.0.1.4.4.dist-info → odoo_addon_contract-18.0.2.0.8.dist-info}/METADATA +18 -13
- odoo_addon_contract-18.0.2.0.8.dist-info/RECORD +132 -0
- {odoo_addon_contract-17.0.1.4.4.dist-info → odoo_addon_contract-18.0.2.0.8.dist-info}/WHEEL +1 -1
- odoo/addons/contract/data/contract_renew_cron.xml +0 -14
- odoo/addons/contract/models/abstract_contract.py +0 -82
- odoo/addons/contract/models/abstract_contract_line.py +0 -271
- odoo/addons/contract/models/contract_line_constraints.py +0 -429
- odoo/addons/contract/models/contract_terminate_reason.py +0 -14
- odoo/addons/contract/models/res_company.py +0 -15
- odoo/addons/contract/models/res_config_settings.py +0 -18
- odoo/addons/contract/security/contract_terminate_reason.xml +0 -23
- odoo/addons/contract/security/groups.xml +0 -9
- odoo/addons/contract/views/abstract_contract_line.xml +0 -117
- odoo/addons/contract/views/contract_terminate_reason.xml +0 -38
- odoo/addons/contract/wizards/contract_contract_terminate.py +0 -42
- odoo/addons/contract/wizards/contract_contract_terminate.xml +0 -33
- odoo/addons/contract/wizards/contract_line_wizard.py +0 -53
- odoo/addons/contract/wizards/contract_line_wizard.xml +0 -111
- odoo_addon_contract-17.0.1.4.4.dist-info/RECORD +0 -144
- {odoo_addon_contract-17.0.1.4.4.dist-info → odoo_addon_contract-18.0.2.0.8.dist-info}/top_level.txt +0 -0
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8" ?>
|
|
2
|
-
<odoo noupdate="1">
|
|
3
|
-
<record model="ir.cron" id="contract_line_cron_for_renew">
|
|
4
|
-
<field name="name">Renew Contract lines</field>
|
|
5
|
-
<field name="model_id" ref="model_contract_line" />
|
|
6
|
-
<field name="state">code</field>
|
|
7
|
-
<field name="code">model.cron_renew_contract_line()</field>
|
|
8
|
-
<field name="user_id" ref="base.user_root" />
|
|
9
|
-
<field name="interval_number">1</field>
|
|
10
|
-
<field name="interval_type">days</field>
|
|
11
|
-
<field name="numbercall">-1</field>
|
|
12
|
-
<field eval="False" name="doall" />
|
|
13
|
-
</record>
|
|
14
|
-
</odoo>
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# Copyright 2004-2010 OpenERP SA
|
|
2
|
-
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
|
|
3
|
-
# Copyright 2015-2020 Tecnativa - Pedro M. Baeza
|
|
4
|
-
# Copyright 2016-2018 Carlos Dauden <carlos.dauden@tecnativa.com>
|
|
5
|
-
# Copyright 2016-2017 LasLabs Inc.
|
|
6
|
-
# Copyright 2018 ACSONE SA/NV
|
|
7
|
-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
8
|
-
|
|
9
|
-
from odoo import api, fields, models
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ContractAbstractContract(models.AbstractModel):
|
|
13
|
-
_inherit = "contract.recurrency.basic.mixin"
|
|
14
|
-
_name = "contract.abstract.contract"
|
|
15
|
-
_description = "Abstract Recurring Contract"
|
|
16
|
-
_check_company_auto = True
|
|
17
|
-
|
|
18
|
-
# These fields will not be synced to the contract
|
|
19
|
-
NO_SYNC = ["name", "partner_id", "company_id"]
|
|
20
|
-
|
|
21
|
-
name = fields.Char(required=True)
|
|
22
|
-
# Needed for avoiding errors on several inherited behaviors
|
|
23
|
-
partner_id = fields.Many2one(
|
|
24
|
-
comodel_name="res.partner", string="Partner", index=True
|
|
25
|
-
)
|
|
26
|
-
pricelist_id = fields.Many2one(comodel_name="product.pricelist", string="Pricelist")
|
|
27
|
-
contract_type = fields.Selection(
|
|
28
|
-
selection=[("sale", "Customer"), ("purchase", "Supplier")],
|
|
29
|
-
default="sale",
|
|
30
|
-
index=True,
|
|
31
|
-
)
|
|
32
|
-
journal_id = fields.Many2one(
|
|
33
|
-
comodel_name="account.journal",
|
|
34
|
-
string="Journal",
|
|
35
|
-
domain="[('type', '=', contract_type)]",
|
|
36
|
-
compute="_compute_journal_id",
|
|
37
|
-
store=True,
|
|
38
|
-
readonly=False,
|
|
39
|
-
index=True,
|
|
40
|
-
check_company=True,
|
|
41
|
-
)
|
|
42
|
-
company_id = fields.Many2one(
|
|
43
|
-
"res.company",
|
|
44
|
-
string="Company",
|
|
45
|
-
required=True,
|
|
46
|
-
default=lambda self: self.env.company.id,
|
|
47
|
-
)
|
|
48
|
-
line_recurrence = fields.Boolean(
|
|
49
|
-
string="Recurrence at line level?",
|
|
50
|
-
help="Mark this check if you want to control recurrrence at line level instead"
|
|
51
|
-
" of all together for the whole contract.",
|
|
52
|
-
)
|
|
53
|
-
generation_type = fields.Selection(
|
|
54
|
-
selection=[("invoice", "Invoice")],
|
|
55
|
-
default=lambda self: self._default_generation_type(),
|
|
56
|
-
help="Choose the document that will be automatically generated by cron.",
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
@api.model
|
|
60
|
-
def _default_generation_type(self):
|
|
61
|
-
return "invoice"
|
|
62
|
-
|
|
63
|
-
@api.onchange("contract_type")
|
|
64
|
-
def _onchange_contract_type(self):
|
|
65
|
-
if self.contract_type == "purchase":
|
|
66
|
-
self.contract_line_ids.filtered("automatic_price").update(
|
|
67
|
-
{"automatic_price": False}
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
@api.depends("contract_type", "company_id")
|
|
71
|
-
def _compute_journal_id(self):
|
|
72
|
-
AccountJournal = self.env["account.journal"]
|
|
73
|
-
for contract in self:
|
|
74
|
-
domain = [
|
|
75
|
-
("type", "=", contract.contract_type),
|
|
76
|
-
("company_id", "=", contract.company_id.id),
|
|
77
|
-
]
|
|
78
|
-
journal = AccountJournal.search(domain, limit=1)
|
|
79
|
-
if journal:
|
|
80
|
-
contract.journal_id = journal.id
|
|
81
|
-
else:
|
|
82
|
-
contract.journal_id = None
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
# Copyright 2004-2010 OpenERP SA
|
|
2
|
-
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
|
|
3
|
-
# Copyright 2015 Pedro M. Baeza <pedro.baeza@tecnativa.com>
|
|
4
|
-
# Copyright 2016-2018 Carlos Dauden <carlos.dauden@tecnativa.com>
|
|
5
|
-
# Copyright 2016-2017 LasLabs Inc.
|
|
6
|
-
# Copyright 2018 ACSONE SA/NV
|
|
7
|
-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
8
|
-
|
|
9
|
-
from odoo import api, fields, models
|
|
10
|
-
from odoo.exceptions import ValidationError
|
|
11
|
-
from odoo.tools.translate import _
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class ContractAbstractContractLine(models.AbstractModel):
|
|
15
|
-
_inherit = "contract.recurrency.basic.mixin"
|
|
16
|
-
_name = "contract.abstract.contract.line"
|
|
17
|
-
_description = "Abstract Recurring Contract Line"
|
|
18
|
-
|
|
19
|
-
product_id = fields.Many2one("product.product", string="Product")
|
|
20
|
-
name = fields.Text(string="Description", required=True)
|
|
21
|
-
partner_id = fields.Many2one(
|
|
22
|
-
comodel_name="res.partner", related="contract_id.partner_id"
|
|
23
|
-
)
|
|
24
|
-
quantity = fields.Float(default=1.0, required=True)
|
|
25
|
-
product_uom_category_id = fields.Many2one( # Used for domain of field uom_id
|
|
26
|
-
comodel_name="uom.category",
|
|
27
|
-
related="product_id.uom_id.category_id",
|
|
28
|
-
)
|
|
29
|
-
uom_id = fields.Many2one(
|
|
30
|
-
comodel_name="uom.uom",
|
|
31
|
-
string="Unit of Measure",
|
|
32
|
-
domain="[('category_id', '=', product_uom_category_id)]",
|
|
33
|
-
)
|
|
34
|
-
automatic_price = fields.Boolean(
|
|
35
|
-
string="Auto-price?",
|
|
36
|
-
help="If this is marked, the price will be obtained automatically "
|
|
37
|
-
"applying the pricelist to the product. If not, you will be "
|
|
38
|
-
"able to introduce a manual price",
|
|
39
|
-
)
|
|
40
|
-
# Just to have a currency_id here - will get overwriten in contract.line
|
|
41
|
-
# model with the related currency from the contract
|
|
42
|
-
currency_id = fields.Many2one("res.currency")
|
|
43
|
-
specific_price = fields.Float()
|
|
44
|
-
price_unit = fields.Float(
|
|
45
|
-
string="Unit Price",
|
|
46
|
-
compute="_compute_price_unit",
|
|
47
|
-
inverse="_inverse_price_unit",
|
|
48
|
-
)
|
|
49
|
-
price_subtotal = fields.Monetary(
|
|
50
|
-
compute="_compute_price_subtotal",
|
|
51
|
-
string="Sub Total",
|
|
52
|
-
)
|
|
53
|
-
discount = fields.Float(
|
|
54
|
-
string="Discount (%)",
|
|
55
|
-
digits="Discount",
|
|
56
|
-
help="Discount that is applied in generated invoices."
|
|
57
|
-
" It should be less or equal to 100",
|
|
58
|
-
)
|
|
59
|
-
sequence = fields.Integer(
|
|
60
|
-
default=10,
|
|
61
|
-
help="Sequence of the contract line when displaying contracts",
|
|
62
|
-
)
|
|
63
|
-
recurring_rule_type = fields.Selection(
|
|
64
|
-
compute="_compute_recurring_rule_type",
|
|
65
|
-
store=True,
|
|
66
|
-
readonly=False,
|
|
67
|
-
required=True,
|
|
68
|
-
copy=True,
|
|
69
|
-
)
|
|
70
|
-
recurring_invoicing_type = fields.Selection(
|
|
71
|
-
compute="_compute_recurring_invoicing_type",
|
|
72
|
-
store=True,
|
|
73
|
-
readonly=False,
|
|
74
|
-
required=True,
|
|
75
|
-
copy=True,
|
|
76
|
-
)
|
|
77
|
-
recurring_interval = fields.Integer(
|
|
78
|
-
compute="_compute_recurring_interval",
|
|
79
|
-
store=True,
|
|
80
|
-
readonly=False,
|
|
81
|
-
required=True,
|
|
82
|
-
copy=True,
|
|
83
|
-
)
|
|
84
|
-
date_start = fields.Date(
|
|
85
|
-
compute="_compute_date_start",
|
|
86
|
-
store=True,
|
|
87
|
-
readonly=False,
|
|
88
|
-
copy=True,
|
|
89
|
-
)
|
|
90
|
-
last_date_invoiced = fields.Date()
|
|
91
|
-
is_canceled = fields.Boolean(string="Canceled", default=False)
|
|
92
|
-
is_auto_renew = fields.Boolean(string="Auto Renew", default=False)
|
|
93
|
-
auto_renew_interval = fields.Integer(
|
|
94
|
-
default=1,
|
|
95
|
-
string="Renew Every",
|
|
96
|
-
help="Renew every (Days/Week/Month/Year)",
|
|
97
|
-
)
|
|
98
|
-
auto_renew_rule_type = fields.Selection(
|
|
99
|
-
[
|
|
100
|
-
("daily", "Day(s)"),
|
|
101
|
-
("weekly", "Week(s)"),
|
|
102
|
-
("monthly", "Month(s)"),
|
|
103
|
-
("yearly", "Year(s)"),
|
|
104
|
-
],
|
|
105
|
-
default="yearly",
|
|
106
|
-
string="Renewal type",
|
|
107
|
-
help="Specify Interval for automatic renewal.",
|
|
108
|
-
)
|
|
109
|
-
termination_notice_interval = fields.Integer(
|
|
110
|
-
default=1, string="Termination Notice Before"
|
|
111
|
-
)
|
|
112
|
-
termination_notice_rule_type = fields.Selection(
|
|
113
|
-
[("daily", "Day(s)"), ("weekly", "Week(s)"), ("monthly", "Month(s)")],
|
|
114
|
-
default="monthly",
|
|
115
|
-
string="Termination Notice type",
|
|
116
|
-
)
|
|
117
|
-
contract_id = fields.Many2one(
|
|
118
|
-
string="Contract",
|
|
119
|
-
comodel_name="contract.abstract.contract",
|
|
120
|
-
required=True,
|
|
121
|
-
ondelete="cascade",
|
|
122
|
-
)
|
|
123
|
-
display_type = fields.Selection(
|
|
124
|
-
selection=[("line_section", "Section"), ("line_note", "Note")],
|
|
125
|
-
default=False,
|
|
126
|
-
help="Technical field for UX purpose.",
|
|
127
|
-
)
|
|
128
|
-
note_invoicing_mode = fields.Selection(
|
|
129
|
-
selection=[
|
|
130
|
-
("with_previous_line", "With previous line"),
|
|
131
|
-
("with_next_line", "With next line"),
|
|
132
|
-
("custom", "Custom"),
|
|
133
|
-
],
|
|
134
|
-
default="with_previous_line",
|
|
135
|
-
help="Defines when the Note is invoiced:\n"
|
|
136
|
-
"- With previous line: If the previous line can be invoiced.\n"
|
|
137
|
-
"- With next line: If the next line can be invoiced.\n"
|
|
138
|
-
"- Custom: Depending on the recurrence to be define.",
|
|
139
|
-
)
|
|
140
|
-
is_recurring_note = fields.Boolean(compute="_compute_is_recurring_note")
|
|
141
|
-
company_id = fields.Many2one(related="contract_id.company_id", store=True)
|
|
142
|
-
|
|
143
|
-
def _set_recurrence_field(self, field):
|
|
144
|
-
"""Helper method for computed methods that gets the equivalent field
|
|
145
|
-
in the header.
|
|
146
|
-
|
|
147
|
-
We need to re-assign the original value for avoiding a missing error.
|
|
148
|
-
"""
|
|
149
|
-
for record in self:
|
|
150
|
-
if record.contract_id.line_recurrence:
|
|
151
|
-
record[field] = record[field]
|
|
152
|
-
else:
|
|
153
|
-
record[field] = record.contract_id[field]
|
|
154
|
-
|
|
155
|
-
@api.depends("contract_id.recurring_rule_type", "contract_id.line_recurrence")
|
|
156
|
-
def _compute_recurring_rule_type(self):
|
|
157
|
-
self._set_recurrence_field("recurring_rule_type")
|
|
158
|
-
|
|
159
|
-
@api.depends("contract_id.recurring_invoicing_type", "contract_id.line_recurrence")
|
|
160
|
-
def _compute_recurring_invoicing_type(self):
|
|
161
|
-
self._set_recurrence_field("recurring_invoicing_type")
|
|
162
|
-
|
|
163
|
-
@api.depends("contract_id.recurring_interval", "contract_id.line_recurrence")
|
|
164
|
-
def _compute_recurring_interval(self):
|
|
165
|
-
self._set_recurrence_field("recurring_interval")
|
|
166
|
-
|
|
167
|
-
@api.depends("contract_id.date_start", "contract_id.line_recurrence")
|
|
168
|
-
def _compute_date_start(self):
|
|
169
|
-
self._set_recurrence_field("date_start")
|
|
170
|
-
|
|
171
|
-
# pylint: disable=missing-return
|
|
172
|
-
@api.depends("contract_id.recurring_next_date", "contract_id.line_recurrence")
|
|
173
|
-
def _compute_recurring_next_date(self):
|
|
174
|
-
super()._compute_recurring_next_date()
|
|
175
|
-
self._set_recurrence_field("recurring_next_date")
|
|
176
|
-
|
|
177
|
-
@api.depends("display_type", "note_invoicing_mode")
|
|
178
|
-
def _compute_is_recurring_note(self):
|
|
179
|
-
for record in self:
|
|
180
|
-
record.is_recurring_note = (
|
|
181
|
-
record.display_type == "line_note"
|
|
182
|
-
and record.note_invoicing_mode == "custom"
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
@api.depends(
|
|
186
|
-
"automatic_price",
|
|
187
|
-
"specific_price",
|
|
188
|
-
"product_id",
|
|
189
|
-
"quantity",
|
|
190
|
-
"contract_id.pricelist_id",
|
|
191
|
-
"contract_id.partner_id",
|
|
192
|
-
)
|
|
193
|
-
def _compute_price_unit(self):
|
|
194
|
-
"""Get the specific price if no auto-price, and the price obtained
|
|
195
|
-
from the pricelist otherwise.
|
|
196
|
-
"""
|
|
197
|
-
for line in self:
|
|
198
|
-
if line.automatic_price and line.product_id:
|
|
199
|
-
pricelist = (
|
|
200
|
-
line.contract_id.pricelist_id
|
|
201
|
-
or line.contract_id.partner_id.with_company(
|
|
202
|
-
line.contract_id.company_id
|
|
203
|
-
).property_product_pricelist
|
|
204
|
-
)
|
|
205
|
-
product = line.product_id.with_context(
|
|
206
|
-
quantity=line.env.context.get(
|
|
207
|
-
"contract_line_qty",
|
|
208
|
-
line.quantity,
|
|
209
|
-
),
|
|
210
|
-
pricelist=pricelist.id,
|
|
211
|
-
partner=line.contract_id.partner_id.id,
|
|
212
|
-
date=line.env.context.get(
|
|
213
|
-
"old_date", fields.Date.context_today(line)
|
|
214
|
-
),
|
|
215
|
-
)
|
|
216
|
-
line.price_unit = pricelist._get_product_price(product, quantity=1)
|
|
217
|
-
else:
|
|
218
|
-
line.price_unit = line.specific_price
|
|
219
|
-
|
|
220
|
-
# Tip in https://github.com/odoo/odoo/issues/23891#issuecomment-376910788
|
|
221
|
-
@api.onchange("price_unit")
|
|
222
|
-
def _inverse_price_unit(self):
|
|
223
|
-
"""Store the specific price in the no auto-price records."""
|
|
224
|
-
for line in self.filtered(lambda x: not x.automatic_price):
|
|
225
|
-
line.specific_price = line.price_unit
|
|
226
|
-
|
|
227
|
-
@api.depends("quantity", "price_unit", "discount")
|
|
228
|
-
def _compute_price_subtotal(self):
|
|
229
|
-
for line in self:
|
|
230
|
-
subtotal = line.quantity * line.price_unit
|
|
231
|
-
discount = line.discount / 100
|
|
232
|
-
subtotal *= 1 - discount
|
|
233
|
-
if line.contract_id.pricelist_id:
|
|
234
|
-
cur = line.contract_id.pricelist_id.currency_id
|
|
235
|
-
line.price_subtotal = cur.round(subtotal)
|
|
236
|
-
else:
|
|
237
|
-
line.price_subtotal = subtotal
|
|
238
|
-
|
|
239
|
-
@api.constrains("discount")
|
|
240
|
-
def _check_discount(self):
|
|
241
|
-
for line in self:
|
|
242
|
-
if line.discount > 100:
|
|
243
|
-
raise ValidationError(_("Discount should be less or equal to 100"))
|
|
244
|
-
|
|
245
|
-
@api.onchange("product_id")
|
|
246
|
-
def _onchange_product_id(self):
|
|
247
|
-
vals = {}
|
|
248
|
-
if not self.uom_id or (
|
|
249
|
-
self.product_id.uom_id.category_id.id != self.uom_id.category_id.id
|
|
250
|
-
):
|
|
251
|
-
vals["uom_id"] = self.product_id.uom_id
|
|
252
|
-
|
|
253
|
-
date = self.recurring_next_date or fields.Date.context_today(self)
|
|
254
|
-
partner = self.contract_id.partner_id or self.env.user.partner_id
|
|
255
|
-
if self.product_id:
|
|
256
|
-
product = self.product_id.with_context(
|
|
257
|
-
lang=partner.lang,
|
|
258
|
-
partner=partner.id,
|
|
259
|
-
quantity=self.quantity,
|
|
260
|
-
date=date,
|
|
261
|
-
pricelist=self.contract_id.pricelist_id.id,
|
|
262
|
-
uom=self.uom_id.id,
|
|
263
|
-
)
|
|
264
|
-
vals["name"] = self.product_id.get_product_multiline_description_sale()
|
|
265
|
-
if self.contract_id.pricelist_id:
|
|
266
|
-
vals["price_unit"] = self.contract_id.pricelist_id._get_product_price(
|
|
267
|
-
product, quantity=1
|
|
268
|
-
)
|
|
269
|
-
else:
|
|
270
|
-
vals["price_unit"] = 0.0
|
|
271
|
-
self.update(vals)
|