Sale Blanket Orders

sale_blanket_order
REPOSITORY
REPOSITORYOCA/sale-blanket
GIT
GIThttps://github.com/OCA/sale-blanket.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-blanket/tree/19.0/sale_blanket_order
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERSOCA-git-bot, Raf Ven, oca-ci
WEBSITE
WEBSITEhttps://github.com/OCA/sale-blanket
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:40:49
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - uom
    - base
    - sale_management
    - sale
    - sales_team
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - account_payment
    - account
    - onboarding
    - product
    - analytic
    - portal
    - http_routing
    - auth_signup
    - digest
    - resource
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
A blanket order is a pre-agreement to sell a certain number of
quantities of products at a specific price. From a confirmed blanket
order, the users can create new sale orders at such price, until the
blanket order expires, either due to reaching the validity date or
exhausting all the quantities of products.

Code Analysis

Views touched (12)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_blanket_order_line_form sale.blanket.order.line.form sale.blanket.order.line form New
sale_blanket_order_line_search sale.blanket.order.line.search sale.blanket.order.line search New
sale_blanket_order_line_tree sale.blanket.order.line.list sale.blanket.order.line list New
sale_config_settings_form_view res.config.settings.form (in sale_blanket_order) res.config.settings block Inherits sale.res_config_settings_view_form
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.list sale.blanket.order list New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order field Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (7)

New fields (1)
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (27)
  • amount_tax Monetary
    compute='_compute_amount_all' readonly=True store=True string='Taxes'
  • amount_total Monetary
    compute='_compute_amount_all' readonly=True store=True string='Total'
  • amount_untaxed Monetary
    compute='_compute_amount_all' readonly=True store=True string='Untaxed Amount' tracking=True
  • client_order_ref Char
    copy=False string='Customer Reference'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> index=True required=True
  • confirmed Boolean
    copy=False
  • currency_id Many2one → res.currency
    related='pricelist_id.currency_id' args: 'res.currency'
  • delivered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_delivered_uom_qty' string='Delivered quantity'
  • fiscal_position_id Many2one → account.fiscal.position
    check_company=True string='Fiscal Position' args: 'account.fiscal.position'
  • invoiced_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_invoiced_uom_qty' string='Invoiced quantity'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Sale Blanket Order Line count'
  • line_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    copy=False default='Draft' readonly=True
  • note Text
    default=<expr>
  • ordered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_ordered_uom_qty' string='Ordered quantity'
  • original_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_original_uom_qty' string='Original quantity'
  • partner_id Many2one → res.partner
    string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    required=True string='Pricelist' args: 'product.pricelist'
  • product_id Many2one → product.product
    related='line_ids.product_id' string='Product' args: 'product.product'
  • remaining_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_remaining_uom_qty' string='Remaining quantity'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' copy=False selection=[('draft', 'Draft'), ('open', 'Open'), ('done', 'Done'), ('expired', 'Expired')] store=True
  • tag_ids Many2many → crm.tag
    column1='blanket_order_id' column2='tag_id' comodel_name='crm.tag' relation='sale_blanket_order_tag_rel' string='Tags'
  • team_id Many2one → crm.team
    change_default=True default=<expr> string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    string='Salesperson' args: 'res.users'
  • validity_date Date
Public methods (7)
  • action_cancel(self)
  • action_confirm(self)
  • action_view_sale_blanket_order_line(self)
  • action_view_sale_orders(self)
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term - Fiscal position
  • set_to_draft(self)

New fields (26)
  • company_id Many2one
    index=True precompute=True related='order_id.company_id' store=True
  • currency_id Many2one → res.currency
    related='order_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • delivered_uom_qty Float
    compute='_compute_quantities' store=True string='Delivered quantity'
  • display_type Selection
    default=False help='Technical field for UX purpose.' args: [('line_section', 'Section'), ('line_note', 'Note')]
  • invoiced_uom_qty Float
    compute='_compute_quantities' store=True string='Invoiced quantity'
  • name Char
    tracking=True args: 'Description'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_uom_qty Float
    compute='_compute_quantities' store=True string='Ordered quantity'
  • original_uom_qty Float
    default=1 digits='Product Unit of Measure' string='Original quantity'
  • partner_id Many2one
    related='order_id.partner_id' string='Customer'
  • payment_term_id Many2one
    related='order_id.payment_term_id' string='Payment Terms'
  • price_subtotal Monetary
    compute='_compute_amount' store=True string='Subtotal'
  • price_tax Float
    compute='_compute_amount' store=True string='Tax'
  • price_total Monetary
    compute='_compute_amount' store=True string='Total'
  • price_unit Float
    digits='Product Price' string='Price'
  • pricelist_id Many2one
    related='order_id.pricelist_id' string='Pricelist'
  • pricelist_item_id Many2one → product.pricelist.item
    comodel_name='product.pricelist.item' compute='_compute_pricelist_item_id'
  • product_id Many2one → product.product
    domain=[('sale_ok', '=', True)] string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    string='Unit of Measure' args: 'uom.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity in base UoM'
  • remaining_uom_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity'
  • sale_lines One2many → sale.order.line
    copy=False readonly=True string='Sale order lines' args: 'sale.order.line', 'blanket_order_line'
  • sequence Integer
  • taxes_id Many2many → account.tax
    check_company=True comodel_name='account.tax' context={'active_test': False}
  • user_id Many2one
    related='order_id.user_id' string='Responsible'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • onchange_product(self)
    @api.onchange('product_id', 'original_uom_qty')
  • write(self, values)

New fields (3)
  • blanket_order_id Many2one → sale.blanket.order
    comodel_name='sale.blanket.order' default=<expr> readonly=True
  • line_ids One2many → sale.blanket.order.wizard.line
    default=<expr> string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
  • sale_order_id Many2one → sale.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'sale.order'
Public methods (1)
  • create_sale_order(self)

New fields (13)
  • analytic_distribution Json
    related='blanket_line_id.analytic_distribution'
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • company_id Many2one → res.company
    related='blanket_line_id.company_id' string='Company' args: 'res.company'
  • currency_id Many2one → res.currency
    related='blanket_line_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • partner_id Many2one → res.partner
    related='blanket_line_id.partner_id' string='Vendor' args: 'res.partner'
  • price_unit Float
    related='blanket_line_id.price_unit'
  • product_id Many2one → product.product
    related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    related='blanket_line_id.product_uom' string='Unit of Measure' args: 'uom.uom'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_uom_qty Float
    related='blanket_line_id.remaining_uom_qty'
  • taxes_id Many2many → account.tax
    related='blanket_line_id.taxes_id' args: 'account.tax'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (2)
  • blanket_order_id Many2one → sale.blanket.order
    related='order_line.blanket_order_line.order_id' string='Origin blanket order' args: 'sale.blanket.order'
  • disable_adding_lines Boolean
    compute='_compute_disable_adding_lines'
Public methods (2)
  • action_confirm(self)
  • check_partner_id(self)
    @api.constrains('partner_id')

New fields (1)
  • blanket_order_line Many2one → sale.blanket.order.line
    compute='_compute_blanket_order_line' copy=False precompute=True store=True string='Blanket Order line' args: 'sale.blanket.order.line'
Public methods (3)
  • check_currency(self)
    @api.constrains('currency_id')
  • check_product_id(self)
    @api.constrains('product_id')
  • get_assigned_bo_line(self)
REPOSITORY
REPOSITORYOCA/sale-blanket
GIT
GIThttps://github.com/OCA/sale-blanket.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-blanket/tree/18.0/sale_blanket_order
VERSION
VERSION 1.2.2
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERSAaronHForgeFlow, Weblate, OCA-git-bot, oca-ci, LauraCForgeFlow, David Gallay
WEBSITE
WEBSITEhttps://github.com/OCA/sale-blanket
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:15
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - uom
    - base
    - sale_management
    - sale
    - sales_team
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - account_payment
    - account
    - onboarding
    - product
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
A blanket order is a pre-agreement to sell a certain number of
quantities of products at a specific price. From a confirmed blanket
order, the users can create new sale orders at such price, until the
blanket order expires, either due to reaching the validity date or
exhausting all the quantities of products.

Code Analysis

Views touched (12)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_blanket_order_line_form sale.blanket.order.line.form sale.blanket.order.line form New
sale_blanket_order_line_search sale.blanket.order.line.search sale.blanket.order.line search New
sale_blanket_order_line_tree sale.blanket.order.line.list sale.blanket.order.line list New
sale_config_settings_form_view res.config.settings.form (in sale_blanket_order) res.config.settings block Inherits sale.res_config_settings_view_form
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.list sale.blanket.order list New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order field Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (7)

