Sales Invoice Plan

sale_invoice_plan
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/18.0/sale_invoice_plan
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYSales
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Ecosoft
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Ecosoft
COMMITTERS
COMMITTERSRuchir Shukla, Weblate, OCA-git-bot, oca-ci
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:11
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
    - sale_management
    - sale
    - sales_team
    - account_payment
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
By standard feature, user can gradually create partial invoices, one by
one. This module add ability to create invoices based on the predefined
invoice plan, either all at once, or one by one. The plan support both
advance invoice and installment invoices.

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
view_order_form_invoice_plan view.order.form.invoice.plan sale.order xpath Inherits sale.view_order_form
view_sale_create_invoice_plan Create Invoice Plan sale.create.invoice.plan form New
view_sale_invoice_plan_filter view.sale.invoice.plan.filter sale.invoice.plan search New
view_sale_invoice_plan_form view.sale.invoice.plan.form sale.invoice.plan form New
view_sale_invoice_plan_list view.sale.invoice.plan.list sale.invoice.plan list New
view_sale_invoice_plan_list_readonly view.sale.invoice.plan.list sale.invoice.plan list New
view_sale_make_planned_invoice Invoice Orders sale.make.planned.invoice form New
Models touched (5)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • advance Boolean
    default=False string='Advance on 1st Invoice'
  • installment_date Date
    default=fields.Date.context_today required=True
  • interval Integer
    default=1 required=True
  • interval_type Selection
    default='month' required=True args: [('day', 'Day'), ('month', 'Month'), ('year', 'Year')]
  • num_installment Integer
    default=0 required=True string='Number of Installment'
Public methods (1)
  • sale_create_invoice_plan(self)

New fields (15)
  • amount Float
    compute='_compute_amount' digits='Product Price' help='This amount will be used to calculate the percent' inverse='_inverse_amount'
  • amount_invoiced Float
    compute='_compute_invoiced' store=True
  • distribution_analytic_account_ids Many2many → account.analytic.account
    compute='_compute_distribution_analytic_account_ids' store=True string='Distribution Analytic Accounts' args: 'account.analytic.account'
  • installment Integer
  • invoice_move_ids Many2many → account.move
    column1='plan_id' column2='move_id' readonly=True relation='sale_invoice_plan_invoice_rel' string='Invoices' args: 'account.move'
  • invoice_type Selection
    default='installment' required=True string='Type' args: [('advance', 'Advance'), ('installment', 'Installment')]
  • invoiced Boolean
    compute='_compute_invoiced' help='If this line already invoiced' store=True string='Invoice Created'
  • last Boolean
    compute='_compute_last' help='Last installment will create invoice use remaining amount' string='Last Installment'
  • no_edit Boolean
    compute='_compute_no_edit'
  • partner_id Many2one → res.partner
    comodel_name='res.partner' index=True related='sale_id.partner_id' store=True string='Customer'
  • percent Float
    digits='Sales Invoice Plan Percent' help='This percent will be used to calculate new quantity'
  • plan_date Date
    required=True
  • sale_id Many2one → sale.order
    comodel_name='sale.order' index=True ondelete='cascade' readonly=True string='Sales Order'
  • state Selection
    index=True related='sale_id.state' store=True string='Status'
  • to_invoice Boolean
    compute='_compute_to_invoice' help='If this line is ready to create new invoice' string='Next Invoice'
Public methods (1)
  • unlink(self)

New fields (0)

No new fields.

Public methods (1)
  • create_invoices_by_plan(self)

New fields (5)
  • invoice_plan_ids One2many → sale.invoice.plan
    comodel_name='sale.invoice.plan' copy=False inverse_name='sale_id'
  • invoice_plan_process Boolean
    compute='_compute_invoice_plan_process' help='At least one invoice plan line pending to create invoice' string='Invoice Plan In Process'
  • invoice_plan_total_amount Monetary
    compute='_compute_invoice_plan_total' string='Total Plan Amount'
  • invoice_plan_total_percent Float
    compute='_compute_invoice_plan_total' string='Percent'
  • use_invoice_plan Boolean
    copy=False default=False
