Repository
OCA/contract · module folder · Try on Runboat
Module version
1.0.3
Category
Contract Management
Folder size
5.45 MB
License
AGPL-3
Application
No
Auto-installable
No
Website
https://github.com/OCA/contract
Last tracking update
2026-08-07 09:06:34
Authors
ACSONE SA/NV, Odoo Community Association (OCA), Tecnativa
Maintainers
ACSONE SA/NV, Odoo Community Association (OCA), Tecnativa
Committers
Pilar Vargas, Weblate, OCA-git-bot, Renzo Meister, oca-ci, bosd, eduezerouali-tecnativa, Bhavesh Heliconia
Odoo dependencies
Python dependencies
None
System dependencies
None
Required by
contract_analytic_tag, contract_membership_delegated_partner, contract_payment_mode, contract_sale, contract_update_last_date_invoiced, contract_variable_quantity, pms_contract
Description
This module enables contracts management with recurring invoicing
functions. Also you can print and send by email contract report.

It works for customer contract and supplier contracts.

Contracts are shown in portal.

Code Analysis

Views touched (31)
XML IDNameModelTypeStatus
contract_contract_customer_form_view contract.contract customer form view (in contract) contract.contract form Inherits contract_contract_form_view
contract_contract_form_view contract.contract form view (in contract) contract.contract form New
contract_contract_search_view contract.contract search view (in contract) contract.contract search New
contract_contract_supplier_form_view contract.contract supplier form view (in contract) contract.contract form Inherits contract_contract_form_view
contract_contract_tree_view contract.contract list view (in contract) contract.contract list New
contract_line_customer_form_view contract.line customer form view (in contract) contract.line form Inherits contract_line_form_view
contract_line_form_view contract.line form Inherits contract_template_line_form_view
contract_line_report_tree_view contract.line report tree view (in contract) contract.line list New
contract_line_search_view contract.line search view (in contract) contract.line search New
contract_line_supplier_form_view contract.line supplier form view (in contract) contract.line form Inherits contract_line_form_view
contract_line_supplier_tree_view contract.line supplier list view (in contract) contract.line list Inherits contract_line_tree_view
contract_line_tree_view contract.line list view (in contract) contract.line list New
contract_line_view_pivot contract.line.view.pivot contract.line pivot New
contract_manually_create_invoice_form_view contract.manually.create.invoice form New
contract_tag_form_view contract.tag form New
contract_tag_tree_view contract.tag list New
contract_template_form_view contract.template form view (in contract) contract.template form New
contract_template_line_form_view contract.template.line form New
contract_template_search_view contract.template search view (in contract) contract.template search New
contract_template_tree_view contract.template list view (in contract) contract.template list New
mail_notification_contract mail_notification_contract ir.ui.view qweb Inherits mail.mail_notification_layout
portal_contract_page My Contract ir.ui.view qweb New
portal_my_contracts My Contracts ir.ui.view qweb New
portal_my_home_contract Show Contracts ir.ui.view qweb Inherits portal.portal_my_home
portal_my_home_menu_contract Portal layout : Contract menu entries ir.ui.view qweb Inherits portal.portal_breadcrumbs
report_contract_document report_contract_document ir.ui.view qweb New
report_contract_template report_contract_template ir.ui.view qweb New
res_config_settings_form_view res.config.settings form Inherits account.res_config_settings_view_form
template_contract_modification Contract Modification ir.ui.view qweb New
view_partner_form res.partner form Inherits base.view_partner_form
view_res_partner_filter res.partner Inherits base.view_res_partner_filter
HTTP endpoints (2)
Route(s)HandlerAuthTypeMethodsFlags
/my/contracts/<int:contract_contract_id> PortalContract.portal_my_contract_detail public http ALL website
/my/contracts, /my/contracts/page/<int:page> PortalContract.portal_my_contracts user http ALL website
Models touched (10)

New fields (1)
  • contract_line_id Many2one → contract.line
    index=True string='Contract Line' args: 'contract.line'
Public methods (0)

No public methods.