New fields (1)
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (27)
  • amount_tax Monetary
    compute='_compute_amount_all' readonly=True store=True string='Taxes'
  • amount_total Monetary
    compute='_compute_amount_all' readonly=True store=True string='Total'
  • amount_untaxed Monetary
    compute='_compute_amount_all' readonly=True store=True string='Untaxed Amount' tracking=True
  • client_order_ref Char
    copy=False string='Customer Reference'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> index=True required=True
  • confirmed Boolean
    copy=False
  • currency_id Many2one → res.currency
    related='pricelist_id.currency_id' args: 'res.currency'
  • delivered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_delivered_uom_qty' string='Delivered quantity'
  • fiscal_position_id Many2one → account.fiscal.position
    check_company=True string='Fiscal Position' args: 'account.fiscal.position'
  • invoiced_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_invoiced_uom_qty' string='Invoiced quantity'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Sale Blanket Order Line count'
  • line_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    copy=False default='Draft' readonly=True
  • note Text
    default=_default_note
  • ordered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_ordered_uom_qty' string='Ordered quantity'
  • original_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_original_uom_qty' string='Original quantity'
  • partner_id Many2one → res.partner
    string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    required=True string='Pricelist' args: 'product.pricelist'
  • product_id Many2one → product.product
    related='line_ids.product_id' string='Product' args: 'product.product'
  • remaining_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_remaining_uom_qty' string='Remaining quantity'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' copy=False selection=[('draft', 'Draft'), ('open', 'Open'), ('done', 'Done'), ('expired', 'Expired')] store=True
  • tag_ids Many2many → crm.tag
    column1='blanket_order_id' column2='tag_id' comodel_name='crm.tag' relation='sale_blanket_order_tag_rel' string='Tags'
  • team_id Many2one → crm.team
    change_default=True default=<expr> string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    string='Salesperson' args: 'res.users'
  • validity_date Date
Public methods (8)
  • action_cancel(self)
  • action_confirm(self)
  • action_view_sale_blanket_order_line(self)
  • action_view_sale_orders(self)
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term - Fiscal position
  • set_to_draft(self)
  • unlink(self)

New fields (26)
  • company_id Many2one
    index=True precompute=True related='order_id.company_id' store=True
  • currency_id Many2one → res.currency
    related='order_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • delivered_uom_qty Float
    compute='_compute_quantities' store=True string='Delivered quantity'
  • display_type Selection
    default=False help='Technical field for UX purpose.' args: [('line_section', 'Section'), ('line_note', 'Note')]
  • invoiced_uom_qty Float
    compute='_compute_quantities' store=True string='Invoiced quantity'
  • name Char
    tracking=True args: 'Description'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_uom_qty Float
    compute='_compute_quantities' store=True string='Ordered quantity'
  • original_uom_qty Float
    default=1 digits='Product Unit of Measure' string='Original quantity'
  • partner_id Many2one
    related='order_id.partner_id' string='Customer'
  • payment_term_id Many2one
    related='order_id.payment_term_id' string='Payment Terms'
  • price_subtotal Monetary
    compute='_compute_amount' store=True string='Subtotal'
  • price_tax Float
    compute='_compute_amount' store=True string='Tax'
  • price_total Monetary
    compute='_compute_amount' store=True string='Total'
  • price_unit Float
    digits='Product Price' string='Price'
  • pricelist_id Many2one
    related='order_id.pricelist_id' string='Pricelist'
  • pricelist_item_id Many2one → product.pricelist.item
    comodel_name='product.pricelist.item' compute='_compute_pricelist_item_id'
  • product_id Many2one → product.product
    domain=[('sale_ok', '=', True)] string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    string='Unit of Measure' args: 'uom.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity in base UoM'
  • remaining_uom_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity'
  • sale_lines One2many → sale.order.line
    copy=False readonly=True string='Sale order lines' args: 'sale.order.line', 'blanket_order_line'
  • sequence Integer
  • taxes_id Many2many → account.tax
    check_company=True comodel_name='account.tax' context={'active_test': False}
  • user_id Many2one
    related='order_id.user_id' string='Responsible'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • onchange_product(self)
    @api.onchange('product_id', 'original_uom_qty')
  • write(self, values)

New fields (3)
  • blanket_order_id Many2one → sale.blanket.order
    comodel_name='sale.blanket.order' default=<expr> readonly=True
  • line_ids One2many → sale.blanket.order.wizard.line
    default=_default_lines string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
  • sale_order_id Many2one → sale.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'sale.order'
Public methods (1)
  • create_sale_order(self)

New fields (13)
  • analytic_distribution Json
    related='blanket_line_id.analytic_distribution'
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • company_id Many2one → res.company
    related='blanket_line_id.company_id' string='Company' args: 'res.company'
  • currency_id Many2one → res.currency
    related='blanket_line_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • partner_id Many2one → res.partner
    related='blanket_line_id.partner_id' string='Vendor' args: 'res.partner'
  • price_unit Float
    related='blanket_line_id.price_unit'
  • product_id Many2one → product.product
    related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    related='blanket_line_id.product_uom' string='Unit of Measure' args: 'uom.uom'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_uom_qty Float
    related='blanket_line_id.remaining_uom_qty'
  • taxes_id Many2many → account.tax
    related='blanket_line_id.taxes_id' args: 'account.tax'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (2)
  • blanket_order_id Many2one → sale.blanket.order
    related='order_line.blanket_order_line.order_id' string='Origin blanket order' args: 'sale.blanket.order'
  • disable_adding_lines Boolean
    compute='_compute_disable_adding_lines'
Public methods (2)
  • action_confirm(self)
  • check_partner_id(self)
    @api.constrains('partner_id')

New fields (1)
  • blanket_order_line Many2one → sale.blanket.order.line
    copy=False string='Blanket Order line' args: 'sale.blanket.order.line'
Public methods (6)
  • check_currency(self)
    @api.constrains('currency_id')
  • check_product_id(self)
    @api.constrains('product_id')
  • get_assigned_bo_line(self)
  • onchange_blanket_order_line(self)
    @api.onchange('blanket_order_line')
  • onchange_product_id(self)
    @api.onchange('product_id', 'order_partner_id')
  • product_uom_change(self)
    @api.onchange('product_uom', 'product_uom_qty')
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_blanket_order
VERSION
VERSION 2.1.0
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERSStefan Rijnhart, AaronHForgeFlow, Weblate, OCA-git-bot, oca-ci, Saran440, LauraCForgeFlow, Chris Bergman
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:20:05
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - uom
    - base
    - sale_management
    - sale
    - sales_team
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - account_payment
    - account
    - onboarding
    - product
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
A blanket order is a pre-agreement to sell a certain number of
quantities of products at a specific price. From a confirmed blanket
order, the users can create new sale orders at such price, until the
blanket order expires, either due to reaching the validity date or
exhausting all the quantities of products.

Code Analysis

Views touched (12)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_blanket_order_line_form sale.blanket.order.line.form sale.blanket.order.line form New
sale_blanket_order_line_search sale.blanket.order.line.search sale.blanket.order.line search New
sale_blanket_order_line_tree sale.blanket.order.line.tree sale.blanket.order.line tree New
sale_config_settings_form_view res.config.settings.form (in sale_blanket_order) res.config.settings block Inherits sale.res_config_settings_view_form
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.tree sale.blanket.order tree New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order field Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (7)

New fields (1)
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (28)
  • amount_tax Monetary
    compute='_compute_amount_all' readonly=True store=True string='Taxes'
  • amount_total Monetary
    compute='_compute_amount_all' readonly=True store=True string='Total'
  • amount_untaxed Monetary
    compute='_compute_amount_all' readonly=True store=True string='Untaxed Amount' tracking=True
  • analytic_account_id Many2one → account.analytic.account
    check_company=True comodel_name='account.analytic.account' copy=False domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" string='Analytic Account'
  • client_order_ref Char
    copy=False string='Customer Reference'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> index=True required=True
  • confirmed Boolean
    copy=False
  • currency_id Many2one → res.currency
    related='pricelist_id.currency_id' args: 'res.currency'
  • delivered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_delivered_uom_qty' string='Delivered quantity'
  • fiscal_position_id Many2one → account.fiscal.position
    check_company=True string='Fiscal Position' args: 'account.fiscal.position'
  • invoiced_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_invoiced_uom_qty' string='Invoiced quantity'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Sale Blanket Order Line count'
  • line_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    copy=False default='Draft' readonly=True
  • note Text
    default=_default_note
  • ordered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_ordered_uom_qty' string='Ordered quantity'
  • original_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_original_uom_qty' string='Original quantity'
  • partner_id Many2one → res.partner
    string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    required=True string='Pricelist' args: 'product.pricelist'
  • product_id Many2one → product.product
    related='line_ids.product_id' string='Product' args: 'product.product'
  • remaining_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_remaining_uom_qty' string='Remaining quantity'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' copy=False selection=[('draft', 'Draft'), ('open', 'Open'), ('done', 'Done'), ('expired', 'Expired')] store=True
  • tag_ids Many2many → crm.tag
    column1='blanket_order_id' column2='tag_id' comodel_name='crm.tag' relation='sale_blanket_order_tag_rel' string='Tags'
  • team_id Many2one → crm.team
    change_default=True default=<expr> string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    string='Salesperson' args: 'res.users'
  • validity_date Date
Public methods (8)
  • action_cancel(self)
  • action_confirm(self)
  • action_view_sale_blanket_order_line(self)
  • action_view_sale_orders(self)
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term - Fiscal position
  • set_to_draft(self)
  • unlink(self)