Public methods (3)
  • action_confirm(self)
  • create_invoice_plan(self, num_installment, installment_date, interval, interval_type, advance)
  • remove_invoice_plan(self)
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/17.0/sale_invoice_plan
VERSION
VERSION 1.0.1
CATEGORY
CATEGORYSales
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Ecosoft
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Ecosoft
COMMITTERS
COMMITTERSRaphaël Valyi, OCA-git-bot, oca-ci, Reinier Quevedo Batista
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:20:05
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
    - sale_management
    - sale
    - sales_team
    - account_payment
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
By standard feature, user can gradually create partial invoices, one by
one. This module add ability to create invoices based on the predefined
invoice plan, either all at once, or one by one. The plan support both
advance invoice and installment invoices.

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
view_order_form_invoice_plan view.order.form.invoice.plan sale.order xpath Inherits sale.view_order_form
view_sale_create_invoice_plan Create Invoice Plan sale.create.invoice.plan form New
view_sale_invoice_plan_filter view.sale.invoice.plan.filter sale.invoice.plan search New
view_sale_invoice_plan_form view.sale.invoice.plan.form sale.invoice.plan form New
view_sale_invoice_plan_tree view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_invoice_plan_tree_readonly view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_make_planned_invoice Invoice Orders sale.make.planned.invoice form New
Models touched (5)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • advance Boolean
    default=False string='Advance on 1st Invoice'
  • installment_date Date
    default=fields.Date.context_today required=True
  • interval Integer
    default=1 required=True
  • interval_type Selection
    default='month' required=True args: [('day', 'Day'), ('month', 'Month'), ('year', 'Year')]
  • num_installment Integer
    default=0 required=True string='Number of Installment'
Public methods (1)
  • sale_create_invoice_plan(self)

New fields (15)
  • amount Float
    compute='_compute_amount' digits='Product Price' help='This amount will be used to calculate the percent' inverse='_inverse_amount'
  • amount_invoiced Float
    compute='_compute_invoiced' store=True
  • analytic_account_id Many2one
    related='sale_id.analytic_account_id'
  • installment Integer
  • invoice_move_ids Many2many → account.move
    column1='plan_id' column2='move_id' relation='sale_invoice_plan_invoice_rel' string='Invoices' args: 'account.move'
  • invoice_type Selection
    default='installment' required=True string='Type' args: [('advance', 'Advance'), ('installment', 'Installment')]
  • invoiced Boolean
    compute='_compute_invoiced' help='If this line already invoiced' store=True string='Invoice Created'
  • last Boolean
    compute='_compute_last' help='Last installment will create invoice use remaining amount' string='Last Installment'
  • no_edit Boolean
    compute='_compute_no_edit'
  • partner_id Many2one → res.partner
    comodel_name='res.partner' index=True related='sale_id.partner_id' store=True string='Customer'
  • percent Float
    digits='Sales Invoice Plan Percent' help='This percent will be used to calculate new quantity'
  • plan_date Date
    required=True
  • sale_id Many2one → sale.order
    comodel_name='sale.order' index=True ondelete='cascade' string='Sales Order'
  • state Selection
    index=True related='sale_id.state' store=True string='Status'
  • to_invoice Boolean
    compute='_compute_to_invoice' help='If this line is ready to create new invoice' string='Next Invoice'
Public methods (1)
  • unlink(self)

New fields (0)

No new fields.

Public methods (1)
  • create_invoices_by_plan(self)

