Cost-Revenue Spread

account_spread_cost_revenue
REPOSITORY
REPOSITORYOCA/account-financial-tools
GIT
GIThttps://github.com/OCA/account-financial-tools.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/account-financial-tools/tree/18.0/account_spread_cost_revenue
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Onestein
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Onestein
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, oca-ci, Anusha
WEBSITE
WEBSITEhttps://github.com/OCA/account-financial-tools
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:07
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - account
    - base_setup
    - base
    - web
    - onboarding
    - product
    - mail
    - bus
    - web_tour
    - html_editor
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Allows to spread costs or revenues over a customizable periods, to even
out cost or invoice spikes.

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
view_account_spread account.spread form New
view_account_spread_invoice_line_link_wizard account.spread.invoice.line.link.wizard form New
view_account_spread_search account.spread search New
view_account_spread_template account.spread.template form New
view_account_spread_template_tree account.spread.template list New
view_account_spread_tree account.spread list New
view_company_form res.company xpath Inherits base.view_company_form
view_invoice_spread account.move xpath Inherits account.view_move_form
Models touched (8)

New fields (0)

No new fields.

Public methods (2)
  • action_post(self)
    Invoked when validating the invoices.
  • button_cancel(self)
    Cancel the spread lines and their related moves when the invoice is canceled.

New fields (2)
  • spread_check Selection
    compute='_compute_spread_check' args: [('linked', 'Linked'), ('unlinked', 'Unlinked'), ('unavailable', 'Unavailable')]
  • spread_id Many2one → account.spread
    copy=False string='Spread Board' args: 'account.spread'
Public methods (3)
  • create_auto_spread(self)
    Create auto spread table for each invoice line, when needed
  • spread_details(self)
    Button on the invoice lines tree view of the invoice form to show the spread form view.
  • write(self, vals)

New fields (32)
  • active Boolean
    default=True
  • all_posted Boolean
    compute='_compute_all_posted' store=True
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • credit_account_id Many2one → account.account
    compute='_compute_credit_account_id' readonly=False required=True store=True args: 'account.account'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency'
  • days_calc Boolean
    default=False help='Use number of days to calculate amount' string='Calculate by days'
  • debit_account_id Many2one → account.account
    compute='_compute_debit_account_id' readonly=False required=True store=True args: 'account.account'
  • display_create_all_moves Boolean
    compute='_compute_display_create_all_moves'
  • display_move_line_auto_post Boolean
    compute='_compute_display_move_line_auto_post' string='Display Button Auto-post lines'
  • display_recompute_buttons Boolean
    compute='_compute_display_recompute_buttons'
  • estimated_amount Float
    digits='Account'
  • invoice_id Many2one
    related='invoice_line_id.move_id' store=True
  • invoice_line_id Many2one → account.move.line
    compute='_compute_invoice_line' inverse='_inverse_invoice_line' store=True string='Invoice line' args: 'account.move.line'
  • invoice_line_ids One2many → account.move.line
    copy=False string='Invoice Lines' args: 'account.move.line', 'spread_id'
  • invoice_type Selection
    required=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • is_credit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • is_debit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • journal_id Many2one → account.journal
    check_company=True compute='_compute_journal_id' domain="[('id', 'in', suitable_journal_ids)]" precompute=True readonly=False required=True store=True args: 'account.journal'
  • line_ids One2many → account.spread.line
    string='Spread Lines' args: 'account.spread.line', 'spread_id'
  • move_line_auto_post Boolean
    default=True args: 'Auto-post lines'
  • name Char
    required=True
  • period_number Integer
    default=12 help='Define the number of spread lines' required=True string='Number of Repetitions'
  • period_type Selection
    default='month' help='Period length for the entries' required=True args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • posted_amount Float
    compute='_compute_amounts' digits='Account'
  • spread_date Date
    default=time.strftime('%Y-01-01') required=True string='Start Date'
  • spread_type Selection
    compute='_compute_spread_type' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • suitable_journal_ids Many2many → account.journal
    compute='_compute_suitable_journal_ids' args: 'account.journal'
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • total_amount Float
    compute='_compute_amounts' digits='Account'
  • unposted_amount Float
    compute='_compute_amounts' digits='Account'
  • unspread_amount Float
    compute='_compute_amounts' digits='Account'
  • use_invoice_line_account Boolean
Public methods (11)
  • action_recalculate_spread(self)
    Recalculate spread
  • action_undo_spread(self)
    Undo spreading: Remove all created moves
  • action_unlink_invoice_line(self)
    Unlink the invoice line from the spread board
  • compute_spread_board(self)
    Checks whether the spread lines should be calculated. In case checks pass, invoke "def _compute_spread_board()" method.
  • create_all_moves(self)
  • default_get(self, fields)
    @api.model
  • default_journal(self, company_id)
    @api.model
  • onchange_template(self)
    @api.onchange('template_id')
  • open_posted_view(self)
  • reconcile_spread_moves(self)
  • unlink(self)

New fields (13)
  • company_id Many2one → res.company
    required=True args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/revenue account' args: 'account.account'
  • invoice_id Many2one
    related='invoice_line_id.move_id'
  • invoice_line_id Many2one → account.move.line
    ondelete='cascade' required=True args: 'account.move.line'
  • invoice_type Selection
    compute='_compute_invoice_type' store=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False store=True string='Balance sheet account / Spread account' args: 'account.account'
  • spread_action_type Selection
    default=<expr> selection=<expr>
  • spread_id Many2one → account.spread
    domain="[('id', 'in', spread_invoice_type_domain_ids)]" string='Spread Board' args: 'account.spread'
  • spread_invoice_type_domain_ids One2many → account.spread
    compute='_compute_spread_invoice_type_domain' args: 'account.spread'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False store=True string='Spread Journal' args: 'account.journal'
  • spread_type Selection
    compute='_compute_invoice_type' store=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too."
Public methods (1)
  • confirm(self)

New fields (5)
  • amount Float
    digits='Account' required=True
  • date Date
    required=True
  • move_id Many2one → account.move
    string='Journal Entry' args: 'account.move'
  • name Char
    args: 'Description'
  • spread_id Many2one → account.spread
    ondelete='cascade' args: 'account.spread'
Public methods (4)
  • create_and_reconcile_moves(self)
  • create_move(self)
    Button to manually create a move from a spread line entry.
  • open_move(self)
    Used by a button to manually view a move from a spread line entry.
  • unlink_move(self)
    Used by a button to manually unlink a move from a spread line entry.

New fields (13)
  • auto_spread Boolean
    help='If checked, provide option to auto create spread during invoice validation, based on product/account/analytic in invoice line.' string='Auto assign template on invoice validate'
  • auto_spread_ids One2many → account.spread.template.auto
    comodel_name='account.spread.template.auto' inverse_name='template_id' string='Auto Spread On'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • days_calc Boolean
    default=False help='Use number of days to calculate amount' string='Calculate by days'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/Revenue Account' args: 'account.account'
  • name Char
    required=True
  • period_number Integer
    help='Define the number of spread lines' string='Number of Repetitions'
  • period_type Selection
    help='Period length for the entries' args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False required=False store=True string='Spread Balance Sheet Account' args: 'account.account'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False required=True store=True string='Journal' args: 'account.journal'
  • spread_type Selection
    default='sale' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • start_date Date
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too." string='Invoice account as spread account'
Public methods (1)
  • default_get(self, fields)
    @api.model

New fields (5)
  • account_id Many2one → account.account
    comodel_name='account.account' string='Account'
  • company_id Many2one
    related='template_id.company_id' store=True
  • name Char
    default='/' required=True
  • product_id Many2one → product.product
    comodel_name='product.product' string='Product'
  • template_id Many2one → account.spread.template
    comodel_name='account.spread.template' index=True ondelete='cascade' required=True string='Spread Template'
Public methods (0)

No public methods.

New fields (7)
  • allow_spread_planning Boolean
    default=True help='Disable this option if you do not want to allow the spreading before the invoice is validated.'
  • auto_archive_spread Boolean
    help='Enable this option if you want the cron job to automatically archive the spreads when all lines are posted.' args: 'Auto-archive spread'
  • default_spread_expense_account_id Many2one → account.account
    string='Expense Spread Account' args: 'account.account'
  • default_spread_expense_journal_id Many2one → account.journal
    string='Expense Spread Journal' args: 'account.journal'
  • default_spread_revenue_account_id Many2one → account.account
    string='Revenue Spread Account' args: 'account.account'
  • default_spread_revenue_journal_id Many2one → account.journal
    string='Revenue Spread Journal' args: 'account.journal'
  • force_move_auto_post Boolean
    help='Enable this option if you want to post automatically the accounting moves of all the spreads.' args: 'Auto-post spread lines'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/account-financial-tools
