TIP: You can type at any time to perform a new search.
Recurring - Product Contract
product_contract · OCA/contract
- Repository
- OCA/contract · module folder · Try on Runboat
- Module version
- 1.1.4
- Category
- Contract Management
- Folder size
- 0.94 MB
- License
- AGPL-3
- Application
- No
- Auto-installable
- No
- Website
- https://github.com/OCA/contract
- Last tracking update
- 2026-08-07 08:43:01
- Authors
- ACSONE SA/NV, Odoo Community Association (OCA), LasLabs
- Maintainers
- ACSONE SA/NV, Odoo Community Association (OCA), LasLabs
- Committers
- Carlos Lopez, sbejaoui, Víctor Martínez, Weblate, Tobias Zehntner, OCA-git-bot, Benoit Aimont, oca-ci, Angel Rivas, bo-eska, bjouini
- Odoo dependencies
- Python dependencies
- python-dateutil
- System dependencies
- None
- Required by
- contract_sale_mandate, contract_sale_payment_mode, contract_sale_transmit_method, product_contract_brand, product_contract_recurrence_in_price, product_contract_variable_quantity
- Description
This module adds support for products to be linked to contract templates. A contract is created on `sale.order` confirmation for each different template used in sale order line where recurrence details are set too. Contract product are ignored on invoicing process and pass to nothing to invoice directly.
Code Analysis ⓘ
Views touched (5)
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
contract_contract_customer_form_view |
contract.contract | form | Inherits contract.contract_contract_customer_form_view | |
product_contract_configurator_form |
product.contract.configurator | form | New | |
product_template_form_contract_view |
account.invoice.select.contract | product.template | form | Inherits product.product_template_form_view |
res_config_settings_form_view |
res.config.settings.form (in product_contract) | res.config.settings | form | Inherits sale.res_config_settings_view_form |
view_order_form |
sale.order.form (in product_contract) | sale.order | form | Inherits sale.view_order_form |
HTTP endpoints (0)
No HTTP endpoints found for this module.
Models touched (9)
New fields (1)
-
sale_order_countIntegercompute='_compute_sale_order_count'
-
action_view_sales_orders(self)
New fields (1)
-
sale_order_line_idMany2one → sale.order.linecomodel_name='sale.order.line'copy=Falserequired=Falsestring='Sale Order Line'
No public methods.
New fields (0)
No new fields.
Public methods (0)No public methods.
New fields (16)
-
auto_renew_intervalIntegerdefault=1help='Renew every (Days/Week/Month/Year)'string='Renew Every' -
auto_renew_rule_typeSelectiondefault='yearly'help='Specify Interval for automatic renewal.'string='Renewal type' args: [('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)'), ('yearly', 'Year(s)')] -
contract_start_date_methodSelectiondefault='manual'help="This field allows to define how the start date of the contract will\n be calculated:\n\n - Manual: The start date will be selected by the user, by default will be the\n date of sale confirmation.\n - Start of current period: The start date will be the first day of the actual\n period selected on 'Invoicing Every' field. Example: If we are on 2024/08/27\n and the period selected is 'Year(s)' the start date will be 2024/01/01.\n - End of current period: The start date will be the last day of the actual\n period selected on 'Invoicing Every' field. Example: If we are on 2024/08/27\n and the period selected is 'Year(s)' the start date will be 2024/12/31.\n - Start of next period: The start date will be the first day of the next\n period selected on 'Invoicing Every' field. Example: If we are on 2024/08/27\n and the period selected is 'Year(s)' the start date will be 2025/01/01.\n - End of next period: The start date will be the last day of the actual\n period selected on 'Invoicing Every' field. Example: If we are on 2024/08/27\n and the period selected is 'Year(s)' the start date will be 2025/12/31.\n " args: [('manual', 'Manual'), ('start_this', 'Start of current period'), ('end_this', 'End of current period'), ('start_next', 'Start of next period'), ('end_next', 'End of next period')], 'Start Date Method' -
force_month_quarterlySelectionhelp='Force the month to be used inside the quarter' args: [('1', 'First month'), ('2', 'Second month'), ('3', 'Third month')], 'Force Month (quarterly)' -
force_month_semesterlySelectionhelp='Force the month to be used inside the semester' args: [('1', 'First month'), ('2', 'Second month'), ('3', 'Third month'), ('4', 'Fourth month'), ('5', 'Fifth month'), ('6', 'Sixth month')], 'Force Month (semesterly)' -
force_month_yearlySelectionargs: [('1', 'January'), ('2', 'February'), ('3', 'March'), ('4', 'April'), ('5', 'May'), ('6', 'June'), ('7', 'July'), ('8', 'August'), ('9', 'September'), ('10', 'October'), ('11', 'November'), ('12', 'December')], 'Force Month' -
is_auto_renewBooleandefault=Falsestring='Auto Renew' -
is_contractBooleanargs: 'Is a contract' -
property_contract_template_idMany2one → contract.templatecomodel_name='contract.template'company_dependent=Truestring='Contract Template' -
recurrence_intervalSelectiondefault='monthly'help='Define the length of each recurrence period (e.g., every 1 month, every 3 months).' args: [('monthly', 'Month(s)'), ('quarterly', 'Quarter(s)'), ('semesterly', 'Semester(s)'), ('yearly', 'Year(s)')] -
recurrence_numberIntegerdefault=1help='Total number of recurrence periods for the contract.'string='Number of Recurrences' -
recurring_intervalIntegerdefault=1help='Frequency at which invoices are generated (e.g., every 1 month, every 2 weeks).'string='Invoice Every' -
recurring_invoicing_typeSelectiondefault='pre-paid'help='Define whether invoices are issued before (prepaid) or after (postpaid) the service period.'string='Invoicing type' args: [('pre-paid', 'Pre-paid'), ('post-paid', 'Post-paid')] -
recurring_rule_typeSelectiondefault='monthly'help='Specify the time unit for generating recurring invoices (days, weeks, months, etc.).'string='Invoicing Recurrence' args: [('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)'), ('monthlylastday', 'Month(s) last day'), ('quarterly', 'Quarter(s)'), ('semesterly', 'Semester(s)'), ('yearly', 'Year(s)')] -
termination_notice_intervalIntegerdefault=1string='Termination Notice Before' -
termination_notice_rule_typeSelectiondefault='monthly'string='Termination Notice type' args: [('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)')]
-
write(self, vals)
New fields (1)
-
create_contract_at_sale_order_confirmationBooleandefault=Truestring='Automatically Create Contracts At Sale Order Confirmation'
No public methods.
New fields (1)
-
create_contract_at_sale_order_confirmationBooleanreadonly=Falserelated='company_id.create_contract_at_sale_order_confirmation'
No public methods.
New fields (3)
-
contract_countIntegercompute='_compute_contract_count' -
is_contractBooleancompute='_compute_is_contract'string='Is a contract' -
need_contract_creationBooleancompute='_compute_need_contract_creation'
-
action_confirm(self)If we have a contract in the order, set it up -
action_create_contract(self) -
action_show_contracts(self)
New fields (0)
No new fields.
Public methods (2)-
create_contract_line(self, contract) -
invoice_line_create(self, invoice_id, qty)
New fields (19)
-
auto_renew_intervalIntegercompute='_compute_product_contract_data'default=1help='Renew every (Days/Week/Month/Year)'precompute=Truereadonly=Falsestore=Truestring='Renew Every' -
auto_renew_rule_typeSelectioncompute='_compute_product_contract_data'default='yearly'help='Specify Interval for automatic renewal.'precompute=Truereadonly=Falsestore=Truestring='Renewal type' args: [('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)'), ('yearly', 'Year(s)')] -
company_idMany2one → res.companyargs: 'res.company' -
contract_idMany2one → contract.contractcomodel_name='contract.contract'string='Contract' -
contract_line_idMany2one → contract.linecomodel_name='contract.line'required=Falsestring='Contract Line to replace' -
contract_start_date_methodSelectioncompute='_compute_product_contract_data'default='manual'help="This field allows to define how the start date of the contract will\n be calculated:\n\n - Manual: The start date will be selected by the user, by default will be the\n date of sale confirmation.\n - Start of current period: The start date will be the first day of the actual\n period selected on 'Invoicing Every' field. Example: If we are on 2024/08/27\n and the period selected is 'Year(s)' the start date will be 2024/01/01.\n - End of current period: The start date will be the last day of the actual\n period selected on 'Invoicing Every' field. Example: If we are on 2024/08/27\n and the period selected is 'Year(s)' the start date will be 2024/12/31.\n - Start of next period: The start date will be the first day of the next\n period selected on 'Invoicing Every' field. Example: If we are on 2024/08/27\n and the period selected is 'Year(s)' the start date will be 2025/01/01.\n - End of next period: The start date will be the last day of the actual\n period selected on 'Invoicing Every' field. Example: If we are on 2024/08/27\n and the period selected is 'Year(s)' the start date will be 2025/12/31.\n "precompute=Truereadonly=Falsestore=True args: [('manual', 'Manual'), ('start_this', 'Start of current period'), ('end_this', 'End of current period'), ('start_next', 'Start of next period'), ('end_next', 'End of next period')], 'Start Date Method' -
contract_template_idMany2one → contract.templatecomodel_name='contract.template'compute='_compute_contract_template_id'string='Contract Template' -
date_endDatecompute='_compute_contract_line_date_end'precompute=Truereadonly=Falsestore=True -
date_startDatecompute='_compute_contract_line_date_start'precompute=Truereadonly=Falsestore=True -
is_auto_renewBooleancompute='_compute_product_contract_data'default=Falseprecompute=Truereadonly=Falsestore=Truestring='Auto Renew' -
is_contractBooleanrelated='product_id.is_contract'string='Is a contract' -
partner_idMany2one → res.partnerargs: 'res.partner' -
product_idMany2one → product.productargs: 'product.product' -
product_uom_qtyFloatargs: 'Quantity' -
recurrence_intervalSelectioncompute='_compute_product_contract_data'default='monthly'help='Specify Interval for contract duration.'precompute=Truereadonly=Falsestore=True args: [('monthly', 'Month(s)'), ('quarterly', 'Quarter(s)'), ('semesterly', 'Semester(s)'), ('yearly', 'Year(s)')] -
recurrence_numberIntegercompute='_compute_product_contract_data'precompute=Truereadonly=Falsestore=True -
recurring_intervalIntegercompute='_compute_product_contract_data'default=1help='Invoice every (Days/Week/Month/Year)'precompute=Truereadonly=Falsestore=Truestring='Invoice Every' -
recurring_invoicing_typeSelectioncompute='_compute_product_contract_data'default='pre-paid'help='Specify if the invoice must be generated at the beginning (pre-paid) or end (post-paid) of the period.'precompute=Truereadonly=Falsestore=Truestring='Invoicing type' args: [('pre-paid', 'Pre-paid'), ('post-paid', 'Post-paid')] -
recurring_rule_typeSelectioncompute='_compute_product_contract_data'default='monthly'help='Specify Interval for automatic invoice generation.'precompute=Truereadonly=Falsestore=Truestring='Recurrence' args: [('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)'), ('monthlylastday', 'Month(s) last day'), ('quarterly', 'Quarter(s)'), ('semesterly', 'Semester(s)'), ('yearly', 'Year(s)')]
No public methods.
Loading…
Loading…
Loading…
Loading…
Loading…
Loading…
Loading…
- Status
- Open migration PR — not merged yet for this version
- CI status
- checks failing
- Open since
- 234 days ago
- Last activity
- 45 days ago
- Repository
- OCA/contract
- Pull request
- [19.0][MIG] product_contract (#1371)