New fields (5)
  • invoice_plan_ids One2many → sale.invoice.plan
    comodel_name='sale.invoice.plan' copy=False inverse_name='sale_id' string='Inovice Plan'
  • invoice_plan_process Boolean
    compute='_compute_invoice_plan_process' help='At least one invoice plan line pending to create invoice' string='Invoice Plan In Process'
  • invoice_plan_total_amount Monetary
    compute='_compute_invoice_plan_total' string='Total Amount'
  • invoice_plan_total_percent Float
    compute='_compute_invoice_plan_total' string='Percent'
  • use_invoice_plan Boolean
    copy=False default=False
Public methods (3)
  • action_confirm(self)
  • create_invoice_plan(self, num_installment, installment_date, interval, interval_type, advance)
  • remove_invoice_plan(self)
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/16.0/sale_invoice_plan
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYSales
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Ecosoft
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Ecosoft
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, oca-ci, theerayut
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:53:45
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
    - sale_management
    - sale
    - sales_team
    - account_payment
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
view_order_form_invoice_plan view.order.form.invoice.plan sale.order xpath Inherits sale.view_order_form
view_sale_create_invoice_plan Create Invoice Plan sale.create.invoice.plan form New
view_sale_invoice_plan_filter view.sale.invoice.plan.filter sale.invoice.plan search New
view_sale_invoice_plan_form view.sale.invoice.plan.form sale.invoice.plan form New
view_sale_invoice_plan_tree view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_invoice_plan_tree_readonly view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_make_planned_invoice Invoice Orders sale.make.planned.invoice form New
Models touched (5)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • advance Boolean
    default=False string='Advance on 1st Invoice'
  • installment_date Date
    default=fields.Date.context_today required=True
  • interval Integer
    default=1 required=True
  • interval_type Selection
    default='month' required=True args: [('day', 'Day'), ('month', 'Month'), ('year', 'Year')]
  • num_installment Integer
    default=0 required=True string='Number of Installment'
Public methods (1)
  • sale_create_invoice_plan(self)

New fields (15)
  • amount Float
    compute='_compute_amount' digits='Product Price' help='This amount will be used to calculate the percent' inverse='_inverse_amount'
  • amount_invoiced Float
    compute='_compute_invoiced' store=True
  • analytic_account_id Many2one
    related='sale_id.analytic_account_id'
  • installment Integer
  • invoice_move_ids Many2many → account.move
    column1='plan_id' column2='move_id' readonly=True relation='sale_invoice_plan_invoice_rel' string='Invoices' args: 'account.move'
  • invoice_type Selection
    default='installment' required=True string='Type' args: [('advance', 'Advance'), ('installment', 'Installment')]
  • invoiced Boolean
    compute='_compute_invoiced' help='If this line already invoiced' store=True string='Invoice Created'
  • last Boolean
    compute='_compute_last' help='Last installment will create invoice use remaining amount' string='Last Installment'
  • no_edit Boolean
    compute='_compute_no_edit'
  • partner_id Many2one → res.partner
    comodel_name='res.partner' index=True related='sale_id.partner_id' store=True string='Customer'
  • percent Float
    digits='Sales Invoice Plan Percent' help='This percent will be used to calculate new quantity'
  • plan_date Date
    required=True
  • sale_id Many2one → sale.order
    comodel_name='sale.order' index=True ondelete='cascade' readonly=True string='Sales Order'
  • state Selection
    index=True related='sale_id.state' store=True string='Status'
  • to_invoice Boolean
    compute='_compute_to_invoice' help='If this line is ready to create new invoice' string='Next Invoice'
Public methods (1)
  • unlink(self)

New fields (0)

No new fields.

Public methods (1)
  • create_invoices_by_plan(self)

New fields (5)
  • invoice_plan_ids One2many → sale.invoice.plan
    comodel_name='sale.invoice.plan' copy=False inverse_name='sale_id' string='Inovice Plan'
  • invoice_plan_process Boolean
    compute='_compute_invoice_plan_process' help='At least one invoice plan line pending to create invoice' string='Invoice Plan In Process'
  • invoice_plan_total_amount Monetary
    compute='_compute_invoice_plan_total' string='Total Amount'
  • invoice_plan_total_percent Float
    compute='_compute_invoice_plan_total' string='Percent'
  • use_invoice_plan Boolean
    copy=False default=False