New fields (21)
  • active Boolean
    default=True
  • code Char
    string='Reference'
  • commercial_partner_id Many2one → res.partner
    compute_sudo=True index=True related='partner_id.commercial_partner_id' store=True string='Commercial Entity' args: 'res.partner'
  • contract_line_fixed_ids One2many → contract.line
    comodel_name='contract.line' context={'active_test': False} inverse_name='contract_id' string='Contract lines (fixed)'
  • contract_line_ids One2many → contract.line
    comodel_name='contract.line' context={'active_test': False} copy=True inverse_name='contract_id' string='Contract lines'
  • contract_template_id Many2one → contract.template
    comodel_name='contract.template' string='Contract Template'
  • create_invoice_visibility Boolean
    compute='_compute_create_invoice_visibility'
  • currency_id Many2one → res.currency
    comodel_name='res.currency' compute='_compute_currency_id' inverse='_inverse_currency_id' string='Currency'
  • date_end Date
    compute='_compute_date_end' readonly=False store=True
  • fiscal_position_id Many2one → account.fiscal.position
    comodel_name='account.fiscal.position' ondelete='restrict' string='Fiscal Position'
  • group_id Many2one → account.analytic.account
    comodel_name='account.analytic.account' compute='_compute_group_id' ondelete='restrict' readonly=False store=True string='Group'
  • invoice_count Integer
    compute='_compute_invoice_count'
  • invoice_partner_id Many2one → res.partner
    comodel_name='res.partner' domain="['|',('id', 'parent_of', partner_id), ('id', 'child_of', partner_id)]" ondelete='restrict' string='Invoicing contact'
  • manual_currency_id Many2one → res.currency
    comodel_name='res.currency' readonly=True
  • modification_ids One2many → contract.modification
    comodel_name='contract.modification' inverse_name='contract_id' string='Modifications'
  • name Char
  • note Text
    string='Notes'
  • partner_id Many2one → res.partner
    comodel_name='res.partner' inverse='_inverse_partner_id' required=True
  • payment_term_id Many2one → account.payment.term
    comodel_name='account.payment.term' index=True string='Payment Terms'
  • tag_ids Many2many → contract.tag
    comodel_name='contract.tag' string='Tags'
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> index=True string='Responsible'
Public methods (8)
  • action_contract_send(self)
  • action_preview(self)
    Invoked when 'Preview' button in contract form view is clicked.
  • action_show_invoices(self)
  • create(self, vals_list)
    @api.model_create_multi
  • cron_recurring_create_invoice(self, date_ref=None)
    @api.model
  • get_formview_id(self, access_uid=None)
  • recurring_create_invoice(self)
    Button action This method triggers the creation of the next invoices of the contracts even if their next invoicing date is in the future.
  • write(self, vals)

New fields (8)
  • active Boolean
    readonly=True related='contract_id.active' store=True string='Active'
  • contract_id Many2one → contract.contract
    bypass_search_access=True comodel_name='contract.contract' index=True ondelete='cascade' required=True string='Contract'
  • create_invoice_visibility Boolean
    compute='_compute_create_invoice_visibility'
  • currency_id Many2one
    related='contract_id.currency_id' store=True
  • monthly_recurring Monetary
    aggregator='sum' compute='_compute_monthly_recurring' currency_field='currency_id' store=True
  • partner_id Many2one
    store=True
  • product_id Many2one
    index=True
  • sequence Integer
Public methods (1)
  • get_view(self, view_id=None, view_type='form', **options)
    @api.model

New fields (4)
  • contract_to_invoice_count Integer
    compute='_compute_contract_to_invoice_ids'
  • contract_to_invoice_ids Many2many → contract.contract
    comodel_name='contract.contract' compute='_compute_contract_to_invoice_ids'
  • contract_type Selection
    default='sale' required=True selection=[('sale', 'Customer'), ('purchase', 'Supplier')]
  • invoice_date Date
    required=True
Public methods (2)
  • action_show_contract_to_invoice(self)
  • create_invoice(self)

New fields (4)
  • contract_id Many2one → contract.contract
    comodel_name='contract.contract' index=True ondelete='cascade' required=True string='Contract'
  • date Date
    required=True
  • description Text
    required=True
  • sent Boolean
Public methods (3)
  • check_modification_ids_need_sent(self)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (10)
  • date_end Date
    help='Optional contract termination date (limits recurrence)' index=True
  • date_start Date
    default=<expr> help='Contract activation date (first recurrence starts here)' index=True
  • last_date_invoiced Date
    copy=False readonly=True
  • next_period_date_end Date
    compute='_compute_next_period_date_end' string='Next Period End'
  • next_period_date_start Date
    compute='_compute_next_period_date_start' string='Next Period Start'
  • recurring_interval Integer
    default=1 help='Invoice every (Days/Week/Month/Year)' string='Invoice Every'
  • recurring_invoicing_offset Integer
    compute='_compute_recurring_invoicing_offset' help='Number of days to offset the invoice from the period end date (in post-paid mode) or start date (in pre-paid mode).' string='Invoicing offset'
  • recurring_invoicing_type Selection
    default='pre-paid' help='Specify if the invoice must be generated at the beginning (pre-paid) or end (post-paid) of the period.' string='Invoicing type' args: [('pre-paid', 'Pre-paid'), ('post-paid', 'Post-paid')]
  • recurring_next_date Date
    compute='_compute_recurring_next_date' copy=True readonly=False store=True string='Date of Next Invoice'
  • recurring_rule_type Selection
    default='monthly' help='Specify interval for automatic invoice generation.' string='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)')]