New fields (26)
  • company_id Many2one
    index=True precompute=True related='order_id.company_id' store=True
  • currency_id Many2one → res.currency
    related='order_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • delivered_uom_qty Float
    compute='_compute_quantities' store=True string='Delivered quantity'
  • display_type Selection
    default=False help='Technical field for UX purpose.' args: [('line_section', 'Section'), ('line_note', 'Note')]
  • invoiced_uom_qty Float
    compute='_compute_quantities' store=True string='Invoiced quantity'
  • name Char
    tracking=True args: 'Description'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_uom_qty Float
    compute='_compute_quantities' store=True string='Ordered quantity'
  • original_uom_qty Float
    default=1 digits='Product Unit of Measure' string='Original quantity'
  • partner_id Many2one
    related='order_id.partner_id' string='Customer'
  • payment_term_id Many2one
    related='order_id.payment_term_id' string='Payment Terms'
  • price_subtotal Monetary
    compute='_compute_amount' store=True string='Subtotal'
  • price_tax Float
    compute='_compute_amount' store=True string='Tax'
  • price_total Monetary
    compute='_compute_amount' store=True string='Total'
  • price_unit Float
    digits='Product Price' string='Price'
  • pricelist_id Many2one
    related='order_id.pricelist_id' string='Pricelist'
  • pricelist_item_id Many2one → product.pricelist.item
    comodel_name='product.pricelist.item' compute='_compute_pricelist_item_id'
  • product_id Many2one → product.product
    domain=[('sale_ok', '=', True)] string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    string='Unit of Measure' args: 'uom.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity in base UoM'
  • remaining_uom_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity'
  • sale_lines One2many → sale.order.line
    copy=False readonly=True string='Sale order lines' args: 'sale.order.line', 'blanket_order_line'
  • sequence Integer
  • taxes_id Many2many → account.tax
    check_company=True comodel_name='account.tax' context={'active_test': False}
  • user_id Many2one
    related='order_id.user_id' string='Responsible'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • onchange_product(self)
    @api.onchange('product_id', 'original_uom_qty')
  • write(self, values)

New fields (3)
  • blanket_order_id Many2one → sale.blanket.order
    comodel_name='sale.blanket.order' default=<expr> readonly=True
  • line_ids One2many → sale.blanket.order.wizard.line
    default=_default_lines string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
  • sale_order_id Many2one → sale.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'sale.order'
Public methods (1)
  • create_sale_order(self)

New fields (12)
  • analytic_distribution Json
    related='blanket_line_id.analytic_distribution'
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • currency_id Many2one → res.currency
    related='blanket_line_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • partner_id Many2one → res.partner
    related='blanket_line_id.partner_id' string='Vendor' args: 'res.partner'
  • price_unit Float
    related='blanket_line_id.price_unit'
  • product_id Many2one → product.product
    related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    related='blanket_line_id.product_uom' string='Unit of Measure' args: 'uom.uom'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_uom_qty Float
    related='blanket_line_id.remaining_uom_qty'
  • taxes_id Many2many → account.tax
    related='blanket_line_id.taxes_id' args: 'account.tax'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (1)
  • blanket_order_id Many2one → sale.blanket.order
    compute='_compute_blanket_order_id' string='Origin blanket order' args: 'sale.blanket.order'
Public methods (2)
  • action_confirm(self)
  • check_partner_id(self)
    @api.constrains('partner_id')

New fields (1)
  • blanket_order_line Many2one → sale.blanket.order.line
    copy=False string='Blanket Order line' args: 'sale.blanket.order.line'
Public methods (6)
  • check_currency(self)
    @api.constrains('currency_id')
  • check_product_id(self)
    @api.constrains('product_id')
  • get_assigned_bo_line(self)
  • onchange_blanket_order_line(self)
    @api.onchange('blanket_order_line')
  • onchange_product_id(self)
    @api.onchange('product_id', 'order_partner_id')
  • product_uom_change(self)
    @api.onchange('product_uom', 'product_uom_qty')
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_blanket_order
VERSION
VERSION 2.0.2
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, oca-ci, Borruso, ps-tubtim, LauraCForgeFlow, CristianoMafraJunior, Cristiano Mafra Junior, chien
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:53:46
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/web:
    - web_action_conditionable
odoo/odoo:
    - uom
    - base
    - sale_management
    - sale
    - sales_team
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - account_payment
    - account
    - product
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (12)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_blanket_order_line_form sale.blanket.order.line.form sale.blanket.order.line form New
sale_blanket_order_line_search sale.blanket.order.line.search sale.blanket.order.line search New
sale_blanket_order_line_tree sale.blanket.order.line.tree sale.blanket.order.line tree New
sale_config_settings_form_view res.config.settings.form (in sale_blanket_order) res.config.settings xpath Inherits sale.res_config_settings_view_form
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.tree sale.blanket.order tree New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order field Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (7)

New fields (1)
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (28)
  • amount_tax Monetary
    compute='_compute_amount_all' readonly=True store=True string='Taxes'
  • amount_total Monetary
    compute='_compute_amount_all' readonly=True store=True string='Total'
  • amount_untaxed Monetary
    compute='_compute_amount_all' readonly=True store=True string='Untaxed Amount' tracking=True
  • analytic_account_id Many2one → account.analytic.account
    check_company=True comodel_name='account.analytic.account' copy=False domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" states=READONLY_FIELD_STATES string='Analytic Account'
  • client_order_ref Char
    copy=False states=READONLY_FIELD_STATES string='Customer Reference'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> index=True required=True
  • confirmed Boolean
    copy=False
  • currency_id Many2one → res.currency
    related='pricelist_id.currency_id' args: 'res.currency'
  • delivered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_delivered_uom_qty' string='Delivered quantity'
  • fiscal_position_id Many2one → account.fiscal.position
    string='Fiscal Position' args: 'account.fiscal.position'
  • invoiced_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_invoiced_uom_qty' string='Invoiced quantity'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Sale Blanket Order Line count'
  • line_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    copy=False default='Draft' readonly=True
  • note Text
    default=_default_note states=READONLY_FIELD_STATES
  • ordered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_ordered_uom_qty' string='Ordered quantity'
  • original_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_original_uom_qty' string='Original quantity'
  • partner_id Many2one → res.partner
    states=READONLY_FIELD_STATES string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    states=READONLY_FIELD_STATES string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    required=True states=READONLY_FIELD_STATES string='Pricelist' args: 'product.pricelist'
  • product_id Many2one → product.product
    related='line_ids.product_id' string='Product' args: 'product.product'
  • remaining_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_remaining_uom_qty' string='Remaining quantity'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' copy=False selection=[('draft', 'Draft'), ('open', 'Open'), ('done', 'Done'), ('expired', 'Expired')] store=True
  • tag_ids Many2many → crm.tag
    column1='blanket_order_id' column2='tag_id' comodel_name='crm.tag' relation='sale_blanket_order_tag_rel' string='Tags'
  • team_id Many2one → crm.team
    change_default=True default=<expr> states=READONLY_FIELD_STATES string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    states=READONLY_FIELD_STATES string='Salesperson' args: 'res.users'
  • validity_date Date
    states=READONLY_FIELD_STATES
Public methods (8)
  • action_cancel(self)
  • action_confirm(self)
  • action_view_sale_blanket_order_line(self)
  • action_view_sale_orders(self)
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term - Fiscal position
  • set_to_draft(self)
  • unlink(self)

New fields (25)
  • company_id Many2one
    index=True precompute=True related='order_id.company_id' store=True
  • currency_id Many2one → res.currency
    related='order_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • delivered_uom_qty Float
    compute='_compute_quantities' store=True string='Delivered quantity'
  • display_type Selection
    default=False help='Technical field for UX purpose.' args: [('line_section', 'Section'), ('line_note', 'Note')]
  • invoiced_uom_qty Float
    compute='_compute_quantities' store=True string='Invoiced quantity'
  • name Char
    tracking=True args: 'Description'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_uom_qty Float
    compute='_compute_quantities' store=True string='Ordered quantity'
  • original_uom_qty Float
    default=1 digits='Product Unit of Measure' string='Original quantity'
  • partner_id Many2one
    related='order_id.partner_id' string='Customer'
  • payment_term_id Many2one
    related='order_id.payment_term_id' string='Payment Terms'
  • price_subtotal Monetary
    compute='_compute_amount' store=True string='Subtotal'
  • price_tax Float
    compute='_compute_amount' store=True string='Tax'
  • price_total Monetary
    compute='_compute_amount' store=True string='Total'
  • price_unit Float
    digits='Product Price' string='Price'
  • pricelist_id Many2one
    related='order_id.pricelist_id' string='Pricelist'
  • product_id Many2one → product.product
    domain=[('sale_ok', '=', True)] string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    string='Unit of Measure' args: 'uom.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity in base UoM'
  • remaining_uom_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity'
  • sale_lines One2many → sale.order.line
    copy=False readonly=True string='Sale order lines' args: 'sale.order.line', 'blanket_order_line'
  • sequence Integer
  • taxes_id Many2many → account.tax
    domain=['|', ('active', '=', False), ('active', '=', True)] string='Taxes' args: 'account.tax'
  • user_id Many2one
    related='order_id.user_id' string='Responsible'
Public methods (4)
  • create(self, vals_list)
    @api.model_create_multi
  • name_get(self)
  • onchange_product(self)
    @api.onchange('product_id', 'original_uom_qty')
  • write(self, values)