Public methods (3)
  • action_confirm(self)
  • create_invoice_plan(self, num_installment, installment_date, interval, interval_type, advance)
  • remove_invoice_plan(self)
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/15.0/sale_invoice_plan
VERSION
VERSION 1.4.2
CATEGORY
CATEGORYSales
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Ecosoft
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Ecosoft
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, oca-ci, Kitti U, Maksym Yankin, Saran440, CarlosRoca13, Marcel Savegnago, ps-tubtim, Cesar Andres Sanchez, Joan Mateu Jordi, Camille Morand
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:46:33
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
    - sale_management
    - sale
    - sales_team
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
view_order_form_invoice_plan view.order.form.invoice.plan sale.order xpath Inherits sale.view_order_form
view_sale_create_invoice_plan Create Invoice Plan sale.create.invoice.plan form New
view_sale_invoice_plan_filter view.sale.invoice.plan.filter sale.invoice.plan search New
view_sale_invoice_plan_form view.sale.invoice.plan.form sale.invoice.plan form New
view_sale_invoice_plan_tree view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_invoice_plan_tree_readonly view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_make_planned_invoice Invoice Orders sale.make.planned.invoice form New
Models touched (5)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • advance Boolean
    default=False string='Advance on 1st Invoice'
  • installment_date Date
    default=fields.Date.context_today required=True
  • interval Integer
    default=1 required=True
  • interval_type Selection
    default='month' required=True args: [('day', 'Day'), ('month', 'Month'), ('year', 'Year')]
  • num_installment Integer
    default=0 required=True string='Number of Installment'
Public methods (1)
  • sale_create_invoice_plan(self)

New fields (15)
  • amount Float
    compute='_compute_amount' digits='Product Price' help='This amount will be used to calculate the percent' inverse='_inverse_amount'
  • amount_invoiced Float
    compute='_compute_invoiced'
  • analytic_account_id Many2one
    related='sale_id.analytic_account_id'
  • installment Integer
  • invoice_move_ids Many2many → account.move
    column1='plan_id' column2='move_id' readonly=True relation='sale_invoice_plan_invoice_rel' string='Invoices' args: 'account.move'
  • invoice_type Selection
    default='installment' required=True string='Type' args: [('advance', 'Advance'), ('installment', 'Installment')]
  • invoiced Boolean
    compute='_compute_invoiced' help='If this line already invoiced' string='Invoice Created'
  • last Boolean
    compute='_compute_last' help='Last installment will create invoice use remaining amount' string='Last Installment'
  • no_edit Boolean
    compute='_compute_no_edit'
  • partner_id Many2one → res.partner
    comodel_name='res.partner' index=True related='sale_id.partner_id' store=True string='Customer'
  • percent Float
    digits='Sales Invoice Plan Percent' help='This percent will be used to calculate new quantity'
  • plan_date Date
    required=True
  • sale_id Many2one → sale.order
    comodel_name='sale.order' index=True ondelete='cascade' readonly=True string='Sales Order'
  • state Selection
    index=True related='sale_id.state' store=True string='Status'
  • to_invoice Boolean
    compute='_compute_to_invoice' help='If this line is ready to create new invoice' string='Next Invoice'
Public methods (1)
  • unlink(self)

New fields (0)

No new fields.

Public methods (1)
  • create_invoices_by_plan(self)

New fields (5)
  • invoice_plan_ids One2many → sale.invoice.plan
    comodel_name='sale.invoice.plan' copy=False inverse_name='sale_id' string='Inovice Plan'
  • invoice_plan_process Boolean
    compute='_compute_invoice_plan_process' help='At least one invoice plan line pending to create invoice' string='Invoice Plan In Process'
  • invoice_plan_total_amount Monetary
    compute='_compute_invoice_plan_total' string='Total Amount'
  • invoice_plan_total_percent Float
    compute='_compute_invoice_plan_total' string='Percent'
  • use_invoice_plan Boolean
    copy=False default=False