GIT
GIThttps://github.com/OCA/account-financial-tools.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/account-financial-tools/tree/17.0/account_spread_cost_revenue
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Onestein
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Onestein
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, oca-ci, Antoni Marroig Campomar
WEBSITE
WEBSITEhttps://github.com/OCA/account-financial-tools
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:20:01
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - account
    - base_setup
    - base
    - web
    - onboarding
    - product
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Allows to spread costs or revenues over a customizable periods, to even
out cost or invoice spikes.

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
view_account_spread account.spread form New
view_account_spread_invoice_line_link_wizard account.spread.invoice.line.link.wizard form New
view_account_spread_search account.spread search New
view_account_spread_template account.spread.template form New
view_account_spread_template_tree account.spread.template tree New
view_account_spread_tree account.spread tree New
view_company_form res.company xpath Inherits base.view_company_form
view_invoice_spread account.move xpath Inherits account.view_move_form
Models touched (8)

New fields (0)

No new fields.

Public methods (2)
  • action_post(self)
    Invoked when validating the invoices.
  • button_cancel(self)
    Cancel the spread lines and their related moves when the invoice is canceled.

New fields (2)
  • spread_check Selection
    compute='_compute_spread_check' args: [('linked', 'Linked'), ('unlinked', 'Unlinked'), ('unavailable', 'Unavailable')]
  • spread_id Many2one → account.spread
    copy=False string='Spread Board' args: 'account.spread'
Public methods (3)
  • create_auto_spread(self)
    Create auto spread table for each invoice line, when needed
  • spread_details(self)
    Button on the invoice lines tree view of the invoice form to show the spread form view.
  • write(self, vals)

New fields (32)
  • active Boolean
    default=True
  • all_posted Boolean
    compute='_compute_all_posted' store=True
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • credit_account_id Many2one → account.account
    compute='_compute_credit_account_id' readonly=False required=True store=True args: 'account.account'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency'
  • days_calc Boolean
    default=False help='Use number of days to calculate amount' string='Calculate by days'
  • debit_account_id Many2one → account.account
    compute='_compute_debit_account_id' readonly=False required=True store=True args: 'account.account'
  • display_create_all_moves Boolean
    compute='_compute_display_create_all_moves'
  • display_move_line_auto_post Boolean
    compute='_compute_display_move_line_auto_post' string='Display Button Auto-post lines'
  • display_recompute_buttons Boolean
    compute='_compute_display_recompute_buttons'
  • estimated_amount Float
    digits='Account'
  • invoice_id Many2one
    related='invoice_line_id.move_id' store=True
  • invoice_line_id Many2one → account.move.line
    compute='_compute_invoice_line' inverse='_inverse_invoice_line' store=True string='Invoice line' args: 'account.move.line'
  • invoice_line_ids One2many → account.move.line
    copy=False string='Invoice Lines' args: 'account.move.line', 'spread_id'
  • invoice_type Selection
    required=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • is_credit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • is_debit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • journal_id Many2one → account.journal
    check_company=True compute='_compute_journal_id' domain="[('id', 'in', suitable_journal_ids)]" precompute=True readonly=False required=True store=True args: 'account.journal'
  • line_ids One2many → account.spread.line
    string='Spread Lines' args: 'account.spread.line', 'spread_id'
  • move_line_auto_post Boolean
    default=True args: 'Auto-post lines'
  • name Char
    required=True
  • period_number Integer
    default=12 help='Define the number of spread lines' required=True string='Number of Repetitions'
  • period_type Selection
    default='month' help='Period length for the entries' required=True args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • posted_amount Float
    compute='_compute_amounts' digits='Account'
  • spread_date Date
    default=time.strftime('%Y-01-01') required=True string='Start Date'
  • spread_type Selection
    compute='_compute_spread_type' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • suitable_journal_ids Many2many → account.journal
    compute='_compute_suitable_journal_ids' args: 'account.journal'
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • total_amount Float
    compute='_compute_amounts' digits='Account'
  • unposted_amount Float
    compute='_compute_amounts' digits='Account'
  • unspread_amount Float
    compute='_compute_amounts' digits='Account'
  • use_invoice_line_account Boolean
Public methods (11)
  • action_recalculate_spread(self)
    Recalculate spread
  • action_undo_spread(self)
    Undo spreading: Remove all created moves
  • action_unlink_invoice_line(self)
    Unlink the invoice line from the spread board
  • compute_spread_board(self)
    Checks whether the spread lines should be calculated. In case checks pass, invoke "def _compute_spread_board()" method.
  • create_all_moves(self)
  • default_get(self, fields)
    @api.model
  • default_journal(self, company_id)
    @api.model
  • onchange_template(self)
    @api.onchange('template_id')
  • open_posted_view(self)
  • reconcile_spread_moves(self)
  • unlink(self)

New fields (13)
  • company_id Many2one → res.company
    required=True args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/revenue account' args: 'account.account'
  • invoice_id Many2one
    related='invoice_line_id.move_id'
  • invoice_line_id Many2one → account.move.line
    ondelete='cascade' required=True args: 'account.move.line'
  • invoice_type Selection
    compute='_compute_invoice_type' store=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False store=True string='Balance sheet account / Spread account' args: 'account.account'
  • spread_action_type Selection
    default=_selection_default_spread_action_type selection=_selection_spread_action_type
  • spread_id Many2one → account.spread
    domain="[('id', 'in', spread_invoice_type_domain_ids)]" string='Spread Board' args: 'account.spread'
  • spread_invoice_type_domain_ids One2many → account.spread
    compute='_compute_spread_invoice_type_domain' args: 'account.spread'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False store=True string='Spread Journal' args: 'account.journal'
  • spread_type Selection
    compute='_compute_invoice_type' store=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too."
Public methods (1)
  • confirm(self)

New fields (5)
  • amount Float
    digits='Account' required=True
  • date Date
    required=True
  • move_id Many2one → account.move
    string='Journal Entry' args: 'account.move'
  • name Char
    args: 'Description'
  • spread_id Many2one → account.spread
    ondelete='cascade' args: 'account.spread'
Public methods (4)
  • create_and_reconcile_moves(self)
  • create_move(self)
    Button to manually create a move from a spread line entry.
  • open_move(self)
    Used by a button to manually view a move from a spread line entry.
  • unlink_move(self)
    Used by a button to manually unlink a move from a spread line entry.

New fields (13)
  • auto_spread Boolean
    help='If checked, provide option to auto create spread during invoice validation, based on product/account/analytic in invoice line.' string='Auto assign template on invoice validate'
  • auto_spread_ids One2many → account.spread.template.auto
    comodel_name='account.spread.template.auto' inverse_name='template_id' string='Auto Spread On'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • days_calc Boolean
    default=False help='Use number of days to calculate amount' string='Calculate by days'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/Revenue Account' args: 'account.account'
  • name Char
    required=True
  • period_number Integer
    help='Define the number of spread lines' string='Number of Repetitions'
  • period_type Selection
    help='Period length for the entries' args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False required=False store=True string='Spread Balance Sheet Account' args: 'account.account'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False required=True store=True string='Journal' args: 'account.journal'
  • spread_type Selection
    default='sale' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • start_date Date
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too." string='Invoice account as spread account'
Public methods (1)
  • default_get(self, fields)
    @api.model

New fields (5)
  • account_id Many2one → account.account
    comodel_name='account.account' string='Account'
  • company_id Many2one
    related='template_id.company_id' store=True
  • name Char
    default='/' required=True
  • product_id Many2one → product.product
    comodel_name='product.product' string='Product'
  • template_id Many2one → account.spread.template
    comodel_name='account.spread.template' index=True ondelete='cascade' required=True string='Spread Template'
Public methods (0)

No public methods.

New fields (7)
  • allow_spread_planning Boolean
    default=True help='Disable this option if you do not want to allow the spreading before the invoice is validated.'
  • auto_archive_spread Boolean
    help='Enable this option if you want the cron job to automatically archive the spreads when all lines are posted.' args: 'Auto-archive spread'
  • default_spread_expense_account_id Many2one → account.account
    string='Expense Spread Account' args: 'account.account'
  • default_spread_expense_journal_id Many2one → account.journal
    string='Expense Spread Journal' args: 'account.journal'
  • default_spread_revenue_account_id Many2one → account.account
    string='Revenue Spread Account' args: 'account.account'
  • default_spread_revenue_journal_id Many2one → account.journal
    string='Revenue Spread Journal' args: 'account.journal'
  • force_move_auto_post Boolean
    help='Enable this option if you want to post automatically the accounting moves of all the spreads.' args: 'Auto-post spread lines'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/account-financial-tools
GIT
GIThttps://github.com/OCA/account-financial-tools.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/account-financial-tools/tree/16.0/account_spread_cost_revenue
VERSION
VERSION 1.0.1
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Onestein
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Onestein
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, Andrea Stirpe, oca-ci, Kitti U
WEBSITE
WEBSITEhttps://github.com/OCA/account-financial-tools
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:53:47
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - account
    - base_setup
    - base
    - web
    - product
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
view_account_spread account.spread form New
view_account_spread_invoice_line_link_wizard account.spread.invoice.line.link.wizard form New
view_account_spread_search account.spread search New
view_account_spread_template account.spread.template form New
view_account_spread_template_tree account.spread.template tree New
view_account_spread_tree account.spread tree New
view_company_form res.company xpath Inherits base.view_company_form
view_invoice_spread account.move xpath Inherits account.view_move_form
Models touched (8)