New fields (3)
  • blanket_order_id Many2one → sale.blanket.order
    comodel_name='sale.blanket.order' default=<expr> readonly=True
  • line_ids One2many → sale.blanket.order.wizard.line
    default=_default_lines string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
  • sale_order_id Many2one → sale.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'sale.order'
Public methods (1)
  • create_sale_order(self)

New fields (11)
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • currency_id Many2one → res.currency
    related='blanket_line_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • partner_id Many2one → res.partner
    related='blanket_line_id.partner_id' string='Vendor' args: 'res.partner'
  • price_unit Float
    related='blanket_line_id.price_unit'
  • product_id Many2one → product.product
    related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    related='blanket_line_id.product_uom' string='Unit of Measure' args: 'uom.uom'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_uom_qty Float
    related='blanket_line_id.remaining_uom_qty'
  • taxes_id Many2many → account.tax
    related='blanket_line_id.taxes_id' args: 'account.tax'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (2)
  • blanket_order_id Many2one → sale.blanket.order
    compute='_compute_blanket_order_id' string='Origin blanket order' args: 'sale.blanket.order'
  • disable_adding_lines Boolean
    compute='_compute_disable_adding_lines'
Public methods (2)
  • action_confirm(self)
  • check_partner_id(self)
    @api.constrains('partner_id')

New fields (1)
  • blanket_order_line Many2one → sale.blanket.order.line
    copy=False string='Blanket Order line' args: 'sale.blanket.order.line'
Public methods (6)
  • check_currency(self)
    @api.constrains('currency_id')
  • check_product_id(self)
    @api.constrains('product_id')
  • get_assigned_bo_line(self)
  • onchange_blanket_order_line(self)
    @api.onchange('blanket_order_line')
  • onchange_product_id(self)
    @api.onchange('product_id', 'order_partner_id')
  • product_uom_change(self)
    @api.onchange('product_uom', 'product_uom_qty')
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_blanket_order
VERSION
VERSION 1.2.1
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERSLois Rilo, OCA Transbot, Denis Leemann, Weblate, OCA-git-bot, oca-ci, Telmo Santos
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:46:34
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/web:
    - web_action_conditionable
odoo/odoo:
    - uom
    - base
    - sale_management
    - sale
    - sales_team
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - payment
    - account
    - product
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (12)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_blanket_order_line_form sale.blanket.order.line.form sale.blanket.order.line form New
sale_blanket_order_line_search sale.blanket.order.line.search sale.blanket.order.line search New
sale_blanket_order_line_tree sale.blanket.order.line.tree sale.blanket.order.line tree New
sale_config_settings_form_view res.config.settings.form (in sale_blanket_order) res.config.settings xpath Inherits sale.res_config_settings_view_form
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.tree sale.blanket.order tree New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order xpath Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (7)

New fields (1)
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (27)
  • amount_tax Monetary
    compute='_compute_amount_all' readonly=True store=True string='Taxes'
  • amount_total Monetary
    compute='_compute_amount_all' readonly=True store=True string='Total'
  • amount_untaxed Monetary
    compute='_compute_amount_all' readonly=True store=True string='Untaxed Amount' tracking=True
  • analytic_account_id Many2one → account.analytic.account
    check_company=True comodel_name='account.analytic.account' copy=False domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" readonly=True states={'draft': [('readonly', False)]} string='Analytic Account'
  • client_order_ref Char
    copy=False readonly=True states={'draft': [('readonly', False)]} string='Customer Reference'
  • company_id Many2one → res.company
    default=_default_company readonly=True states={'draft': [('readonly', False)]} string='Company' args: 'res.company'
  • confirmed Boolean
    copy=False
  • currency_id Many2one → res.currency
    related='pricelist_id.currency_id' args: 'res.currency'
  • delivered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_delivered_uom_qty' string='Delivered quantity'
  • fiscal_position_id Many2one → account.fiscal.position
    string='Fiscal Position' args: 'account.fiscal.position'
  • invoiced_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_invoiced_uom_qty' string='Invoiced quantity'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Sale Blanket Order Line count'
  • line_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    copy=False default='Draft' readonly=True
  • note Text
    default=_default_note readonly=True states={'draft': [('readonly', False)]}
  • ordered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_ordered_uom_qty' string='Ordered quantity'
  • original_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_original_uom_qty' string='Original quantity'
  • partner_id Many2one → res.partner
    readonly=True states={'draft': [('readonly', False)]} string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    readonly=True states={'draft': [('readonly', False)]} string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    readonly=True required=True states={'draft': [('readonly', False)]} string='Pricelist' args: 'product.pricelist'
  • product_id Many2one → product.product
    related='line_ids.product_id' string='Product' args: 'product.product'
  • remaining_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_remaining_uom_qty' string='Remaining quantity'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' copy=False selection=[('draft', 'Draft'), ('open', 'Open'), ('done', 'Done'), ('expired', 'Expired')] store=True
  • team_id Many2one → crm.team
    change_default=True default=_get_default_team readonly=True states={'draft': [('readonly', False)]} string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    readonly=True states={'draft': [('readonly', False)]} string='Salesperson' args: 'res.users'
  • validity_date Date
    readonly=True states={'draft': [('readonly', False)]}
Public methods (8)
  • action_cancel(self)
  • action_confirm(self)
  • action_view_sale_blanket_order_line(self)
  • action_view_sale_orders(self)
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term - Fiscal position
  • set_to_draft(self)
  • unlink(self)

New fields (26)
  • analytic_tag_ids Many2many → account.analytic.tag
    comodel_name='account.analytic.tag' domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" string='Analytic Tags'
  • company_id Many2one → res.company
    related='order_id.company_id' store=True args: 'res.company'
  • currency_id Many2one → res.currency
    related='order_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • delivered_uom_qty Float
    compute='_compute_quantities' store=True string='Delivered quantity'
  • display_type Selection
    default=False help='Technical field for UX purpose.' args: [('line_section', 'Section'), ('line_note', 'Note')]
  • invoiced_uom_qty Float
    compute='_compute_quantities' store=True string='Invoiced quantity'
  • name Char
    tracking=True args: 'Description'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_uom_qty Float
    compute='_compute_quantities' store=True string='Ordered quantity'
  • original_uom_qty Float
    default=1 digits='Product Unit of Measure' string='Original quantity'
  • partner_id Many2one
    related='order_id.partner_id' string='Customer'
  • payment_term_id Many2one
    related='order_id.payment_term_id' string='Payment Terms'
  • price_subtotal Monetary
    compute='_compute_amount' store=True string='Subtotal'
  • price_tax Float
    compute='_compute_amount' store=True string='Tax'
  • price_total Monetary
    compute='_compute_amount' store=True string='Total'
  • price_unit Float
    digits='Product Price' string='Price'
  • pricelist_id Many2one
    related='order_id.pricelist_id' string='Pricelist'
  • product_id Many2one → product.product
    domain=[('sale_ok', '=', True)] string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    string='Unit of Measure' args: 'uom.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity in base UoM'
  • remaining_uom_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity'
  • sale_lines One2many → sale.order.line
    copy=False readonly=True string='Sale order lines' args: 'sale.order.line', 'blanket_order_line'
  • sequence Integer
  • taxes_id Many2many → account.tax
    domain=['|', ('active', '=', False), ('active', '=', True)] string='Taxes' args: 'account.tax'
  • user_id Many2one
    related='order_id.user_id' string='Responsible'
Public methods (4)
  • create(self, vals_list)
    @api.model_create_multi
  • name_get(self)
  • onchange_product(self)
    @api.onchange('product_id', 'original_uom_qty')
  • write(self, values)

New fields (3)
  • blanket_order_id Many2one → sale.blanket.order
    comodel_name='sale.blanket.order' default=<expr> readonly=True
  • line_ids One2many → sale.blanket.order.wizard.line
    default=_default_lines string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
  • sale_order_id Many2one → sale.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'sale.order'
Public methods (1)
  • create_sale_order(self)

New fields (11)
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • currency_id Many2one → res.currency
    related='blanket_line_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • partner_id Many2one → res.partner
    related='blanket_line_id.partner_id' string='Vendor' args: 'res.partner'
  • price_unit Float
    related='blanket_line_id.price_unit'
  • product_id Many2one → product.product
    related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    related='blanket_line_id.product_uom' string='Unit of Measure' args: 'uom.uom'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_uom_qty Float
    related='blanket_line_id.remaining_uom_qty'
  • taxes_id Many2many → account.tax
    related='blanket_line_id.taxes_id' args: 'account.tax'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (1)
  • blanket_order_id Many2one → sale.blanket.order
    related='order_line.blanket_order_line.order_id' string='Origin blanket order' args: 'sale.blanket.order'
Public methods (2)
  • button_confirm(self)
  • check_partner_id(self)
    @api.constrains('partner_id')

New fields (1)
  • blanket_order_line Many2one → sale.blanket.order.line
    copy=False string='Blanket Order line' args: 'sale.blanket.order.line'