Public methods (3)
  • action_confirm(self)
  • create_invoice_plan(self, num_installment, installment_date, interval, interval_type, advance)
  • remove_invoice_plan(self)
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/14.0/sale_invoice_plan
VERSION
VERSION 1.0.5
CATEGORY
CATEGORYSales
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Ecosoft
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Ecosoft
COMMITTERS
COMMITTERSThierry Ducrest, oca-travis, Weblate, OCA-git-bot, Kitti U, Marcel Savegnago, Ilyas, sonhd
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:40:57
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
    - sale_management
    - sale
    - sales_team
    - payment
    - utm
    - sale_stock
    - stock_account
    - stock
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
view_order_form_invoice_plan view.order.form.invoice.plan sale.order xpath Inherits sale.view_order_form
view_sale_create_invoice_plan Create Invoice Plan sale.create.invoice.plan form New
view_sale_invoice_plan_filter view.sale.invoice.plan.filter sale.invoice.plan search New
view_sale_invoice_plan_form view.sale.invoice.plan.form sale.invoice.plan form New
view_sale_invoice_plan_tree view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_invoice_plan_tree_readonly view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_make_planned_invoice Invoice Orders sale.make.planned.invoice form New
Models touched (5)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • advance Boolean
    default=False string='Advance on 1st Invoice'
  • installment_date Date
    default=fields.Date.context_today required=True string='Installment Date'
  • interval Integer
    default=1 required=True string='Interval'
  • interval_type Selection
    default='month' required=True string='Interval Type' args: [('day', 'Day'), ('month', 'Month'), ('year', 'Year')]
  • num_installment Integer
    default=0 required=True string='Number of Installment'
Public methods (1)
  • sale_create_invoice_plan(self)

New fields (11)
  • installment Integer
    string='Installment'
  • invoice_move_ids Many2many → account.move
    column1='plan_id' column2='move_id' readonly=True relation='sale_invoice_plan_invoice_rel' string='Invoices' args: 'account.move'
  • invoice_type Selection
    default='installment' required=True string='Type' args: [('advance', 'Advance'), ('installment', 'Installment')]
  • invoiced Boolean
    compute='_compute_invoiced' help='If this line already invoiced' string='Invoice Created'
  • last Boolean
    compute='_compute_last' help='Last installment will create invoice use remaining amount' string='Last Installment'
  • partner_id Many2one → res.partner
    comodel_name='res.partner' index=True related='sale_id.partner_id' store=True string='Customer'
  • percent Float
    digits='Product Unit of Measure' help='This percent will be used to calculate new quantity' string='Percent'
  • plan_date Date
    required=True string='Plan Date'
  • sale_id Many2one → sale.order
    comodel_name='sale.order' index=True ondelete='cascade' readonly=True string='Sales Order'
  • state Selection
    index=True related='sale_id.state' store=True string='Status'
  • to_invoice Boolean
    compute='_compute_to_invoice' help='If this line is ready to create new invoice' string='Next Invoice'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • create_invoices_by_plan(self)

New fields (3)
  • invoice_plan_ids One2many → sale.invoice.plan
    comodel_name='sale.invoice.plan' copy=False inverse_name='sale_id' string='Inovice Plan'
  • ip_invoice_plan Boolean
    compute='_compute_ip_invoice_plan' help='At least one invoice plan line pending to create invoice' string='Invoice Plan In Process'
  • use_invoice_plan Boolean
    copy=False default=False string='Use Invoice Plan'