Public methods (3)
  • get_next_invoice_date(self, next_period_date_start, recurring_invoicing_type, recurring_invoicing_offset, recurring_rule_type, recurring_interval, max_date_end)
    @api.model
    Compute the date of the next invoice based on all parameters.
  • get_next_period_date_end(self, next_period_date_start, recurring_rule_type, recurring_interval, max_date_end, next_invoice_date=False, recurring_invoicing_type=False, recurring_invoicing_offset=False)
    @api.model
    Compute the end date for the next period.
  • get_relative_delta(self, recurring_rule_type, interval)
    @api.model
    Return a relativedelta for one period based on rule type.

New fields (3)
  • color Integer
    default=0 args: 'Color Index'
  • company_id Many2one → res.company
    default=<expr> string='Company' args: 'res.company'
  • name Char
    required=True
Public methods (0)

No public methods.

New fields (9)
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • contract_line_ids One2many → contract.template.line
    comodel_name='contract.template.line' copy=True inverse_name='contract_id' string='Contract template lines'
  • contract_type Selection
    default='sale' index=True selection=[('sale', 'Customer'), ('purchase', 'Supplier')]
  • generation_type Selection
    default=<expr> help='Defines what document is automatically generated by the cron.' selection=[('invoice', 'Invoice')]
  • journal_id Many2one → account.journal
    check_company=True comodel_name='account.journal' compute='_compute_journal_id' domain="[('type', '=', contract_type)]" index=True readonly=False store=True string='Journal'
  • line_recurrence Boolean
    help='Check this if you want to control recurrence at the line level instead of for the whole contract.' string='Recurrence at line level?'
  • name Char
    required=True
  • partner_id Many2one → res.partner
    comodel_name='res.partner' index=True string='Partner'
  • pricelist_id Many2one → product.pricelist
    comodel_name='product.pricelist' string='Pricelist'
Public methods (0)

No public methods.

New fields (23)
  • allowed_uom_ids Many2many → uom.uom
    comodel_name='uom.uom' compute='_compute_allowed_uom_ids'
  • automatic_price Boolean
    compute='_compute_automatic_price' help='If checked, the price will be taken from the pricelist. Otherwise, it must be set manually.' readonly=False store=True string='Auto-price?'
  • company_id Many2one
    readonly=True related='contract_id.company_id' store=True
  • contract_id Many2one → contract.template
    comodel_name='contract.template' ondelete='cascade' required=True string='Contract'
  • currency_id Many2one → res.currency
    args: 'res.currency'
  • date_start Date
    compute='_compute_date_start' copy=True readonly=False store=True
  • discount Float
    digits='Discount' help='Discount to apply on generated invoices. Must be ≤ 100.' string='Discount (%)'
  • display_type Selection
    default=False help='Technical field for UX purposes.' selection=[('line_section', 'Section'), ('line_note', 'Note')]
  • is_canceled Boolean
    default=False string='Canceled'
  • is_recurring_note Boolean
    compute='_compute_is_recurring_note' string='Recurring Note'
  • name Text
    compute='_compute_name' readonly=False required=True store=True string='Description'
  • note_invoicing_mode Selection
    default='with_previous_line' help='When to invoice this note line relative to others.' selection=[('with_previous_line', 'With previous line'), ('with_next_line', 'With next line'), ('custom', 'Custom')]
  • partner_id Many2one → res.partner
    comodel_name='res.partner' related='contract_id.partner_id'
  • price_subtotal Monetary
    compute='_compute_price_subtotal' string='Sub Total'
  • price_unit Float
    compute='_compute_price_unit' inverse='_inverse_price_unit' string='Unit Price'
  • product_id Many2one → product.product
    domain=[('active', '=', True)] string='Product' args: 'product.product'
  • quantity Float
    default=1.0 required=True
  • recurring_interval Integer
    compute='_compute_recurring_interval' copy=True readonly=False required=True store=True
  • recurring_invoicing_type Selection
    compute='_compute_recurring_invoicing_type' copy=True readonly=False required=True store=True
  • recurring_rule_type Selection
    compute='_compute_recurring_rule_type' copy=True readonly=False required=True store=True
  • sequence Integer
    default=10 help='Defines line ordering in the contract.'
  • specific_price Float
  • uom_id Many2one → uom.uom
    comodel_name='uom.uom' compute='_compute_uom_id' domain="[('id', 'in', allowed_uom_ids)]" readonly=False store=True string='Unit of Measure'
Public methods (0)

No public methods.

New fields (3)
  • contract_ids One2many → contract.contract
    comodel_name='contract.contract' inverse_name='partner_id' string='Contracts'
  • purchase_contract_count Integer
    compute='_compute_contract_count' string='Purchase Contracts'
  • sale_contract_count Integer
    compute='_compute_contract_count' string='Sale Contracts'
Public methods (1)
  • act_show_contract(self)
    This opens contract view @return: the contract view

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…