Public methods (6)
  • check_currency(self)
    @api.constrains('currency_id')
  • check_product_id(self)
    @api.constrains('product_id')
  • get_assigned_bo_line(self)
  • onchange_blanket_order_line(self)
    @api.onchange('blanket_order_line')
  • onchange_product_id(self)
    @api.onchange('product_id', 'order_partner_id')
  • product_uom_change(self)
    @api.onchange('product_uom_qty', 'product_uom')
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_blanket_order
VERSION
VERSION 2.0.0
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERStafaRU, OCA Transbot, Miquel Raïch, oca-travis, Weblate, OCA-git-bot, oca-ci, Marcel Savegnago, Alessandro Uffreduzzi, Bernat Puig Font, oca-git-bot, Alessio Renda, PicchiSeba
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:40:58
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/web:
    - web_action_conditionable
odoo/odoo:
    - uom
    - base
    - sale_management
    - sale
    - sales_team
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - payment
    - account
    - product
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (12)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_blanket_order_line_form sale.blanket.order.line.form sale.blanket.order.line form New
sale_blanket_order_line_search sale.blanket.order.line.search sale.blanket.order.line search New
sale_blanket_order_line_tree sale.blanket.order.line.tree sale.blanket.order.line tree New
sale_config_settings_form_view res.config.settings.form (in sale_blanket_order) res.config.settings div Inherits sale.res_config_settings_view_form
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.tree sale.blanket.order tree New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order xpath Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (8)

New fields (1)
  • blanket_order_seq_number_from_draft Boolean
    default=False args: 'Enable Blanket Order numbering from draft state'
Public methods (0)

No public methods.

New fields (2)
  • blanket_order_seq_number_from_draft Boolean
    readonly=False related='company_id.blanket_order_seq_number_from_draft'
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (27)
  • amount_tax Monetary
    compute='_compute_amount_all' readonly=True store=True string='Taxes'
  • amount_total Monetary
    compute='_compute_amount_all' readonly=True store=True string='Total'
  • amount_untaxed Monetary
    compute='_compute_amount_all' readonly=True store=True string='Untaxed Amount' tracking=True
  • analytic_account_id Many2one → account.analytic.account
    check_company=True comodel_name='account.analytic.account' copy=False domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" readonly=True states={'draft': [('readonly', False)]} string='Analytic Account'
  • client_order_ref Char
    copy=False readonly=True states={'draft': [('readonly', False)]} string='Customer Reference'
  • company_id Many2one → res.company
    default=_default_company readonly=True states={'draft': [('readonly', False)]} string='Company' args: 'res.company'
  • confirmed Boolean
    copy=False
  • currency_id Many2one → res.currency
    related='pricelist_id.currency_id' args: 'res.currency'
  • delivered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_delivered_uom_qty' string='Delivered quantity'
  • fiscal_position_id Many2one → account.fiscal.position
    string='Fiscal Position' args: 'account.fiscal.position'
  • invoiced_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_invoiced_uom_qty' string='Invoiced quantity'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Sale Blanket Order Line count'
  • line_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    copy=False default='Draft' readonly=True
  • note Text
    default=_default_note readonly=True states={'draft': [('readonly', False)]}
  • ordered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_ordered_uom_qty' string='Ordered quantity'
  • original_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_original_uom_qty' string='Original quantity'
  • partner_id Many2one → res.partner
    readonly=True states={'draft': [('readonly', False)]} string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    readonly=True states={'draft': [('readonly', False)]} string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    readonly=True required=True states={'draft': [('readonly', False)]} string='Pricelist' args: 'product.pricelist'
  • product_id Many2one → product.product
    related='line_ids.product_id' string='Product' args: 'product.product'
  • remaining_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_remaining_uom_qty' string='Remaining quantity'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' copy=False selection=[('draft', 'Draft'), ('open', 'Open'), ('done', 'Done'), ('expired', 'Expired'), ('cancel', 'Cancelled')] store=True
  • team_id Many2one → crm.team
    change_default=True default=_get_default_team readonly=True states={'draft': [('readonly', False)]} string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    readonly=True states={'draft': [('readonly', False)]} string='Salesperson' args: 'res.users'
  • validity_date Date
    readonly=True states={'draft': [('readonly', False)]}
Public methods (9)
  • action_cancel(self)
  • action_confirm(self)
  • action_view_sale_blanket_order_line(self)
  • action_view_sale_orders(self)
  • create(self, vals_list)
    @api.model_create_multi
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term - Fiscal position
  • set_to_draft(self)
  • unlink(self)

New fields (25)
  • analytic_tag_ids Many2many → account.analytic.tag
    comodel_name='account.analytic.tag' domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" string='Analytic Tags'
  • company_id Many2one → res.company
    related='order_id.company_id' store=True args: 'res.company'
  • currency_id Many2one → res.currency
    related='order_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • delivered_uom_qty Float
    compute='_compute_quantities' store=True string='Delivered Qty'
  • invoiced_uom_qty Float
    compute='_compute_quantities' store=True string='Invoiced Qty'
  • name Char
    tracking=True args: 'Description'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_uom_qty Float
    compute='_compute_quantities' store=True string='Ordered Qty'
  • original_uom_qty Float
    default=1 digits='Product Unit of Measure' required=True string='Original Qty'
  • partner_id Many2one
    related='order_id.partner_id' store=True string='Partner'
  • payment_term_id Many2one
    related='order_id.payment_term_id' string='Payment Terms'
  • price_subtotal Monetary
    compute='_compute_amount' store=True string='Subtotal'
  • price_tax Float
    compute='_compute_amount' store=True string='Tax'
  • price_total Monetary
    compute='_compute_amount' store=True string='Total'
  • price_unit Float
    digits='Product Price' required=True string='Price'
  • pricelist_id Many2one
    related='order_id.pricelist_id' string='Pricelist'
  • product_id Many2one → product.product
    domain=[('sale_ok', '=', True)] required=True string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    required=True string='Unit of Measure' args: 'uom.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining Qty in base UoM'
  • remaining_uom_qty Float
    compute='_compute_quantities' store=True string='Remaining Qty'
  • sale_lines One2many → sale.order.line
    copy=False readonly=True string='Sale order lines' args: 'sale.order.line', 'blanket_order_line'
  • sequence Integer
  • taxes_id Many2many → account.tax
    domain=['|', ('active', '=', False), ('active', '=', True)] string='Taxes' args: 'account.tax'
  • user_id Many2one
    related='order_id.user_id' string='Responsible'
Public methods (2)
  • name_get(self)
  • onchange_product(self)
    @api.onchange('product_id', 'original_uom_qty')

New fields (3)
  • blanket_order_id Many2one → sale.blanket.order
    comodel_name='sale.blanket.order' default=<expr> readonly=True
  • line_ids One2many → sale.blanket.order.wizard.line
    default=_default_lines string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
  • sale_order_id Many2one → sale.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'sale.order'
Public methods (1)
  • create_sale_order(self)

New fields (11)
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • currency_id Many2one → res.currency
    related='blanket_line_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • partner_id Many2one → res.partner
    related='blanket_line_id.partner_id' string='Vendor' args: 'res.partner'
  • price_unit Float
    related='blanket_line_id.price_unit'
  • product_id Many2one → product.product
    related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    related='blanket_line_id.product_uom' string='Unit of Measure' args: 'uom.uom'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_uom_qty Float
    related='blanket_line_id.remaining_uom_qty'
  • taxes_id Many2many → account.tax
    related='blanket_line_id.taxes_id' args: 'account.tax'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (1)
  • blanket_order_id Many2one → sale.blanket.order
    related='order_line.blanket_order_line.order_id' string='Origin blanket order' args: 'sale.blanket.order'
Public methods (2)
  • button_confirm(self)
  • check_partner_id(self)
    @api.constrains('partner_id')

New fields (1)
  • blanket_order_line Many2one → sale.blanket.order.line
    copy=False string='Blanket Order line' args: 'sale.blanket.order.line'
Public methods (6)
  • check_currency(self)
    @api.constrains('currency_id')
  • check_product_id(self)
    @api.constrains('product_id')
  • get_assigned_bo_line(self)
  • onchange_blanket_order_line(self)
    @api.onchange('blanket_order_line')
  • onchange_product_id(self)
    @api.onchange('product_id', 'order_partner_id')
  • product_uom_change(self)
    @api.onchange('product_uom_qty', 'product_uom')
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_blanket_order
VERSION
VERSION 1.2.2
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERSLois Rilo, OCA Transbot, Miquel Raïch, oca-travis, OCA-git-bot, Jesus Ramoneda, Maciej
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:34:13
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/web:
    - web_action_conditionable
odoo/odoo:
    - uom
    - base
    - sale_management
    - sale
    - sales_team
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - payment
    - account
    - product
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (12)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_blanket_order_line_form sale.blanket.order.line.form sale.blanket.order.line form New
sale_blanket_order_line_search sale.blanket.order.line.search sale.blanket.order.line search New
sale_blanket_order_line_tree sale.blanket.order.line.tree sale.blanket.order.line tree New
sale_config_settings_form_view res.config.settings.form (in sale_blanket_order) res.config.settings xpath Inherits sale.res_config_settings_view_form
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.tree sale.blanket.order tree New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order xpath Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (7)