Public methods (3)
  • action_confirm(self)
  • create_invoice_plan(self, num_installment, installment_date, interval, interval_type, advance)
  • remove_invoice_plan(self)
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/13.0/sale_invoice_plan
VERSION
VERSION 1.0.5
CATEGORY
CATEGORYSales
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Ecosoft
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Ecosoft
COMMITTERS
COMMITTERSPedro M. Baeza, Carlos Dauden, OCA Transbot, Ernesto Tejeda, oca-travis, Weblate, OCA-git-bot, oca-ci, Kitti U, Marcel Savegnago
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:34:12
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
    - sale_management
    - sale
    - sales_team
    - payment
    - utm
    - sale_stock
    - stock_account
    - stock
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
view_order_form_invoice_plan view.order.form.invoice.plan sale.order xpath Inherits sale.view_order_form
view_sale_create_invoice_plan Create Invoice Plan sale.create.invoice.plan form New
view_sale_invoice_plan_filter view.sale.invoice.plan.filter sale.invoice.plan search New
view_sale_invoice_plan_form view.sale.invoice.plan.form sale.invoice.plan form New
view_sale_invoice_plan_tree view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_invoice_plan_tree_readonly view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_make_planned_invoice Invoice Orders sale.make.planned.invoice form New
Models touched (5)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • advance Boolean
    default=False string='Advance on 1st Invoice'
  • installment_date Date
    default=fields.Date.context_today required=True string='Installment Date'
  • interval Integer
    default=1 required=True string='Interval'
  • interval_type Selection
    default='month' required=True string='Interval Type' args: [('day', 'Day'), ('month', 'Month'), ('year', 'Year')]
  • num_installment Integer
    default=0 required=True string='Number of Installment'
Public methods (1)
  • sale_create_invoice_plan(self)

New fields (11)
  • installment Integer
    string='Installment'
  • invoice_move_ids Many2many → account.move
    column1='plan_id' column2='move_id' readonly=True relation='sale_invoice_plan_invoice_rel' string='Invoices' args: 'account.move'
  • invoice_type Selection
    default='installment' required=True string='Type' args: [('advance', 'Advance'), ('installment', 'Installment')]
  • invoiced Boolean
    compute='_compute_invoiced' help='If this line already invoiced' string='Invoice Created'
  • last Boolean
    compute='_compute_last' help='Last installment will create invoice use remaining amount' string='Last Installment'
  • partner_id Many2one → res.partner
    comodel_name='res.partner' index=True related='sale_id.partner_id' store=True string='Customer'
  • percent Float
    digits='Product Unit of Measure' help='This percent will be used to calculate new quantity' string='Percent'
  • plan_date Date
    required=True string='Plan Date'
  • sale_id Many2one → sale.order
    comodel_name='sale.order' index=True ondelete='cascade' readonly=True string='Sales Order'
  • state Selection
    index=True related='sale_id.state' store=True string='Status' args: [('draft', 'Quotation'), ('sent', 'Quotation Sent'), ('sale', 'Sales Order'), ('done', 'Locked'), ('cancel', 'Cancelled')]
  • to_invoice Boolean
    compute='_compute_to_invoice' help='If this line is ready to create new invoice' string='Next Invoice'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • create_invoices_by_plan(self)

New fields (3)
  • invoice_plan_ids One2many → sale.invoice.plan
    comodel_name='sale.invoice.plan' copy=False inverse_name='sale_id' string='Inovice Plan'
  • ip_invoice_plan Boolean
    compute='_compute_ip_invoice_plan' help='At least one invoice plan line pending to create invoice' string='Invoice Plan In Process'
  • use_invoice_plan Boolean
    copy=False default=False string='Use Invoice Plan'