New fields (0)

No new fields.

Public methods (2)
  • action_post(self)
    Invoked when validating the invoices.
  • button_cancel(self)
    Cancel the spread lines and their related moves when the invoice is canceled.

New fields (2)
  • spread_check Selection
    compute='_compute_spread_check' args: [('linked', 'Linked'), ('unlinked', 'Unlinked'), ('unavailable', 'Unavailable')]
  • spread_id Many2one → account.spread
    copy=False string='Spread Board' args: 'account.spread'
Public methods (3)
  • create_auto_spread(self)
    Create auto spread table for each invoice line, when needed
  • spread_details(self)
    Button on the invoice lines tree view of the invoice form to show the spread form view.
  • write(self, vals)

New fields (32)
  • active Boolean
    default=True
  • all_posted Boolean
    compute='_compute_all_posted' store=True
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • credit_account_id Many2one → account.account
    compute='_compute_credit_account_id' readonly=False required=True store=True args: 'account.account'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency'
  • days_calc Boolean
    default=False help='Use number of days to calculate amount' string='Calculate by days'
  • debit_account_id Many2one → account.account
    compute='_compute_debit_account_id' readonly=False required=True store=True args: 'account.account'
  • display_create_all_moves Boolean
    compute='_compute_display_create_all_moves'
  • display_move_line_auto_post Boolean
    compute='_compute_display_move_line_auto_post' string='Display Button Auto-post lines'
  • display_recompute_buttons Boolean
    compute='_compute_display_recompute_buttons'
  • estimated_amount Float
    digits='Account'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.move_id' store=True
  • invoice_line_id Many2one → account.move.line
    compute='_compute_invoice_line' inverse='_inverse_invoice_line' store=True string='Invoice line' args: 'account.move.line'
  • invoice_line_ids One2many → account.move.line
    copy=False string='Invoice Lines' args: 'account.move.line', 'spread_id'
  • invoice_type Selection
    required=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • is_credit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • is_debit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • journal_id Many2one → account.journal
    check_company=True compute='_compute_journal_id' domain="[('id', 'in', suitable_journal_ids)]" precompute=True readonly=False required=True store=True args: 'account.journal'
  • line_ids One2many → account.spread.line
    string='Spread Lines' args: 'account.spread.line', 'spread_id'
  • move_line_auto_post Boolean
    default=True args: 'Auto-post lines'
  • name Char
    required=True
  • period_number Integer
    default=12 help='Define the number of spread lines' required=True string='Number of Repetitions'
  • period_type Selection
    default='month' help='Period length for the entries' required=True args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • posted_amount Float
    compute='_compute_amounts' digits='Account'
  • spread_date Date
    default=time.strftime('%Y-01-01') required=True string='Start Date'
  • spread_type Selection
    compute='_compute_spread_type' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • suitable_journal_ids Many2many → account.journal
    compute='_compute_suitable_journal_ids' args: 'account.journal'
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • total_amount Float
    compute='_compute_amounts' digits='Account'
  • unposted_amount Float
    compute='_compute_amounts' digits='Account'
  • unspread_amount Float
    compute='_compute_amounts' digits='Account'
  • use_invoice_line_account Boolean
Public methods (11)
  • action_recalculate_spread(self)
    Recalculate spread
  • action_undo_spread(self)
    Undo spreading: Remove all created moves
  • action_unlink_invoice_line(self)
    Unlink the invoice line from the spread board
  • compute_spread_board(self)
    Checks whether the spread lines should be calculated. In case checks pass, invoke "def _compute_spread_board()" method.
  • create_all_moves(self)
  • default_get(self, fields)
    @api.model
  • default_journal(self, company_id)
    @api.model
  • onchange_template(self)
    @api.onchange('template_id')
  • open_posted_view(self)
  • reconcile_spread_moves(self)
  • unlink(self)

New fields (13)
  • company_id Many2one → res.company
    required=True args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/revenue account' args: 'account.account'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.move_id'
  • invoice_line_id Many2one → account.move.line
    ondelete='cascade' readonly=True required=True args: 'account.move.line'
  • invoice_type Selection
    compute='_compute_invoice_type' store=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False store=True string='Balance sheet account / Spread account' args: 'account.account'
  • spread_action_type Selection
    default=_selection_default_spread_action_type selection=_selection_spread_action_type
  • spread_id Many2one → account.spread
    domain="[('id', 'in', spread_invoice_type_domain_ids)]" string='Spread Board' args: 'account.spread'
  • spread_invoice_type_domain_ids One2many → account.spread
    compute='_compute_spread_invoice_type_domain' args: 'account.spread'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False store=True string='Spread Journal' args: 'account.journal'
  • spread_type Selection
    compute='_compute_invoice_type' store=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too."
Public methods (1)
  • confirm(self)

New fields (5)
  • amount Float
    digits='Account' required=True
  • date Date
    required=True
  • move_id Many2one → account.move
    readonly=True string='Journal Entry' args: 'account.move'
  • name Char
    readonly=True args: 'Description'
  • spread_id Many2one → account.spread
    ondelete='cascade' args: 'account.spread'
Public methods (4)
  • create_and_reconcile_moves(self)
  • create_move(self)
    Button to manually create a move from a spread line entry.
  • open_move(self)
    Used by a button to manually view a move from a spread line entry.
  • unlink_move(self)
    Used by a button to manually unlink a move from a spread line entry.

New fields (13)
  • auto_spread Boolean
    help='If checked, provide option to auto create spread during invoice validation, based on product/account/analytic in invoice line.' string='Auto assign template on invoice validate'
  • auto_spread_ids One2many → account.spread.template.auto
    comodel_name='account.spread.template.auto' inverse_name='template_id' string='Auto Spread On'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • days_calc Boolean
    default=False help='Use number of days to calculate amount' string='Calculate by days'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/Revenue Account' args: 'account.account'
  • name Char
    required=True
  • period_number Integer
    help='Define the number of spread lines' string='Number of Repetitions'
  • period_type Selection
    help='Period length for the entries' args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False required=False store=True string='Spread Balance Sheet Account' args: 'account.account'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False required=True store=True string='Journal' args: 'account.journal'
  • spread_type Selection
    default='sale' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • start_date Date
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too." string='Invoice account as spread account'
Public methods (1)
  • default_get(self, fields)
    @api.model

New fields (5)
  • account_id Many2one → account.account
    comodel_name='account.account' string='Account'
  • company_id Many2one
    related='template_id.company_id' store=True
  • name Char
    default='/' required=True
  • product_id Many2one → product.product
    comodel_name='product.product' string='Product'
  • template_id Many2one → account.spread.template
    comodel_name='account.spread.template' index=True ondelete='cascade' required=True string='Spread Template'
Public methods (0)

No public methods.

New fields (7)
  • allow_spread_planning Boolean
    default=True help='Disable this option if you do not want to allow the spreading before the invoice is validated.'
  • auto_archive_spread Boolean
    help='Enable this option if you want the cron job to automatically archive the spreads when all lines are posted.' args: 'Auto-archive spread'
  • default_spread_expense_account_id Many2one → account.account
    string='Expense Spread Account' args: 'account.account'
  • default_spread_expense_journal_id Many2one → account.journal
    string='Expense Spread Journal' args: 'account.journal'
  • default_spread_revenue_account_id Many2one → account.account
    string='Revenue Spread Account' args: 'account.account'
  • default_spread_revenue_journal_id Many2one → account.journal
    string='Revenue Spread Journal' args: 'account.journal'
  • force_move_auto_post Boolean
    help='Enable this option if you want to post automatically the accounting moves of all the spreads.' args: 'Auto-post spread lines'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/account-financial-tools
GIT
GIThttps://github.com/OCA/account-financial-tools.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/account-financial-tools/tree/15.0/account_spread_cost_revenue
VERSION
VERSION 1.0.1
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Onestein
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Onestein
COMMITTERS
COMMITTERSmanu, Weblate, OCA-git-bot, oca-ci, Saran440
WEBSITE
WEBSITEhttps://github.com/OCA/account-financial-tools
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:46:34
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - account
    - base_setup
    - base
    - web
    - product
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (9)
XML IDNameModelTypeStatus
view_account_spread account.spread form New
view_account_spread_account_manager account.spread tree Inherits view_account_spread
view_account_spread_invoice_line_link_wizard account.spread.invoice.line.link.wizard form New
view_account_spread_search account.spread search New
view_account_spread_template account.spread.template form New
view_account_spread_template_tree account.spread.template tree New
view_account_spread_tree account.spread tree New
view_company_form res.company xpath Inherits base.view_company_form
view_invoice_spread account.move xpath Inherits account.view_move_form
Models touched (8)

New fields (0)

No new fields.

Public methods (2)
  • action_post(self)
    Invoked when validating the invoices.
  • button_cancel(self)
    Cancel the spread lines and their related moves when the invoice is canceled.