New fields (1)
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (27)
  • amount_tax Monetary
    compute='_compute_amount_all' readonly=True store=True string='Taxes'
  • amount_total Monetary
    compute='_compute_amount_all' readonly=True store=True string='Total'
  • amount_untaxed Monetary
    compute='_compute_amount_all' readonly=True store=True string='Untaxed Amount' tracking=True
  • analytic_account_id Many2one → account.analytic.account
    check_company=True comodel_name='account.analytic.account' copy=False domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" readonly=True states={'draft': [('readonly', False)]} string='Analytic Account'
  • client_order_ref Char
    copy=False readonly=True states={'draft': [('readonly', False)]} string='Customer Reference'
  • company_id Many2one → res.company
    default=_default_company readonly=True states={'draft': [('readonly', False)]} string='Company' args: 'res.company'
  • confirmed Boolean
    copy=False
  • currency_id Many2one → res.currency
    related='pricelist_id.currency_id' args: 'res.currency'
  • delivered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_delivered_uom_qty' string='Delivered quantity'
  • fiscal_position_id Many2one → account.fiscal.position
    string='Fiscal Position' args: 'account.fiscal.position'
  • invoiced_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_invoiced_uom_qty' string='Invoiced quantity'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Sale Blanket Order Line count'
  • line_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    copy=False default='Draft' readonly=True
  • note Text
    default=_default_note readonly=True states={'draft': [('readonly', False)]}
  • ordered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_ordered_uom_qty' string='Ordered quantity'
  • original_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_original_uom_qty' string='Original quantity'
  • partner_id Many2one → res.partner
    readonly=True states={'draft': [('readonly', False)]} string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    readonly=True states={'draft': [('readonly', False)]} string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    readonly=True required=True states={'draft': [('readonly', False)]} string='Pricelist' args: 'product.pricelist'
  • product_id Many2one → product.product
    related='line_ids.product_id' string='Product' args: 'product.product'
  • remaining_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_remaining_uom_qty' string='Remaining quantity'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' copy=False selection=[('draft', 'Draft'), ('open', 'Open'), ('done', 'Done'), ('expired', 'Expired')] store=True
  • team_id Many2one → crm.team
    change_default=True default=_get_default_team readonly=True states={'draft': [('readonly', False)]} string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    readonly=True states={'draft': [('readonly', False)]} string='Salesperson' args: 'res.users'
  • validity_date Date
    readonly=True states={'draft': [('readonly', False)]}
Public methods (8)
  • action_cancel(self)
  • action_confirm(self)
  • action_view_sale_blanket_order_line(self)
  • action_view_sale_orders(self)
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term - Fiscal position
  • set_to_draft(self)
  • unlink(self)

New fields (25)
  • analytic_tag_ids Many2many → account.analytic.tag
    comodel_name='account.analytic.tag' domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" string='Analytic Tags'
  • company_id Many2one → res.company
    related='order_id.company_id' store=True args: 'res.company'
  • currency_id Many2one → res.currency
    related='order_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • delivered_uom_qty Float
    compute='_compute_quantities' store=True string='Delivered quantity'
  • invoiced_uom_qty Float
    compute='_compute_quantities' store=True string='Invoiced quantity'
  • name Char
    tracking=True args: 'Description'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_uom_qty Float
    compute='_compute_quantities' store=True string='Ordered quantity'
  • original_uom_qty Float
    default=1 digits='Product Unit of Measure' required=True string='Original quantity'
  • partner_id Many2one
    related='order_id.partner_id' string='Customer'
  • payment_term_id Many2one
    related='order_id.payment_term_id' string='Payment Terms'
  • price_subtotal Monetary
    compute='_compute_amount' store=True string='Subtotal'
  • price_tax Float
    compute='_compute_amount' store=True string='Tax'
  • price_total Monetary
    compute='_compute_amount' store=True string='Total'
  • price_unit Float
    digits='Product Price' required=True string='Price'
  • pricelist_id Many2one
    related='order_id.pricelist_id' string='Pricelist'
  • product_id Many2one → product.product
    domain=[('sale_ok', '=', True)] required=True string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    required=True string='Unit of Measure' args: 'uom.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity in base UoM'
  • remaining_uom_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity'
  • sale_lines One2many → sale.order.line
    copy=False readonly=True string='Sale order lines' args: 'sale.order.line', 'blanket_order_line'
  • sequence Integer
  • taxes_id Many2many → account.tax
    domain=['|', ('active', '=', False), ('active', '=', True)] string='Taxes' args: 'account.tax'
  • user_id Many2one
    related='order_id.user_id' string='Responsible'
Public methods (2)
  • name_get(self)
  • onchange_product(self)
    @api.onchange('product_id', 'original_uom_qty')

New fields (3)
  • blanket_order_id Many2one → sale.blanket.order
    comodel_name='sale.blanket.order' default=<expr> readonly=True
  • line_ids One2many → sale.blanket.order.wizard.line
    default=_default_lines string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
  • sale_order_id Many2one → sale.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'sale.order'
Public methods (1)
  • create_sale_order(self)

New fields (11)
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • currency_id Many2one → res.currency
    related='blanket_line_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • partner_id Many2one → res.partner
    related='blanket_line_id.partner_id' string='Vendor' args: 'res.partner'
  • price_unit Float
    related='blanket_line_id.price_unit'
  • product_id Many2one → product.product
    related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    related='blanket_line_id.product_uom' string='Unit of Measure' args: 'uom.uom'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_uom_qty Float
    related='blanket_line_id.remaining_uom_qty'
  • taxes_id Many2many → account.tax
    related='blanket_line_id.taxes_id' args: 'account.tax'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (1)
  • blanket_order_id Many2one → sale.blanket.order
    related='order_line.blanket_order_line.order_id' string='Origin blanket order' args: 'sale.blanket.order'
Public methods (2)
  • button_confirm(self)
  • check_partner_id(self)
    @api.constrains('partner_id')

New fields (1)
  • blanket_order_line Many2one → sale.blanket.order.line
    copy=False string='Blanket Order line' args: 'sale.blanket.order.line'
Public methods (6)
  • check_currency(self)
    @api.constrains('currency_id')
  • check_product_id(self)
    @api.constrains('product_id')
  • get_assigned_bo_line(self)
  • onchange_blanket_order_line(self)
    @api.onchange('blanket_order_line')
  • onchange_product_id(self)
    @api.onchange('product_id', 'order_partner_id')
  • product_uom_change(self)
    @api.onchange('product_uom_qty', 'product_uom')
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_blanket_order
VERSION
VERSION 1.0.3
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERSMaxime Chambreuil, Denis Roussel, tafaRU, OCA Transbot, oca-travis, Weblate, OCA-git-bot
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:29:17
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/web:
    - web_action_conditionable
odoo/odoo:
    - uom
    - base
    - sale_management
    - sale
    - sales_team
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - payment
    - account
    - product
    - decimal_precision
    - analytic
    - portal
    - http_routing
    - digest
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (12)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_blanket_order_line_form sale.blanket.order.line.form sale.blanket.order.line form New
sale_blanket_order_line_search sale.blanket.order.line.search sale.blanket.order.line search New
sale_blanket_order_line_tree sale.blanket.order.line.tree sale.blanket.order.line tree New
sale_config_settings_form_view res.config.settings.form (in sale_blanket_order) res.config.settings xpath Inherits sale.res_config_settings_view_form
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.tree sale.blanket.order tree New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order xpath Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (7)

New fields (1)
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (26)
  • amount_tax Monetary
    compute='_compute_amount_all' readonly=True store=True string='Taxes'
  • amount_total Monetary
    compute='_compute_amount_all' readonly=True store=True string='Total'
  • amount_untaxed Monetary
    compute='_compute_amount_all' readonly=True store=True string='Untaxed Amount' track_visibility='always'
  • client_order_ref Char
    copy=False readonly=True states={'draft': [('readonly', False)]} string='Customer Reference'
  • company_id Many2one → res.company
    default=_default_company readonly=True states={'draft': [('readonly', False)]} string='Company' args: 'res.company'
  • confirmed Boolean
    copy=False
  • currency_id Many2one → res.currency
    related='pricelist_id.currency_id' args: 'res.currency'
  • delivered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_delivered_uom_qty' string='Delivered quantity'
  • fiscal_position_id Many2one → account.fiscal.position
    string='Fiscal Position' args: 'account.fiscal.position'
  • invoiced_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_invoiced_uom_qty' string='Invoiced quantity'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Sale Blanket Order Line count'
  • line_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    copy=False default='Draft' readonly=True
  • note Text
    readonly=True states={'draft': [('readonly', False)]}
  • ordered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_ordered_uom_qty' string='Ordered quantity'
  • original_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_original_uom_qty' string='Original quantity'
  • partner_id Many2one → res.partner
    readonly=True states={'draft': [('readonly', False)]} string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    readonly=True states={'draft': [('readonly', False)]} string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    readonly=True required=True states={'draft': [('readonly', False)]} string='Pricelist' args: 'product.pricelist'
  • product_id Many2one → product.product
    related='line_ids.product_id' string='Product' args: 'product.product'
  • remaining_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_remaining_uom_qty' string='Remaining quantity'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' copy=False selection=[('draft', 'Draft'), ('open', 'Open'), ('done', 'Done'), ('expired', 'Expired')] store=True
  • team_id Many2one → crm.team
    change_default=True default=_get_default_team readonly=True states={'draft': [('readonly', False)]} string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    readonly=True states={'draft': [('readonly', False)]} string='Salesperson' args: 'res.users'
  • validity_date Date
    readonly=True states={'draft': [('readonly', False)]}