Public methods (3)
  • action_confirm(self)
  • create_invoice_plan(self, num_installment, installment_date, interval, interval_type, advance)
  • remove_invoice_plan(self)
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/12.0/sale_invoice_plan
VERSION
VERSION 2.1.4
CATEGORY
CATEGORYSales
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Ecosoft
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Ecosoft
COMMITTERS
COMMITTERSDenis Roussel, OCA Transbot, oca-travis, Weblate, OCA-git-bot, sergiocorato, Kitti U, Marcel Savegnago
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:29:17
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - account
    - base_setup
    - base
    - web
    - product
    - decimal_precision
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - http_routing
    - digest
    - sale_management
    - sale
    - sales_team
    - payment
    - sale_stock
    - stock_account
    - stock
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
view_order_form_invoice_plan view.order.form.invoice.plan sale.order xpath Inherits sale.view_order_form
view_sale_create_invoice_plan Create Invoice Plan sale.create.invoice.plan form New
view_sale_invoice_plan_filter view.sale.invoice.plan.filter sale.invoice.plan search New
view_sale_invoice_plan_form view.sale.invoice.plan.form sale.invoice.plan form New
view_sale_invoice_plan_tree view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_invoice_plan_tree_readonly view.sale.invoice.plan.tree sale.invoice.plan tree New
view_sale_make_planned_invoice Invoice Orders sale.make.planned.invoice form New
Models touched (5)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • advance Boolean
    default=False string='Advance on 1st Invoice'
  • installment_date Date
    default=fields.Date.context_today required=True string='Installment Date'
  • interval Integer
    default=1 required=True string='Interval'
  • interval_type Selection
    default='month' required=True string='Interval Type' args: [('day', 'Day'), ('month', 'Month'), ('year', 'Year')]
  • num_installment Integer
    default=0 required=True string='Number of Installment'
Public methods (1)
  • sale_create_invoice_plan(self)
    @api.multi

New fields (11)
  • installment Integer
    string='Installment'
  • invoice_ids Many2many → account.invoice
    column1='plan_id' column2='invoice_id' readonly=True relation='sale_invoice_plan_invoice_rel' string='Invoices' args: 'account.invoice'
  • invoice_type Selection
    default='installment' required=True string='Type' args: [('advance', 'Advance'), ('installment', 'Installment')]
  • invoiced Boolean
    compute='_compute_invoiced' help='If this line already invoiced' string='Invoice Created'
  • last Boolean
    compute='_compute_last' help='Last installment will create invoice use remaining amount' string='Last Installment'
  • partner_id Many2one → res.partner
    comodel_name='res.partner' index=True related='sale_id.partner_id' store=True string='Customer'
  • percent Float
    digits=dp.get_precision('Product Unit of Measure') help='This percent will be used to calculate new quantity' string='Percent'
  • plan_date Date
    required=True string='Plan Date'
  • sale_id Many2one → sale.order
    comodel_name='sale.order' index=True ondelete='cascade' readonly=True string='Sales Order'
  • state Selection
    index=True related='sale_id.state' store=True string='Status' args: [('draft', 'Quotation'), ('sent', 'Quotation Sent'), ('sale', 'Sales Order'), ('done', 'Locked'), ('cancel', 'Cancelled')]
  • to_invoice Boolean
    compute='_compute_to_invoice' help='If this line is ready to create new invoice' string='Next Invoice'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • create_invoices_by_plan(self)
    @api.multi

New fields (3)
  • invoice_plan_ids One2many → sale.invoice.plan
    comodel_name='sale.invoice.plan' copy=False inverse_name='sale_id' string='Inovice Plan'
  • ip_invoice_plan Boolean
    compute='_compute_ip_invoice_plan' help='At least one invoice plan line pending to create invoice' string='Invoice Plan In Process'
  • use_invoice_plan Boolean
    copy=False default=False string='Use Invoice Plan'
Public methods (4)
  • action_confirm(self)
    @api.multi
  • action_invoice_create(self, grouped=False, final=False)
    @api.multi
  • create_invoice_plan(self, num_installment, installment_date, interval, interval_type, advance)
    @api.multi
  • remove_invoice_plan(self)
    @api.multi
STATUS
STATUSOpen migration PR - not merged yet for this version
REPOSITORY
REPOSITORYOCA/sale-workflow
PULL REQUEST
PULL REQUEST[19.0][MIG] `sale_invoice_plan` (#4121)