New fields (2)
  • spread_check Selection
    compute='_compute_spread_check' args: [('linked', 'Linked'), ('unlinked', 'Unlinked'), ('unavailable', 'Unavailable')]
  • spread_id Many2one → account.spread
    copy=False string='Spread Board' args: 'account.spread'
Public methods (3)
  • create_auto_spread(self)
    Create auto spread table for each invoice line, when needed
  • spread_details(self)
    Button on the invoice lines tree view of the invoice form to show the spread form view.
  • write(self, vals)

New fields (33)
  • account_analytic_id Many2one → account.analytic.account
    string='Analytic Account' args: 'account.analytic.account'
  • active Boolean
    default=True
  • all_posted Boolean
    compute='_compute_all_posted' store=True
  • analytic_tag_ids Many2many → account.analytic.tag
    string='Analytic Tags' args: 'account.analytic.tag'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • credit_account_id Many2one → account.account
    compute='_compute_credit_account_id' readonly=False required=True store=True args: 'account.account'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency'
  • days_calc Boolean
    default=False help='Use number of days to calculate amount' string='Calculate by days'
  • debit_account_id Many2one → account.account
    compute='_compute_debit_account_id' readonly=False required=True store=True args: 'account.account'
  • display_create_all_moves Boolean
    compute='_compute_display_create_all_moves'
  • display_move_line_auto_post Boolean
    compute='_compute_display_move_line_auto_post' string='Display Button Auto-post lines'
  • display_recompute_buttons Boolean
    compute='_compute_display_recompute_buttons'
  • estimated_amount Float
    digits='Account'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.move_id' store=True
  • invoice_line_id Many2one → account.move.line
    compute='_compute_invoice_line' inverse='_inverse_invoice_line' store=True string='Invoice line' args: 'account.move.line'
  • invoice_line_ids One2many → account.move.line
    copy=False string='Invoice Lines' args: 'account.move.line', 'spread_id'
  • invoice_type Selection
    required=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • is_credit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • is_debit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • journal_id Many2one → account.journal
    compute='_compute_journal_id' readonly=False required=True store=True args: 'account.journal'
  • line_ids One2many → account.spread.line
    string='Spread Lines' args: 'account.spread.line', 'spread_id'
  • move_line_auto_post Boolean
    default=True args: 'Auto-post lines'
  • name Char
    required=True
  • period_number Integer
    default=12 help='Define the number of spread lines' required=True string='Number of Repetitions'
  • period_type Selection
    default='month' help='Period length for the entries' required=True args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • posted_amount Float
    compute='_compute_amounts' digits='Account'
  • spread_date Date
    default=time.strftime('%Y-01-01') required=True string='Start Date'
  • spread_type Selection
    compute='_compute_spread_type' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • total_amount Float
    compute='_compute_amounts' digits='Account'
  • unposted_amount Float
    compute='_compute_amounts' digits='Account'
  • unspread_amount Float
    compute='_compute_amounts' digits='Account'
  • use_invoice_line_account Boolean
Public methods (11)
  • action_recalculate_spread(self)
    Recalculate spread
  • action_undo_spread(self)
    Undo spreading: Remove all created moves
  • action_unlink_invoice_line(self)
    Unlink the invoice line from the spread board
  • compute_spread_board(self)
    Checks whether the spread lines should be calculated. In case checks pass, invoke "def _compute_spread_board()" method.
  • create_all_moves(self)
  • default_get(self, fields)
    @api.model
  • default_journal(self, company_id)
    @api.model
  • onchange_template(self)
    @api.onchange('template_id')
  • open_reconcile_view(self)
  • reconcile_spread_moves(self)
  • unlink(self)

New fields (13)
  • company_id Many2one → res.company
    required=True args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/revenue account' args: 'account.account'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.move_id'
  • invoice_line_id Many2one → account.move.line
    ondelete='cascade' readonly=True required=True args: 'account.move.line'
  • invoice_type Selection
    compute='_compute_invoice_type' store=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False store=True string='Balance sheet account / Spread account' args: 'account.account'
  • spread_action_type Selection
    default=_selection_default_spread_action_type selection=_selection_spread_action_type
  • spread_id Many2one → account.spread
    domain="[('id', 'in', spread_invoice_type_domain_ids)]" string='Spread Board' args: 'account.spread'
  • spread_invoice_type_domain_ids One2many → account.spread
    compute='_compute_spread_invoice_type_domain' args: 'account.spread'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False store=True string='Spread Journal' args: 'account.journal'
  • spread_type Selection
    compute='_compute_invoice_type' store=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too."
Public methods (1)
  • confirm(self)

New fields (5)
  • amount Float
    digits='Account' required=True
  • date Date
    required=True
  • move_id Many2one → account.move
    readonly=True string='Journal Entry' args: 'account.move'
  • name Char
    readonly=True args: 'Description'
  • spread_id Many2one → account.spread
    ondelete='cascade' args: 'account.spread'
Public methods (4)
  • create_and_reconcile_moves(self)
  • create_move(self)
    Button to manually create a move from a spread line entry.
  • open_move(self)
    Used by a button to manually view a move from a spread line entry.
  • unlink_move(self)
    Used by a button to manually unlink a move from a spread line entry.

New fields (13)
  • auto_spread Boolean
    help='If checked, provide option to auto create spread during invoice validation, based on product/account/analytic in invoice line.' string='Auto assign template on invoice validate'
  • auto_spread_ids One2many → account.spread.template.auto
    comodel_name='account.spread.template.auto' inverse_name='template_id' string='Auto Spread On'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • days_calc Boolean
    default=False help='Use number of days to calculate amount' string='Calculate by days'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/Revenue Account' args: 'account.account'
  • name Char
    required=True
  • period_number Integer
    help='Define the number of spread lines' string='Number of Repetitions'
  • period_type Selection
    help='Period length for the entries' args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False required=False store=True string='Spread Balance Sheet Account' args: 'account.account'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False required=True store=True string='Journal' args: 'account.journal'
  • spread_type Selection
    default='sale' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • start_date Date
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too." string='Invoice account as spread account'
Public methods (1)
  • default_get(self, fields)
    @api.model

New fields (6)
  • account_id Many2one → account.account
    comodel_name='account.account' string='Account'
  • analytic_account_id Many2one → account.analytic.account
    comodel_name='account.analytic.account' string='Analytic'
  • company_id Many2one
    related='template_id.company_id' store=True
  • name Char
    default='/' required=True
  • product_id Many2one → product.product
    comodel_name='product.product' string='Product'
  • template_id Many2one → account.spread.template
    comodel_name='account.spread.template' index=True ondelete='cascade' required=True string='Spread Template'
Public methods (0)

No public methods.

New fields (7)
  • allow_spread_planning Boolean
    default=True help='Disable this option if you do not want to allow the spreading before the invoice is validated.'
  • auto_archive_spread Boolean
    help='Enable this option if you want the cron job to automatically archive the spreads when all lines are posted.' args: 'Auto-archive spread'
  • default_spread_expense_account_id Many2one → account.account
    string='Expense Spread Account' args: 'account.account'
  • default_spread_expense_journal_id Many2one → account.journal
    string='Expense Spread Journal' args: 'account.journal'
  • default_spread_revenue_account_id Many2one → account.account
    string='Revenue Spread Account' args: 'account.account'
  • default_spread_revenue_journal_id Many2one → account.journal
    string='Revenue Spread Journal' args: 'account.journal'
  • force_move_auto_post Boolean
    help='Enable this option if you want to post automatically the accounting moves of all the spreads.' args: 'Auto-post spread lines'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/account-financial-tools
GIT
GIThttps://github.com/OCA/account-financial-tools.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/account-financial-tools/tree/14.0/account_spread_cost_revenue
VERSION
VERSION 1.0.1
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Onestein
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Onestein
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, sergiocorato, oca-ci, Saran440
WEBSITE
WEBSITEhttps://github.com/OCA/account-financial-tools
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:41:00
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - account
    - base_setup
    - base
    - web
    - product
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (10)
XML IDNameModelTypeStatus
assets_backend account spread ir.ui.view qweb Inherits web.assets_backend
view_account_spread account.spread form New
view_account_spread_account_manager account.spread tree Inherits view_account_spread
view_account_spread_invoice_line_link_wizard account.spread.invoice.line.link.wizard form New
view_account_spread_search account.spread search New
view_account_spread_template account.spread.template form New
view_account_spread_template_tree account.spread.template tree New
view_account_spread_tree account.spread tree New
view_company_form res.company xpath Inherits base.view_company_form
view_invoice_spread account.move xpath Inherits account.view_move_form
Models touched (8)

New fields (0)

No new fields.

Public methods (2)
  • action_post(self)
    Invoked when validating the invoices.
  • button_cancel(self)
    Cancel the spread lines and their related moves when the invoice is canceled.

New fields (2)
  • spread_check Selection
    compute='_compute_spread_check' args: [('linked', 'Linked'), ('unlinked', 'Unlinked'), ('unavailable', 'Unavailable')]
  • spread_id Many2one → account.spread
    copy=False string='Spread Board' args: 'account.spread'