Public methods (8)
  • action_cancel(self)
    @api.multi
  • action_confirm(self)
    @api.multi
  • action_view_sale_blanket_order_line(self)
    @api.multi
  • action_view_sale_orders(self)
    @api.multi
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.multi@api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term - Fiscal position
  • set_to_draft(self)
    @api.multi
  • unlink(self)
    @api.multi

New fields (24)
  • company_id Many2one → res.company
    related='order_id.company_id' store=True args: 'res.company'
  • currency_id Many2one → res.currency
    related='order_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • delivered_uom_qty Float
    compute='_compute_quantities' store=True string='Delivered quantity'
  • invoiced_uom_qty Float
    compute='_compute_quantities' store=True string='Invoiced quantity'
  • name Char
    track_visibility='onchange' args: 'Description'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_uom_qty Float
    compute='_compute_quantities' store=True string='Ordered quantity'
  • original_uom_qty Float
    default=1 digits=dp.get_precision('Product Unit of Measure') required=True string='Original quantity'
  • partner_id Many2one
    related='order_id.partner_id' string='Customer'
  • payment_term_id Many2one
    related='order_id.payment_term_id' string='Payment Terms'
  • price_subtotal Monetary
    compute='_compute_amount' store=True string='Subtotal'
  • price_tax Float
    compute='_compute_amount' store=True string='Tax'
  • price_total Monetary
    compute='_compute_amount' store=True string='Total'
  • price_unit Float
    digits=dp.get_precision('Product Price') required=True string='Price'
  • pricelist_id Many2one
    related='order_id.pricelist_id' string='Pricelist'
  • product_id Many2one → product.product
    domain=[('sale_ok', '=', True)] required=True string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    required=True string='Unit of Measure' args: 'uom.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity in base UoM'
  • remaining_uom_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity'
  • sale_lines One2many → sale.order.line
    copy=False readonly=True string='Sale order lines' args: 'sale.order.line', 'blanket_order_line'
  • sequence Integer
  • taxes_id Many2many → account.tax
    domain=['|', ('active', '=', False), ('active', '=', True)] string='Taxes' args: 'account.tax'
  • user_id Many2one
    related='order_id.user_id' string='Responsible'
Public methods (2)
  • name_get(self)
  • onchange_product(self)
    @api.multi@api.onchange('product_id', 'original_uom_qty')

New fields (3)
  • blanket_order_id Many2one → sale.blanket.order
    readonly=True args: 'sale.blanket.order'
  • line_ids One2many → sale.blanket.order.wizard.line
    default=_default_lines string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
  • sale_order_id Many2one → sale.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'sale.order'
Public methods (1)
  • create_sale_order(self)
    @api.multi

New fields (11)
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • currency_id Many2one → res.currency
    related='blanket_line_id.currency_id' args: 'res.currency'
  • date_schedule Date
    related='blanket_line_id.date_schedule'
  • partner_id Many2one → res.partner
    related='blanket_line_id.partner_id' string='Vendor' args: 'res.partner'
  • price_unit Float
    related='blanket_line_id.price_unit'
  • product_id Many2one → product.product
    related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • product_uom Many2one → uom.uom
    related='blanket_line_id.product_uom' string='Unit of Measure' args: 'uom.uom'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_uom_qty Float
    related='blanket_line_id.remaining_uom_qty'
  • taxes_id Many2many → account.tax
    related='blanket_line_id.taxes_id' args: 'account.tax'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (1)
  • blanket_order_id Many2one → sale.blanket.order
    related='order_line.blanket_order_line.order_id' string='Origin blanket order' args: 'sale.blanket.order'
Public methods (2)
  • button_confirm(self)
    @api.multi
  • check_partner_id(self)
    @api.constrains('partner_id')

New fields (1)
  • blanket_order_line Many2one → sale.blanket.order.line
    copy=False string='Blanket Order line' args: 'sale.blanket.order.line'
Public methods (6)
  • check_currency(self)
    @api.constrains('currency_id')
  • check_product_id(self)
    @api.constrains('product_id')
  • get_assigned_bo_line(self)
    @api.multi
  • onchange_blanket_order_line(self)
    @api.onchange('blanket_order_line')
  • onchange_product_id(self)
    @api.onchange('product_id', 'order_partner_id')
  • product_uom_change(self)
    @api.onchange('product_uom_qty', 'product_uom')
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/11.0/sale_blanket_order
VERSION
VERSION 1.0.2
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERStafaRU, OCA Transbot, oca-travis, Weblate, OCA-git-bot, Adrià Gil Sorribes
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:23:57
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/web:
    - web_action_conditionable
odoo/odoo:
    - sale
    - sales_team
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - account
    - product
    - decimal_precision
    - analytic
    - web_planner
    - portal
    - http_routing
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (12)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_blanket_order_line_form sale.blanket.order.line.form sale.blanket.order.line form New
sale_blanket_order_line_search sale.blanket.order.line.search sale.blanket.order.line search New
sale_blanket_order_line_tree sale.blanket.order.line.tree sale.blanket.order.line tree New
sale_config_settings_form_view res.config.settings.form (in sale_blanket_order) res.config.settings xpath Inherits sale.res_config_settings_view_form
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.tree sale.blanket.order tree New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order xpath Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (7)

New fields (1)
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (26)
  • amount_tax Monetary
    compute='_amount_all' readonly=True store=True string='Taxes'
  • amount_total Monetary
    compute='_amount_all' readonly=True store=True string='Total'
  • amount_untaxed Monetary
    compute='_amount_all' readonly=True store=True string='Untaxed Amount' track_visibility='always'
  • client_order_ref Char
    copy=False readonly=True states={'draft': [('readonly', False)]} string='Customer Reference'
  • company_id Many2one → res.company
    default=_default_company readonly=True states={'draft': [('readonly', False)]} string='Company' args: 'res.company'
  • confirmed Boolean
  • currency_id Many2one → res.currency
    readonly=True related='pricelist_id.currency_id' args: 'res.currency'
  • delivered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_delivered_uom_qty' string='Delivered quantity'
  • fiscal_position_id Many2one → account.fiscal.position
    string='Fiscal Position' args: 'account.fiscal.position'
  • invoiced_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_invoiced_uom_qty' string='Invoiced quantity'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Sale Blanket Order Line count'
  • line_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    default='Draft' readonly=True
  • note Text
    readonly=True states={'draft': [('readonly', False)]}
  • ordered_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_ordered_uom_qty' string='Ordered quantity'
  • original_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_original_uom_qty' string='Original quantity'
  • partner_id Many2one → res.partner
    readonly=True states={'draft': [('readonly', False)]} string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    readonly=True states={'draft': [('readonly', False)]} string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    readonly=True required=True states={'draft': [('readonly', False)]} string='Pricelist' args: 'product.pricelist'
  • product_id Many2one → product.product
    related='line_ids.product_id' string='Product' args: 'product.product'
  • remaining_uom_qty Float
    compute='_compute_uom_qty' default=0.0 search='_search_remaining_uom_qty' string='Remaining quantity'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' copy=False selection=[('draft', 'Draft'), ('open', 'Open'), ('done', 'Done'), ('expired', 'Expired')] store=True
  • team_id Many2one → crm.team
    change_default=True default=_get_default_team readonly=True states={'draft': [('readonly', False)]} string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    readonly=True states={'draft': [('readonly', False)]} string='Salesperson' args: 'res.users'
  • validity_date Date
    readonly=True states={'draft': [('readonly', False)]}
Public methods (9)
  • action_cancel(self)
    @api.multi
  • action_confirm(self)
    @api.multi
  • action_view_sale_blanket_order_line(self)
    @api.multi
  • action_view_sale_orders(self)
    @api.multi
  • copy_data(self, default=None)
    @api.multi
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.multi@api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term - Fiscal position
  • set_to_draft(self)
    @api.multi
  • unlink(self)
    @api.multi

New fields (24)
  • company_id Many2one → res.company
    readonly=True related='order_id.company_id' store=True args: 'res.company'
  • currency_id Many2one → res.currency
    readonly=True related='order_id.currency_id' args: 'res.currency'
  • date_schedule Date
    string='Scheduled Date'
  • delivered_uom_qty Float
    compute='_compute_quantities' store=True string='Delivered quantity'
  • invoiced_uom_qty Float
    compute='_compute_quantities' store=True string='Invoiced quantity'
  • name Char
    track_visibility='onchange' args: 'Description'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_uom_qty Float
    compute='_compute_quantities' store=True string='Ordered quantity'
  • original_uom_qty Float
    default=1 digits=dp.get_precision('Product Unit of Measure') required=True string='Original quantity'
  • partner_id Many2one
    readonly=True related='order_id.partner_id' string='Customer'
  • payment_term_id Many2one
    readonly=True related='order_id.payment_term_id' string='Payment Terms'
  • price_subtotal Monetary
    compute='_compute_amount' store=True string='Subtotal'
  • price_tax Float
    compute='_compute_amount' store=True string='Tax'
  • price_total Monetary
    compute='_compute_amount' store=True string='Total'
  • price_unit Float
    digits=dp.get_precision('Product Price') required=True string='Price'
  • pricelist_id Many2one
    readonly=True related='order_id.pricelist_id' string='Pricelist'
  • product_id Many2one → product.product
    domain=[('sale_ok', '=', True)] required=True string='Product' args: 'product.product'
  • product_uom Many2one → product.uom
    required=True string='Unit of Measure' args: 'product.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity in base UoM'
  • remaining_uom_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity'
  • sale_lines One2many → sale.order.line
    copy=False readonly=True string='Sale order lines' args: 'sale.order.line', 'blanket_order_line'
  • sequence Integer
  • taxes_id Many2many → account.tax
    domain=['|', ('active', '=', False), ('active', '=', True)] string='Taxes' args: 'account.tax'
  • user_id Many2one
    readonly=True related='order_id.user_id' string='Responsible'
