odoo-addon-contract 17.0.1.4.3.2__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.
Files changed (130) hide show
  1. odoo/addons/contract/README.rst +14 -10
  2. odoo/addons/contract/__manifest__.py +3 -10
  3. odoo/addons/contract/controllers/main.py +1 -8
  4. odoo/addons/contract/data/contract_cron.xml +0 -2
  5. odoo/addons/contract/data/mail_template.xml +18 -17
  6. odoo/addons/contract/data/template_mail_notification.xml +1 -1
  7. odoo/addons/contract/i18n/am.po +146 -821
  8. odoo/addons/contract/i18n/ar.po +146 -821
  9. odoo/addons/contract/i18n/bg.po +146 -821
  10. odoo/addons/contract/i18n/bs.po +146 -821
  11. odoo/addons/contract/i18n/ca.po +835 -900
  12. odoo/addons/contract/i18n/ca_ES.po +146 -821
  13. odoo/addons/contract/i18n/contract.pot +145 -818
  14. odoo/addons/contract/i18n/cs.po +146 -821
  15. odoo/addons/contract/i18n/da.po +146 -821
  16. odoo/addons/contract/i18n/de.po +712 -953
  17. odoo/addons/contract/i18n/el_GR.po +146 -821
  18. odoo/addons/contract/i18n/en_GB.po +146 -821
  19. odoo/addons/contract/i18n/es.po +714 -947
  20. odoo/addons/contract/i18n/es_AR.po +550 -877
  21. odoo/addons/contract/i18n/es_CL.po +146 -821
  22. odoo/addons/contract/i18n/es_CO.po +146 -821
  23. odoo/addons/contract/i18n/es_CR.po +146 -821
  24. odoo/addons/contract/i18n/es_DO.po +146 -821
  25. odoo/addons/contract/i18n/es_EC.po +146 -821
  26. odoo/addons/contract/i18n/es_MX.po +146 -821
  27. odoo/addons/contract/i18n/es_PY.po +146 -821
  28. odoo/addons/contract/i18n/es_VE.po +146 -821
  29. odoo/addons/contract/i18n/et.po +146 -821
  30. odoo/addons/contract/i18n/eu.po +146 -821
  31. odoo/addons/contract/i18n/fa.po +146 -821
  32. odoo/addons/contract/i18n/fi.po +422 -848
  33. odoo/addons/contract/i18n/fr.po +713 -953
  34. odoo/addons/contract/i18n/fr_CA.po +146 -821
  35. odoo/addons/contract/i18n/fr_CH.po +146 -821
  36. odoo/addons/contract/i18n/fr_FR.po +454 -850
  37. odoo/addons/contract/i18n/gl.po +257 -846
  38. odoo/addons/contract/i18n/gl_ES.po +146 -821
  39. odoo/addons/contract/i18n/he.po +146 -821
  40. odoo/addons/contract/i18n/hi_IN.po +191 -831
  41. odoo/addons/contract/i18n/hr.po +211 -837
  42. odoo/addons/contract/i18n/hr_HR.po +223 -839
  43. odoo/addons/contract/i18n/hu.po +146 -821
  44. odoo/addons/contract/i18n/id.po +146 -821
  45. odoo/addons/contract/i18n/it.po +753 -902
  46. odoo/addons/contract/i18n/ja.po +146 -821
  47. odoo/addons/contract/i18n/ko.po +146 -821
  48. odoo/addons/contract/i18n/lt.po +146 -821
  49. odoo/addons/contract/i18n/lt_LT.po +146 -821
  50. odoo/addons/contract/i18n/lv.po +146 -821
  51. odoo/addons/contract/i18n/mk.po +146 -821
  52. odoo/addons/contract/i18n/mn.po +146 -821
  53. odoo/addons/contract/i18n/nb.po +146 -821
  54. odoo/addons/contract/i18n/nb_NO.po +146 -821
  55. odoo/addons/contract/i18n/nl.po +699 -953
  56. odoo/addons/contract/i18n/nl_BE.po +146 -821
  57. odoo/addons/contract/i18n/nl_NL.po +191 -831
  58. odoo/addons/contract/i18n/pl.po +146 -821
  59. odoo/addons/contract/i18n/pt.po +415 -839
  60. odoo/addons/contract/i18n/pt_BR.po +704 -947
  61. odoo/addons/contract/i18n/pt_PT.po +146 -821
  62. odoo/addons/contract/i18n/ro.po +146 -821
  63. odoo/addons/contract/i18n/ru.po +191 -831
  64. odoo/addons/contract/i18n/sk.po +146 -821
  65. odoo/addons/contract/i18n/sk_SK.po +146 -821
  66. odoo/addons/contract/i18n/sl.po +146 -821
  67. odoo/addons/contract/i18n/sr.po +146 -821
  68. odoo/addons/contract/i18n/sr@latin.po +146 -821
  69. odoo/addons/contract/i18n/sv.po +784 -933
  70. odoo/addons/contract/i18n/th.po +146 -821
  71. odoo/addons/contract/i18n/tr.po +611 -879
  72. odoo/addons/contract/i18n/tr_TR.po +221 -838
  73. odoo/addons/contract/i18n/uk.po +146 -821
  74. odoo/addons/contract/i18n/vi.po +146 -821
  75. odoo/addons/contract/i18n/vi_VN.po +146 -821
  76. odoo/addons/contract/i18n/zh_CN.po +407 -840
  77. odoo/addons/contract/i18n/zh_TW.po +150 -822
  78. odoo/addons/contract/migrations/18.0.2.0.0/end-migrate.py +27 -0
  79. odoo/addons/contract/migrations/18.0.2.0.0/pre-migrate.py +94 -0
  80. odoo/addons/contract/models/__init__.py +2 -6
  81. odoo/addons/contract/models/account_move.py +0 -8
  82. odoo/addons/contract/models/account_move_line.py +14 -0
  83. odoo/addons/contract/models/contract.py +272 -308
  84. odoo/addons/contract/models/contract_line.py +37 -859
  85. odoo/addons/contract/models/{contract_recurrency_mixin.py → contract_recurring_mixin.py} +101 -82
  86. odoo/addons/contract/models/contract_tag.py +1 -3
  87. odoo/addons/contract/models/contract_template.py +81 -2
  88. odoo/addons/contract/models/contract_template_line.py +250 -3
  89. odoo/addons/contract/report/contract_views.xml +0 -2
  90. odoo/addons/contract/report/report_contract.xml +13 -13
  91. odoo/addons/contract/security/contract_security.xml +6 -15
  92. odoo/addons/contract/security/contract_tag.xml +1 -3
  93. odoo/addons/contract/security/ir.model.access.csv +0 -2
  94. odoo/addons/contract/static/description/index.html +24 -18
  95. odoo/addons/contract/static/src/img/contract_icon.svg +4 -0
  96. odoo/addons/contract/static/src/js/contract_portal_tour.esm.js +6 -4
  97. odoo/addons/contract/tests/test_contract.py +82 -928
  98. odoo/addons/contract/tests/test_multicompany.py +5 -4
  99. odoo/addons/contract/tests/test_portal.py +6 -3
  100. odoo/addons/contract/views/contract.xml +92 -235
  101. odoo/addons/contract/views/contract_line.xml +48 -117
  102. odoo/addons/contract/views/contract_portal_templates.xml +187 -224
  103. odoo/addons/contract/views/contract_tag.xml +3 -3
  104. odoo/addons/contract/views/contract_template.xml +100 -72
  105. odoo/addons/contract/views/contract_template_line.xml +76 -5
  106. odoo/addons/contract/views/res_config_settings.xml +5 -6
  107. odoo/addons/contract/views/res_partner_view.xml +0 -5
  108. odoo/addons/contract/wizards/__init__.py +0 -2
  109. odoo/addons/contract/wizards/contract_manually_create_invoice.py +6 -6
  110. odoo/addons/contract/wizards/contract_manually_create_invoice.xml +2 -3
  111. {odoo_addon_contract-17.0.1.4.3.2.dist-info → odoo_addon_contract-18.0.2.0.8.dist-info}/METADATA +18 -13
  112. odoo_addon_contract-18.0.2.0.8.dist-info/RECORD +132 -0
  113. {odoo_addon_contract-17.0.1.4.3.2.dist-info → odoo_addon_contract-18.0.2.0.8.dist-info}/WHEEL +1 -1
  114. odoo/addons/contract/data/contract_renew_cron.xml +0 -14
  115. odoo/addons/contract/models/abstract_contract.py +0 -82
  116. odoo/addons/contract/models/abstract_contract_line.py +0 -271
  117. odoo/addons/contract/models/contract_line_constraints.py +0 -429
  118. odoo/addons/contract/models/contract_terminate_reason.py +0 -14
  119. odoo/addons/contract/models/res_company.py +0 -15
  120. odoo/addons/contract/models/res_config_settings.py +0 -18
  121. odoo/addons/contract/security/contract_terminate_reason.xml +0 -23
  122. odoo/addons/contract/security/groups.xml +0 -9
  123. odoo/addons/contract/views/abstract_contract_line.xml +0 -117
  124. odoo/addons/contract/views/contract_terminate_reason.xml +0 -38
  125. odoo/addons/contract/wizards/contract_contract_terminate.py +0 -42
  126. odoo/addons/contract/wizards/contract_contract_terminate.xml +0 -33
  127. odoo/addons/contract/wizards/contract_line_wizard.py +0 -53
  128. odoo/addons/contract/wizards/contract_line_wizard.xml +0 -111
  129. odoo_addon_contract-17.0.1.4.3.2.dist-info/RECORD +0 -143
  130. {odoo_addon_contract-17.0.1.4.3.2.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)