Public methods (3)
  • create_auto_spread(self)
    Create auto spread table for each invoice line, when needed
  • spread_details(self)
    Button on the invoice lines tree view of the invoice form to show the spread form view.
  • write(self, vals)

New fields (32)
  • account_analytic_id Many2one → account.analytic.account
    string='Analytic Account' args: 'account.analytic.account'
  • active Boolean
    default=True
  • all_posted Boolean
    compute='_compute_all_posted' store=True
  • analytic_tag_ids Many2many → account.analytic.tag
    string='Analytic Tags' args: 'account.analytic.tag'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • credit_account_id Many2one → account.account
    compute='_compute_credit_account_id' readonly=False required=True store=True args: 'account.account'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency'
  • debit_account_id Many2one → account.account
    compute='_compute_debit_account_id' readonly=False required=True store=True args: 'account.account'
  • display_create_all_moves Boolean
    compute='_compute_display_create_all_moves'
  • display_move_line_auto_post Boolean
    compute='_compute_display_move_line_auto_post' string='Display Button Auto-post lines'
  • display_recompute_buttons Boolean
    compute='_compute_display_recompute_buttons'
  • estimated_amount Float
    digits='Account'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.move_id' store=True
  • invoice_line_id Many2one → account.move.line
    compute='_compute_invoice_line' inverse='_inverse_invoice_line' store=True string='Invoice line' args: 'account.move.line'
  • invoice_line_ids One2many → account.move.line
    copy=False string='Invoice Lines' args: 'account.move.line', 'spread_id'
  • invoice_type Selection
    required=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • is_credit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • is_debit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • journal_id Many2one → account.journal
    compute='_compute_journal_id' readonly=False required=True store=True args: 'account.journal'
  • line_ids One2many → account.spread.line
    string='Spread Lines' args: 'account.spread.line', 'spread_id'
  • move_line_auto_post Boolean
    default=True args: 'Auto-post lines'
  • name Char
    required=True
  • period_number Integer
    default=12 help='Define the number of spread lines' required=True string='Number of Repetitions'
  • period_type Selection
    default='month' help='Period length for the entries' required=True args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • posted_amount Float
    compute='_compute_amounts' digits='Account'
  • spread_date Date
    default=time.strftime('%Y-01-01') required=True string='Start Date'
  • spread_type Selection
    compute='_compute_spread_type' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • total_amount Float
    compute='_compute_amounts' digits='Account'
  • unposted_amount Float
    compute='_compute_amounts' digits='Account'
  • unspread_amount Float
    compute='_compute_amounts' digits='Account'
  • use_invoice_line_account Boolean
Public methods (11)
  • action_recalculate_spread(self)
    Recalculate spread
  • action_undo_spread(self)
    Undo spreading: Remove all created moves
  • action_unlink_invoice_line(self)
    Unlink the invoice line from the spread board
  • compute_spread_board(self)
    Checks whether the spread lines should be calculated. In case checks pass, invoke "def _compute_spread_board()" method.
  • create_all_moves(self)
  • default_get(self, fields)
    @api.model
  • default_journal(self, company_id)
    @api.model
  • onchange_template(self)
    @api.onchange('template_id')
  • open_reconcile_view(self)
  • reconcile_spread_moves(self)
  • unlink(self)

New fields (13)
  • company_id Many2one → res.company
    required=True args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/revenue account' args: 'account.account'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.move_id'
  • invoice_line_id Many2one → account.move.line
    ondelete='cascade' readonly=True required=True args: 'account.move.line'
  • invoice_type Selection
    compute='_compute_invoice_type' store=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False store=True string='Balance sheet account / Spread account' args: 'account.account'
  • spread_action_type Selection
    default=_selection_default_spread_action_type selection=_selection_spread_action_type
  • spread_id Many2one → account.spread
    domain="[('id', 'in', spread_invoice_type_domain_ids)]" string='Spread Board' args: 'account.spread'
  • spread_invoice_type_domain_ids One2many → account.spread
    compute='_compute_spread_invoice_type_domain' args: 'account.spread'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False store=True string='Spread Journal' args: 'account.journal'
  • spread_type Selection
    compute='_compute_invoice_type' store=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too."
Public methods (1)
  • confirm(self)

New fields (5)
  • amount Float
    digits='Account' required=True
  • date Date
    required=True
  • move_id Many2one → account.move
    readonly=True string='Journal Entry' args: 'account.move'
  • name Char
    readonly=True args: 'Description'
  • spread_id Many2one → account.spread
    ondelete='cascade' args: 'account.spread'
Public methods (4)
  • create_and_reconcile_moves(self)
  • create_move(self)
    Button to manually create a move from a spread line entry.
  • open_move(self)
    Used by a button to manually view a move from a spread line entry.
  • unlink_move(self)
    Used by a button to manually unlink a move from a spread line entry.

New fields (12)
  • auto_spread Boolean
    help='If checked, provide option to auto create spread during invoice validation, based on product/account/analytic in invoice line.' string='Auto assign template on invoice validate'
  • auto_spread_ids One2many → account.spread.template.auto
    comodel_name='account.spread.template.auto' inverse_name='template_id' string='Auto Spread On'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/Revenue Account' args: 'account.account'
  • name Char
    required=True
  • period_number Integer
    help='Define the number of spread lines' string='Number of Repetitions'
  • period_type Selection
    help='Period length for the entries' args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False required=False store=True string='Spread Balance Sheet Account' args: 'account.account'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False required=True store=True string='Journal' args: 'account.journal'
  • spread_type Selection
    default='sale' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • start_date Date
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too." string='Invoice account as spread account'
Public methods (1)
  • default_get(self, fields)
    @api.model

New fields (6)
  • account_id Many2one → account.account
    comodel_name='account.account' string='Account'
  • analytic_account_id Many2one → account.analytic.account
    comodel_name='account.analytic.account' string='Analytic'
  • company_id Many2one
    related='template_id.company_id' store=True
  • name Char
    default='/' required=True
  • product_id Many2one → product.product
    comodel_name='product.product' string='Product'
  • template_id Many2one → account.spread.template
    comodel_name='account.spread.template' index=True ondelete='cascade' required=True string='Spread Template'
Public methods (0)

No public methods.

New fields (7)
  • allow_spread_planning Boolean
    default=True help='Disable this option if you do not want to allow the spreading before the invoice is validated.'
  • auto_archive_spread Boolean
    help='Enable this option if you want the cron job to automatically archive the spreads when all lines are posted.' args: 'Auto-archive spread'
  • default_spread_expense_account_id Many2one → account.account
    string='Expense Spread Account' args: 'account.account'
  • default_spread_expense_journal_id Many2one → account.journal
    string='Expense Spread Journal' args: 'account.journal'
  • default_spread_revenue_account_id Many2one → account.account
    string='Revenue Spread Account' args: 'account.account'
  • default_spread_revenue_journal_id Many2one → account.journal
    string='Revenue Spread Journal' args: 'account.journal'
  • force_move_auto_post Boolean
    help='Enable this option if you want to post automatically the accounting moves of all the spreads.' args: 'Auto-post spread lines'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/account-financial-tools
GIT
GIThttps://github.com/OCA/account-financial-tools.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/account-financial-tools/tree/13.0/account_spread_cost_revenue
VERSION
VERSION 1.0.1
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Onestein
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Onestein
COMMITTERS
COMMITTERSAndrea, Víctor Martínez, João Marques, oca-travis, Weblate, OCA-git-bot
WEBSITE
WEBSITEhttps://github.com/OCA/account-financial-tools
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:34:13
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - account
    - base_setup
    - base
    - web
    - product
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (10)
XML IDNameModelTypeStatus
assets_backend account spread ir.ui.view qweb Inherits web.assets_backend
view_account_spread account.spread form New
view_account_spread_account_manager account.spread tree Inherits view_account_spread
view_account_spread_invoice_line_link_wizard account.spread.invoice.line.link.wizard form New
view_account_spread_search account.spread search New
view_account_spread_template account.spread.template form New
view_account_spread_template_tree account.spread.template tree New
view_account_spread_tree account.spread tree New
view_company_form res.company xpath Inherits base.view_company_form
view_invoice_spread account.move xpath Inherits account.view_move_form
Models touched (8)

New fields (0)

No new fields.

Public methods (2)
  • action_post(self)
    Invoked when validating the invoices.
  • button_cancel(self)
    Cancel the spread lines and their related moves when the invoice is canceled.

New fields (2)
  • spread_check Selection
    compute='_compute_spread_check' args: [('linked', 'Linked'), ('unlinked', 'Unlinked'), ('unavailable', 'Unavailable')]
  • spread_id Many2one → account.spread
    copy=False string='Spread Board' args: 'account.spread'
Public methods (3)
  • create_auto_spread(self)
    Create auto spread table for each invoice line, when needed
  • spread_details(self)
    Button on the invoice lines tree view of the invoice form to show the spread form view.
  • write(self, vals)