Public methods (2)
  • name_get(self)
  • onchange_product(self)
    @api.multi@api.onchange('product_id', 'original_uom_qty')

New fields (3)
  • blanket_order_id Many2one → sale.blanket.order
    readonly=True args: 'sale.blanket.order'
  • line_ids One2many → sale.blanket.order.wizard.line
    default=_default_lines string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
  • sale_order_id Many2one → sale.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'sale.order'
Public methods (1)
  • create_sale_order(self)
    @api.multi

New fields (11)
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • currency_id Many2one → res.currency
    related='blanket_line_id.currency_id' args: 'res.currency'
  • date_schedule Date
    readonly=True related='blanket_line_id.date_schedule'
  • partner_id Many2one → res.partner
    readonly=True related='blanket_line_id.partner_id' string='Vendor' args: 'res.partner'
  • price_unit Float
    readonly=True related='blanket_line_id.price_unit'
  • product_id Many2one → product.product
    readonly=True related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • product_uom Many2one → product.uom
    readonly=True related='blanket_line_id.product_uom' string='Unit of Measure' args: 'product.uom'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_uom_qty Float
    readonly=True related='blanket_line_id.remaining_uom_qty'
  • taxes_id Many2many → account.tax
    readonly=True related='blanket_line_id.taxes_id' args: 'account.tax'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (1)
  • blanket_order_id Many2one → sale.blanket.order
    readonly=True related='order_line.blanket_order_line.order_id' string='Origin blanket order' args: 'sale.blanket.order'
Public methods (2)
  • button_confirm(self)
    @api.multi
  • check_partner_id(self)
    @api.constrains('partner_id')

New fields (1)
  • blanket_order_line Many2one → sale.blanket.order.line
    copy=False string='Blanket Order line' args: 'sale.blanket.order.line'
Public methods (6)
  • check_currency(self)
    @api.constrains('currency_id')
  • check_product_id(self)
    @api.constrains('product_id')
  • get_assigned_bo_line(self)
    @api.multi
  • onchange_blanket_order_line(self)
    @api.onchange('blanket_order_line')
  • onchange_product_id(self)
    @api.onchange('product_id', 'order_partner_id')
  • product_uom_change(self)
    @api.onchange('product_uom_qty', 'product_uom')
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/10.0/sale_blanket_order
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYSales
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Acsone SA/NV
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Acsone SA/NV
COMMITTERS
COMMITTERSDenis Roussel, OCA Transbot, oca-travis, OCA-git-bot
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:19:56
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/web:
    - web_action_conditionable
odoo/odoo:
    - sale
    - sales_team
    - base
    - mail
    - base_setup
    - web_kanban
    - web
    - bus
    - web_tour
    - account
    - product
    - decimal_precision
    - report
    - analytic
    - web_planner
    - procurement
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (9)
XML IDNameModelTypeStatus
report_blanketorder report_blanketorder ir.ui.view qweb New
report_blanketorder_document report_blanketorder_document ir.ui.view qweb New
sale_config_settings_form_view sale.config.settings.form (in sale_blanket_order) sale.config.settings xpath Inherits sale.view_sales_config
view_blanket_order_form sale.blanket.order.form sale.blanket.order form New
view_blanket_order_search sale.blanket.order.search sale.blanket.order search New
view_blanket_order_tree sale.blanket.order.tree sale.blanket.order tree New
view_create_sale_order Create Sale Order sale.blanket.order.wizard form New
view_order_form sale.order.from.blanket.form sale.order xpath Inherits sale.view_order_form
view_order_form_disable_adding_lines sale.order.from.blanket.form - disable adding lines sale.order xpath Inherits sale.view_order_form
Models touched (7)

New fields (15)
  • client_order_ref Char
    copy=False readonly=True states={'draft': [('readonly', False)]} string='Customer Reference'
  • company_id Many2one → res.company
    default=_default_company readonly=True states={'draft': [('readonly', False)]} string='Company' args: 'res.company'
  • confirmed Boolean
    copy=False
  • currency_id Many2one → res.currency
    readonly=True related='pricelist_id.currency_id' args: 'res.currency'
  • lines_ids One2many → sale.blanket.order.line
    copy=True string='Order lines' args: 'sale.blanket.order.line', 'order_id'
  • name Char
    copy=False default='Draft' readonly=True
  • note Text
    readonly=True states={'draft': [('readonly', False)]}
  • partner_id Many2one → res.partner
    readonly=True states={'draft': [('readonly', False)]} string='Partner' args: 'res.partner'
  • payment_term_id Many2one → account.payment.term
    readonly=True states={'draft': [('readonly', False)]} string='Payment Terms' args: 'account.payment.term'
  • pricelist_id Many2one → product.pricelist
    readonly=True required=True states={'draft': [('readonly', False)]} string='Pricelist' args: 'product.pricelist'
  • sale_count Integer
    compute='_compute_sale_count'
  • state Selection
    compute='_compute_state' selection=[('draft', 'Draft'), ('opened', 'Open'), ('expired', 'Expired')] store=True
  • team_id Many2one → crm.team
    change_default=True default=_get_default_team readonly=True states={'draft': [('readonly', False)]} string='Sales Team' args: 'crm.team'
  • user_id Many2one → res.users
    readonly=True states={'draft': [('readonly', False)]} string='Salesperson' args: 'res.users'
  • validity_date Date
    readonly=True states={'draft': [('readonly', False)]}
Public methods (4)
  • action_confirm(self)
    @api.multi
  • action_view_sale_orders(self)
    @api.multi
  • expire_orders(self)
    @api.model
  • onchange_partner_id(self)
    @api.multi@api.onchange('partner_id')
    Update the following fields when the partner is changed: - Pricelist - Payment term

New fields (12)
  • company_id Many2one → res.company
    readonly=True related='order_id.company_id' store=True args: 'res.company'
  • delivered_qty Float
    compute='_compute_quantities' store=True string='Delivered quantity'
  • invoiced_qty Float
    compute='_compute_quantities' store=True string='Invoiced quantity'
  • order_id Many2one → sale.blanket.order
    ondelete='cascade' required=True args: 'sale.blanket.order'
  • ordered_qty Float
    compute='_compute_quantities' store=True string='Ordered quantity'
  • original_qty Float
    default=1 digits=dp.get_precision('Product Unit of Measure') required=True string='Original quantity'
  • price_unit Float
    required=True string='Price'
  • product_id Many2one → product.product
    required=True string='Product' args: 'product.product'
  • product_uom Many2one → product.uom
    required=True string='Unit of Measure' args: 'product.uom'
  • remaining_qty Float
    compute='_compute_quantities' store=True string='Remaining quantity'
  • sale_order_lines_ids One2many → sale.order.line
    string='Sale order lines' args: 'sale.order.line', 'blanket_line_id'
  • sequence Integer
Public methods (1)
  • onchange_product(self)
    @api.multi@api.onchange('product_id', 'original_qty')

New fields (2)
  • blanket_order_id Many2one → sale.blanket.order
    default=_default_order readonly=True args: 'sale.blanket.order'
  • lines_ids One2many → sale.blanket.order.wizard.line
    default=_default_lines string='Lines' args: 'sale.blanket.order.wizard.line', 'wizard_id'
Public methods (1)
  • create_sale_order(self)
    @api.multi

New fields (5)
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
  • product_id Many2one → product.product
    readonly=True related='blanket_line_id.product_id' string='Product' args: 'product.product'
  • qty Float
    required=True string='Quantity to Order'
  • remaining_qty Float
    readonly=True related='blanket_line_id.remaining_qty'
  • wizard_id Many2one → sale.blanket.order.wizard
    args: 'sale.blanket.order.wizard'
Public methods (0)

No public methods.

New fields (1)
  • group_blanket_disable_adding_lines Boolean
    implied_group='sale_blanket_order.blanket_orders_disable_adding_lines' string='Disable adding more lines to SOs'
Public methods (0)

No public methods.

New fields (1)
  • blanket_order_id Many2one → sale.blanket.order
    readonly=True related='order_line.blanket_line_id.order_id' string='Origin blanket order' args: 'sale.blanket.order'
Public methods (0)

No public methods.

New fields (1)
  • blanket_line_id Many2one → sale.blanket.order.line
    args: 'sale.blanket.order.line'
Public methods (0)

No public methods.