New fields (32)
  • account_analytic_id Many2one → account.analytic.account
    string='Analytic Account' args: 'account.analytic.account'
  • active Boolean
    default=True
  • all_posted Boolean
    compute='_compute_all_posted' store=True
  • analytic_tag_ids Many2many → account.analytic.tag
    string='Analytic Tags' args: 'account.analytic.tag'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • credit_account_id Many2one → account.account
    compute='_compute_credit_account_id' readonly=False required=True store=True args: 'account.account'
  • currency_id Many2one → res.currency
    default=<expr> required=True args: 'res.currency'
  • debit_account_id Many2one → account.account
    compute='_compute_debit_account_id' readonly=False required=True store=True args: 'account.account'
  • display_create_all_moves Boolean
    compute='_compute_display_create_all_moves'
  • display_move_line_auto_post Boolean
    compute='_compute_display_move_line_auto_post' string='Display Button Auto-post lines'
  • display_recompute_buttons Boolean
    compute='_compute_display_recompute_buttons'
  • estimated_amount Float
    digits='Account'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.move_id' store=True
  • invoice_line_id Many2one → account.move.line
    compute='_compute_invoice_line' inverse='_inverse_invoice_line' store=True string='Invoice line' args: 'account.move.line'
  • invoice_line_ids One2many → account.move.line
    copy=False string='Invoice Lines' args: 'account.move.line', 'spread_id'
  • invoice_type Selection
    required=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • is_credit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • is_debit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • journal_id Many2one → account.journal
    compute='_compute_journal_id' readonly=False required=True store=True args: 'account.journal'
  • line_ids One2many → account.spread.line
    string='Spread Lines' args: 'account.spread.line', 'spread_id'
  • move_line_auto_post Boolean
    default=True args: 'Auto-post lines'
  • name Char
    required=True
  • period_number Integer
    default=12 help='Define the number of spread lines' required=True string='Number of Repetitions'
  • period_type Selection
    default='month' help='Period length for the entries' required=True args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • posted_amount Float
    compute='_compute_amounts' digits='Account'
  • spread_date Date
    default=time.strftime('%Y-01-01') required=True string='Start Date'
  • spread_type Selection
    compute='_compute_spread_type' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • total_amount Float
    compute='_compute_amounts' digits='Account'
  • unposted_amount Float
    compute='_compute_amounts' digits='Account'
  • unspread_amount Float
    compute='_compute_amounts' digits='Account'
  • use_invoice_line_account Boolean
Public methods (11)
  • action_recalculate_spread(self)
    Recalculate spread
  • action_undo_spread(self)
    Undo spreading: Remove all created moves
  • action_unlink_invoice_line(self)
    Unlink the invoice line from the spread board
  • compute_spread_board(self)
    Checks whether the spread lines should be calculated. In case checks pass, invoke "def _compute_spread_board()" method.
  • create_all_moves(self)
  • default_get(self, fields)
    @api.model
  • default_journal(self, company_id)
    @api.model
  • onchange_template(self)
    @api.onchange('template_id')
  • open_reconcile_view(self)
  • reconcile_spread_moves(self)
  • unlink(self)

New fields (13)
  • company_id Many2one → res.company
    required=True args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/revenue account' args: 'account.account'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.move_id'
  • invoice_line_id Many2one → account.move.line
    ondelete='cascade' readonly=True required=True args: 'account.move.line'
  • invoice_type Selection
    compute='_compute_invoice_type' store=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False store=True string='Balance sheet account / Spread account' args: 'account.account'
  • spread_action_type Selection
    default=_selection_default_spread_action_type selection=_selection_spread_action_type
  • spread_id Many2one → account.spread
    domain="[('id', 'in', spread_invoice_type_domain_ids)]" string='Spread Board' args: 'account.spread'
  • spread_invoice_type_domain_ids One2many → account.spread
    compute='_compute_spread_invoice_type_domain' args: 'account.spread'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False store=True string='Spread Journal' args: 'account.journal'
  • spread_type Selection
    compute='_compute_invoice_type' store=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too."
Public methods (1)
  • confirm(self)

New fields (5)
  • amount Float
    digits='Account' required=True
  • date Date
    required=True
  • move_id Many2one → account.move
    readonly=True string='Journal Entry' args: 'account.move'
  • name Char
    readonly=True args: 'Description'
  • spread_id Many2one → account.spread
    ondelete='cascade' args: 'account.spread'
Public methods (4)
  • create_and_reconcile_moves(self)
  • create_move(self)
    Button to manually create a move from a spread line entry.
  • open_move(self)
    Used by a button to manually view a move from a spread line entry.
  • unlink_move(self)
    Used by a button to manually unlink a move from a spread line entry.

New fields (12)
  • auto_spread Boolean
    help='If checked, provide option to auto create spread during invoice validation, based on product/account/analytic in invoice line.' string='Auto assign template on invoice validate'
  • auto_spread_ids One2many → account.spread.template.auto
    comodel_name='account.spread.template.auto' inverse_name='template_id' string='Auto Spread On'
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/Revenue Account' args: 'account.account'
  • name Char
    required=True
  • period_number Integer
    help='Define the number of spread lines' string='Number of Repetitions'
  • period_type Selection
    help='Period length for the entries' args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • spread_account_id Many2one → account.account
    compute='_compute_spread_account' readonly=False required=False store=True string='Spread Balance Sheet Account' args: 'account.account'
  • spread_journal_id Many2one → account.journal
    compute='_compute_spread_journal' readonly=False required=True store=True string='Journal' args: 'account.journal'
  • spread_type Selection
    default='sale' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • start_date Date
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too." string='Invoice account as spread account'
Public methods (1)
  • default_get(self, fields)
    @api.model

New fields (6)
  • account_id Many2one → account.account
    comodel_name='account.account' string='Account'
  • analytic_account_id Many2one → account.analytic.account
    comodel_name='account.analytic.account' string='Analytic'
  • company_id Many2one
    related='template_id.company_id' store=True
  • name Char
    default='/' required=True
  • product_id Many2one → product.product
    comodel_name='product.product' string='Product'
  • template_id Many2one → account.spread.template
    comodel_name='account.spread.template' index=True ondelete='cascade' required=True string='Spread Template'
Public methods (0)

No public methods.

New fields (7)
  • allow_spread_planning Boolean
    default=True help='Disable this option if you do not want to allow the spreading before the invoice is validated.'
  • auto_archive_spread Boolean
    help='Enable this option if you want the cron job to automatically archive the spreads when all lines are posted.' args: 'Auto-archive spread'
  • default_spread_expense_account_id Many2one → account.account
    string='Expense Spread Account' args: 'account.account'
  • default_spread_expense_journal_id Many2one → account.journal
    string='Expense Spread Journal' args: 'account.journal'
  • default_spread_revenue_account_id Many2one → account.account
    string='Revenue Spread Account' args: 'account.account'
  • default_spread_revenue_journal_id Many2one → account.journal
    string='Revenue Spread Journal' args: 'account.journal'
  • force_move_auto_post Boolean
    help='Enable this option if you want to post automatically the accounting moves of all the spreads.' args: 'Auto-post spread lines'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/account-financial-tools
GIT
GIThttps://github.com/OCA/account-financial-tools.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/account-financial-tools/tree/12.0/account_spread_cost_revenue
VERSION
VERSION 1.2.1
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Onestein
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Onestein
COMMITTERS
COMMITTERSGitHub, Andrea, OCA Transbot, oca-travis, Weblate, OCA-git-bot, sergiocorato, antonio, Kitti U
WEBSITE
WEBSITEhttps://github.com/OCA/account-financial-tools
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:29:18
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - account
    - base_setup
    - base
    - web
    - product
    - decimal_precision
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - http_routing
    - digest
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (11)
XML IDNameModelTypeStatus
assets_backend account spread ir.ui.view qweb Inherits web.assets_backend
view_account_spread account.spread form New
view_account_spread_account_manager account.spread tree Inherits view_account_spread
view_account_spread_invoice_line_link_wizard account.spread.invoice.line.link.wizard form New
view_account_spread_search account.spread search New
view_account_spread_template account.spread.template form New
view_account_spread_template_tree account.spread.template tree New
view_account_spread_tree account.spread tree New
view_company_form res.company xpath Inherits base.view_company_form
view_customer_invoice_spread account.invoice xpath Inherits account.invoice_form
view_supplier_invoice_spread account.invoice xpath Inherits account.invoice_supplier_form
Models touched (8)

New fields (0)

No new fields.

Public methods (4)
  • action_cancel(self)
    @api.multi
    Cancel the spread lines and their related moves when the invoice is canceled.
  • action_invoice_open(self)
  • action_move_create(self)
    @api.multi
    Invoked when validating the invoices.
  • invoice_line_move_line_get(self)
    @api.multi
    Copying expense/revenue account from spread to move lines.

New fields (2)
  • spread_check Selection
    compute='_compute_spread_check' args: [('linked', 'Linked'), ('unlinked', 'Unlinked'), ('unavailable', 'Unavailable')]
  • spread_id Many2one → account.spread
    copy=False string='Spread Board' args: 'account.spread'
Public methods (2)
  • create_auto_spread(self)
    Create auto spread table for each invoice line, when needed
  • spread_details(self)
    @api.multi
    Button on the invoice lines tree view of the invoice form to show the spread form view.

New fields (32)
  • account_analytic_id Many2one → account.analytic.account
    string='Analytic Account' args: 'account.analytic.account'
  • active Boolean
    default=True
  • all_posted Boolean
    compute='_compute_amounts' store=True
  • analytic_tag_ids Many2many → account.analytic.tag
    string='Analytic Tags' args: 'account.analytic.tag'
  • company_id Many2one → res.company
    default=<expr> required=True string='Company' args: 'res.company'
  • credit_account_id Many2one → account.account
    required=True string='Credit Account' args: 'account.account'
  • currency_id Many2one → res.currency
    default=<expr> required=True string='Currency' args: 'res.currency'
  • debit_account_id Many2one → account.account
    required=True string='Debit Account' args: 'account.account'
  • display_create_all_moves Boolean
    compute='_compute_display_create_all_moves' string='Display Button All Moves'
  • display_move_line_auto_post Boolean
    compute='_compute_display_move_line_auto_post' string='Display Button Auto-post lines'
  • display_recompute_buttons Boolean
    compute='_compute_display_recompute_buttons' string='Display Buttons Recompute'
  • estimated_amount Float
    digits=dp.get_precision('Account')
  • invoice_id Many2one
    readonly=True related='invoice_line_id.invoice_id' store=True string='Invoice'
  • invoice_line_id Many2one → account.invoice.line
    compute='_compute_invoice_line' inverse='_inverse_invoice_line' store=True string='Invoice line' args: 'account.invoice.line'
  • invoice_line_ids One2many → account.invoice.line
    copy=False string='Invoice Lines' args: 'account.invoice.line', 'spread_id'
  • invoice_type Selection
    required=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • is_credit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • is_debit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • journal_id Many2one → account.journal
    required=True string='Journal' args: 'account.journal'
  • line_ids One2many → account.spread.line
    string='Spread Lines' args: 'account.spread.line', 'spread_id'
  • move_line_auto_post Boolean
    default=True args: 'Auto-post lines'
  • name Char
    required=True
  • period_number Integer
    default=12 help='Define the number of spread lines' required=True string='Number of Repetitions'
  • period_type Selection
    default='month' help='Period length for the entries' required=True args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • posted_amount Float
    compute='_compute_amounts' digits=dp.get_precision('Account')
  • spread_date Date
    default=time.strftime('%Y-01-01') required=True string='Start Date'
  • spread_type Selection
    compute='_compute_spread_type' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • total_amount Float
    compute='_compute_amounts' digits=dp.get_precision('Account')
  • unposted_amount Float
    compute='_compute_amounts' digits=dp.get_precision('Account')
  • unspread_amount Float
    compute='_compute_amounts' digits=dp.get_precision('Account')
  • use_invoice_line_account Boolean
    string="Use invoice line's account"
Public methods (11)
  • action_recalculate_spread(self)
    @api.multi
    Recalculate spread
  • action_undo_spread(self)
    @api.multi
    Undo spreading: Remove all created moves, restore original account on move line
  • action_unlink_invoice_line(self)
    @api.multi
    Unlink the invoice line from the spread board
  • compute_spread_board(self)
    @api.multi
    Checks whether the spread lines should be calculated. In case checks pass, invoke "def _compute_spread_board()" method.
  • create_all_moves(self)
    @api.multi
  • default_get(self, fields)
    @api.model
  • onchange_invoice_type(self)
    @api.onchange('invoice_type', 'company_id')
  • onchange_template(self)
    @api.onchange('template_id')
  • open_reconcile_view(self)
    @api.multi
  • reconcile_spread_moves(self)
    @api.multi
  • unlink(self)
    @api.multi

New fields (12)
  • company_id Many2one → res.company
    required=True string='Company' args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/revenue account' args: 'account.account'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.invoice_id'
  • invoice_line_id Many2one → account.invoice.line
    ondelete='cascade' readonly=True required=True string='Invoice Line' args: 'account.invoice.line'
  • invoice_type Selection
    compute='_compute_invoice_type' store=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • spread_account_id Many2one → account.account
    store=True string='Balance sheet account / Spread account' args: 'account.account'
  • spread_action_type Selection
    default=_selection_default_spread_action_type selection=_selection_spread_action_type
  • spread_id Many2one → account.spread
    string='Spread Board' args: 'account.spread'
  • spread_journal_id Many2one → account.journal
    store=True string='Spread Journal' args: 'account.journal'
  • spread_type Selection
    compute='_compute_invoice_type' store=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too." string="Use invoice line's account"
Public methods (2)
  • confirm(self)
    @api.multi
  • onchange_invoice_type(self)
    @api.onchange('invoice_type')

New fields (5)
  • amount Float
    digits=dp.get_precision('Account') required=True
  • date Date
    required=True
  • move_id Many2one → account.move
    readonly=True string='Journal Entry' args: 'account.move'
  • name Char
    readonly=True args: 'Description'
  • spread_id Many2one → account.spread
    ondelete='cascade' string='Spread Board' args: 'account.spread'
Public methods (4)
  • create_and_reconcile_moves(self)
    @api.multi
  • create_move(self)
    @api.multi
    Button to manually create a move from a spread line entry.
  • open_move(self)
    @api.multi
    Used by a button to manually view a move from a spread line entry.
  • unlink_move(self)
    @api.multi
    Used by a button to manually unlink a move from a spread line entry.

New fields (12)
  • auto_spread Boolean
    help='If checked, provide option to auto create spread during invoice validation, based on product/account/analytic in invoice line.' string='Auto assign template on invoice validate'
  • auto_spread_ids One2many → account.spread.template.auto
    comodel_name='account.spread.template.auto' inverse_name='template_id' string='Auto Spread On'
  • company_id Many2one → res.company
    default=<expr> required=True string='Company' args: 'res.company'
  • exp_rev_account_id Many2one → account.account
    help='Optional account to overwrite the existing expense/revenue account' string='Expense/Revenue Account' args: 'account.account'
  • name Char
    required=True
  • period_number Integer
    help='Define the number of spread lines' string='Number of Repetitions'
  • period_type Selection
    help='Period length for the entries' args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • spread_account_id Many2one → account.account
    required=False string='Spread Balance Sheet Account' args: 'account.account'
  • spread_journal_id Many2one → account.journal
    required=True string='Journal' args: 'account.journal'
  • spread_type Selection
    default='sale' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • start_date Date
  • use_invoice_line_account Boolean
    help="Use invoice line's account as Balance sheet / spread account.\nIn this case, user need to select expense/revenue account too." string='Invoice account as spread account'
Public methods (2)
  • default_get(self, fields)
    @api.model
  • onchange_spread_type(self)
    @api.onchange('spread_type', 'company_id')

New fields (6)
  • account_id Many2one → account.account
    comodel_name='account.account' string='Account'
  • analytic_account_id Many2one → account.analytic.account
    comodel_name='account.analytic.account' string='Analytic'
  • company_id Many2one
    related='template_id.company_id' store=True
  • name Char
    default='/' required=True
  • product_id Many2one → product.product
    comodel_name='product.product' string='Product'
  • template_id Many2one → account.spread.template
    comodel_name='account.spread.template' index=True ondelete='cascade' required=True string='Spread Template'
Public methods (0)

No public methods.

New fields (7)
  • allow_spread_planning Boolean
    default=True help='Disable this option if you do not want to allow the spreading before the invoice is validated.'
  • auto_archive Boolean
    help='Enable this option if you want the cron job to automatically archive the spreads when all lines are posted.' args: 'Auto-archive spread'
  • default_spread_expense_account_id Many2one → account.account
    string='Expense Spread Account' args: 'account.account'
  • default_spread_expense_journal_id Many2one → account.journal
    string='Expense Spread Journal' args: 'account.journal'
  • default_spread_revenue_account_id Many2one → account.account
    string='Revenue Spread Account' args: 'account.account'
  • default_spread_revenue_journal_id Many2one → account.journal
    string='Revenue Spread Journal' args: 'account.journal'
  • force_move_auto_post Boolean
    help='Enable this option if you want to post automatically the accounting moves of all the spreads.' args: 'Auto-post spread lines'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/account-financial-tools
GIT
GIThttps://github.com/OCA/account-financial-tools.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/account-financial-tools/tree/11.0/account_spread_cost_revenue
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYAccounting & Finance
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Onestein
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Onestein
COMMITTERS
COMMITTERSAndrea, OCA Transbot, oca-travis, OCA-git-bot
WEBSITE
WEBSITEhttps://github.com/OCA/account-financial-tools/
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:23:58
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - account
    - base_setup
    - base
    - web
    - product
    - decimal_precision
    - mail
    - bus
    - web_tour
    - analytic
    - web_planner
    - portal
    - http_routing
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (11)
XML IDNameModelTypeStatus
assets_backend account spread ir.ui.view qweb Inherits web.assets_backend
view_account_spread account.spread form New
view_account_spread_account_manager account.spread tree Inherits view_account_spread
view_account_spread_invoice_line_link_wizard account.spread.invoice.line.link.wizard form New
view_account_spread_search account.spread search New
view_account_spread_template account.spread.template form New
view_account_spread_template_tree account.spread.template tree New
view_account_spread_tree account.spread tree New
view_company_form res.company xpath Inherits base.view_company_form
view_customer_invoice_spread account.invoice xpath Inherits account.invoice_form
view_supplier_invoice_spread account.invoice xpath Inherits account.invoice_supplier_form
Models touched (7)

New fields (0)

No new fields.

Public methods (3)
  • action_cancel(self)
    @api.multi
    Cancel the spread lines and their related moves when the invoice is canceled.
  • action_move_create(self)
    @api.multi
    Invoked when validating the invoices.
  • invoice_line_move_line_get(self)
    @api.multi
    Copying expense/revenue account from spread to move lines.

New fields (2)
  • spread_check Selection
    compute='_compute_spread_check' args: [('linked', 'Linked'), ('unlinked', 'Unlinked'), ('unavailable', 'Unavailable')]
  • spread_id Many2one → account.spread
    copy=False string='Spread Board' args: 'account.spread'
Public methods (1)
  • spread_details(self)
    @api.multi
    Button on the invoice lines tree view of the invoice form to show the spread form view.

New fields (31)
  • account_analytic_id Many2one → account.analytic.account
    string='Analytic Account' args: 'account.analytic.account'
  • active Boolean
    default=True
  • all_posted Boolean
    compute='_compute_amounts' store=True
  • analytic_tag_ids Many2many → account.analytic.tag
    string='Analytic Tags' args: 'account.analytic.tag'
  • company_id Many2one → res.company
    default=<expr> required=True string='Company' args: 'res.company'
  • credit_account_id Many2one → account.account
    required=True string='Credit Account' args: 'account.account'
  • currency_id Many2one → res.currency
    default=<expr> required=True string='Currency' args: 'res.currency'
  • debit_account_id Many2one → account.account
    required=True string='Debit Account' args: 'account.account'
  • display_create_all_moves Boolean
    compute='_compute_display_create_all_moves' string='Display Button All Moves'
  • display_move_line_auto_post Boolean
    compute='_compute_display_move_line_auto_post' string='Display Button Auto-post lines'
  • display_recompute_buttons Boolean
    compute='_compute_display_recompute_buttons' string='Display Buttons Recompute'
  • estimated_amount Float
    digits=dp.get_precision('Account')
  • invoice_id Many2one
    readonly=True related='invoice_line_id.invoice_id' store=True string='Invoice'
  • invoice_line_id Many2one → account.invoice.line
    compute='_compute_invoice_line' inverse='_inverse_invoice_line' store=True string='Invoice line' args: 'account.invoice.line'
  • invoice_line_ids One2many → account.invoice.line
    copy=False string='Invoice Lines' args: 'account.invoice.line', 'spread_id'
  • invoice_type Selection
    required=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • is_credit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • is_debit_account_deprecated Boolean
    compute='_compute_deprecated_accounts'
  • journal_id Many2one → account.journal
    required=True string='Journal' args: 'account.journal'
  • line_ids One2many → account.spread.line
    string='Spread Lines' args: 'account.spread.line', 'spread_id'
  • move_line_auto_post Boolean
    default=True args: 'Auto-post lines'
  • name Char
    required=True
  • period_number Integer
    default=12 help='Define the number of spread lines' required=True string='Number of Repetitions'
  • period_type Selection
    default='month' help='Period length for the entries' required=True args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • posted_amount Float
    compute='_compute_amounts' digits=dp.get_precision('Account')
  • spread_date Date
    default=time.strftime('%Y-01-01') required=True string='Start Date'
  • spread_type Selection
    compute='_compute_spread_type' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
  • total_amount Float
    compute='_compute_amounts' digits=dp.get_precision('Account')
  • unposted_amount Float
    compute='_compute_amounts' digits=dp.get_precision('Account')
  • unspread_amount Float
    compute='_compute_amounts' digits=dp.get_precision('Account')
Public methods (11)
  • action_recalculate_spread(self)
    @api.multi
    Recalculate spread
  • action_undo_spread(self)
    @api.multi
    Undo spreading: Remove all created moves, restore original account on move line
  • action_unlink_invoice_line(self)
    @api.multi
    Unlink the invoice line from the spread board
  • compute_spread_board(self)
    @api.multi
    Checks whether the spread lines should be calculated. In case checks pass, invoke "def _compute_spread_board()" method.
  • create_all_moves(self)
    @api.multi
  • default_get(self, fields)
    @api.model
  • onchange_invoice_type(self)
    @api.onchange('invoice_type', 'company_id')
  • onchange_template(self)
    @api.onchange('template_id')
  • open_reconcile_view(self)
    @api.multi
  • reconcile_spread_moves(self)
    @api.multi
  • unlink(self)
    @api.multi

New fields (10)
  • company_id Many2one → res.company
    required=True string='Company' args: 'res.company'
  • invoice_id Many2one
    readonly=True related='invoice_line_id.invoice_id'
  • invoice_line_id Many2one → account.invoice.line
    ondelete='cascade' readonly=True required=True string='Invoice Line' args: 'account.invoice.line'
  • invoice_type Selection
    compute='_compute_invoice_type' store=True args: [('out_invoice', 'Customer Invoice'), ('in_invoice', 'Vendor Bill'), ('out_refund', 'Customer Credit Note'), ('in_refund', 'Vendor Credit Note')]
  • spread_account_id Many2one → account.account
    store=True string='Balance sheet account / Spread account' args: 'account.account'
  • spread_action_type Selection
    default=_selection_default_spread_action_type selection=_selection_spread_action_type
  • spread_id Many2one → account.spread
    string='Spread Board' args: 'account.spread'
  • spread_journal_id Many2one → account.journal
    store=True string='Spread Journal' args: 'account.journal'
  • spread_type Selection
    compute='_compute_invoice_type' store=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • template_id Many2one → account.spread.template
    string='Spread Template' args: 'account.spread.template'
Public methods (2)
  • confirm(self)
    @api.multi
  • onchange_invoice_type(self)
    @api.onchange('invoice_type')

New fields (5)
  • amount Float
    digits=dp.get_precision('Account') required=True
  • date Date
    required=True
  • move_id Many2one → account.move
    readonly=True string='Journal Entry' args: 'account.move'
  • name Char
    readonly=True args: 'Description'
  • spread_id Many2one → account.spread
    ondelete='cascade' string='Spread Board' args: 'account.spread'
Public methods (4)
  • create_and_reconcile_moves(self)
    @api.multi
  • create_move(self)
    @api.multi
    Button to manually create a move from a spread line entry.
  • open_move(self)
    @api.multi
    Used by a button to manually view a move from a spread line entry.
  • unlink_move(self)
    @api.multi
    Used by a button to manually unlink a move from a spread line entry.

New fields (8)
  • company_id Many2one → res.company
    default=<expr> required=True string='Company' args: 'res.company'
  • name Char
    required=True
  • period_number Integer
    help='Define the number of spread lines' string='Number of Repetitions'
  • period_type Selection
    help='Period length for the entries' args: [('month', 'Month'), ('quarter', 'Quarter'), ('year', 'Year')]
  • spread_account_id Many2one → account.account
    required=True string='Spread Balance Sheet Account' args: 'account.account'
  • spread_journal_id Many2one → account.journal
    required=True string='Journal' args: 'account.journal'
  • spread_type Selection
    default='sale' required=True args: [('sale', 'Customer'), ('purchase', 'Supplier')]
  • start_date Date
Public methods (2)
  • default_get(self, fields)
    @api.model
  • onchange_spread_type(self)
    @api.onchange('spread_type', 'company_id')

New fields (7)
  • allow_spread_planning Boolean
    default=True help='Disable this option if you do not want to allow the spreading before the invoice is validated.'
  • auto_archive Boolean
    help='Enable this option if you want the cron job to automatically archive the spreads when all lines are posted.' args: 'Auto-archive spread'
  • default_spread_expense_account_id Many2one → account.account
    string='Expense Spread Account' args: 'account.account'
  • default_spread_expense_journal_id Many2one → account.journal
    string='Expense Spread Journal' args: 'account.journal'
  • default_spread_revenue_account_id Many2one → account.account
    string='Revenue Spread Account' args: 'account.account'
  • default_spread_revenue_journal_id Many2one → account.journal
    string='Revenue Spread Journal' args: 'account.journal'
  • force_move_auto_post Boolean
    help='Enable this option if you want to post automatically the accounting moves of all the spreads.' args: 'Auto-post spread lines'
Public methods (0)

No public methods.

STATUS
STATUSOpen migration PR - not merged yet for this version
REPOSITORY
REPOSITORYOCA/account-financial-tools
PULL REQUEST
PULL REQUEST[19.0][MIG] account_spread_cost_revenue: Migration to 19.0 (#2208)