Sale Block no Stock

sale_block_no_stock
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/18.0/sale_block_no_stock
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Moduon
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Moduon
COMMITTERS
COMMITTERSRuchir Shukla, Weblate, OCA-git-bot, oca-ci
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:11
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/server-ux:
    - mail_message_destiny_link_template
odoo/odoo:
    - sale_stock
    - sale
    - sales_team
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - account_payment
    - account
    - onboarding
    - product
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - payment
    - utm
    - stock_account
    - stock
    - barcodes_gs1_nomenclature
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module extends the functionality of Sales to support blocking sales and to allow you to ensure you are capable to send product you have in stock.

When a Sale Order is going to be confirmed, it will be checked if the quantity demanded exceeds that of the field selected in the configuration, and in this case a wizard will appear to allow you to fix quantities indicating what is the maximum quantity that can be ordered.

Then, you can adjust UoM quantities, Packaging quantities or move remaining unfixed lines to a new order.

If the user who is confirming an order has a group that is allowed, an extra option to confirm the Order with errors will appear on the Wizard.

This module only can block lines with product type 'product' (storable products).

Internal notes will be posted on sales when adjusting quantities or moving to another orders.

Code Analysis

Views touched (2)
XML IDNameModelTypeStatus
res_config_settings_view_form res.config.settings.view.form.inherit.sale.block res.config.settings xpath Inherits sale.res_config_settings_view_form
sale_order_block_wizard_view Sale Order Block sale.order.block.wizard form New
Models touched (5)

New fields (2)
  • sale_line_block_allowed_groups Many2many → res.groups
    comodel_name='res.groups' help='These groups will be able to bypass the block on the Sale Order Lines if the quantity is not enough' string='Allowed Groups to bypass the block'
  • sale_line_field_block Many2one → ir.model.fields
    comodel_name='ir.model.fields' domain=[('model_id.model', '=', 'sale.order.line'), ('name', 'in', ('free_qty_today', 'qty_available_today', 'virtual_available_at_date'))] help='This field will be checked to block the Sale Order Lines if the quantity is not enough' string='Field to compare quantities on Sale Order Lines'
Public methods (0)

No public methods.

New fields (2)
  • sale_line_block_allowed_groups Many2many
    help='These groups will be able to bypass the block on the Sale Order Lines if the quantity is not enough' readonly=False related='company_id.sale_line_block_allowed_groups'
  • sale_line_field_block Many2one
    help='This field will be checked to block the Sale Order Lines if the quantity is not enough' readonly=False related='company_id.sale_line_field_block'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_confirm(self)
    Check the stock of the products before confirming the sale order.

New fields (4)
  • confirmation_allowed Boolean
    compute='_compute_confirmation_allowed' string='Allowed to confirm'
  • is_packaging_adjustable Boolean
    compute='_compute_is_adjustable' compute_sudo=True readonly=True store=True
  • is_uom_adjustable Boolean
    compute='_compute_is_adjustable' compute_sudo=True readonly=True store=True
  • sale_line_block_ids One2many → sale.order.block.wizard.line
    comodel_name='sale.order.block.wizard.line' inverse_name='wizard_id' string='Sale Block Lines'
Public methods (4)
  • action_adjust_packaging_quantity(self)
    Adjust the quantity of the sale lines to the maximum allowed by the packaging.
  • action_adjust_uom_quantity(self)
    Adjust the quantity of the sale lines to the maximum allowed by the UoM.
  • action_move_to_new_order(self)
    Move the sale lines to a new sale order.
  • confirm(self)
    Confirm the sale orders ignoring next possible wizards.

New fields (11)
  • company_id Many2one
    readonly=True related='sale_line_id.order_id.company_id' store=True string='Company'
  • order_id Many2one
    readonly=True related='sale_line_id.order_id' store=True string='Sale Order'
  • product_id Many2one
    readonly=True related='sale_line_id.product_id' store=True string='Product'
  • product_packaging_allowed_max_qty Float
    compute='_compute_allowed_max_qty' compute_sudo=True readonly=True store=True string='Max. Qty. (Pkg.)'
  • product_packaging_id Many2one
    readonly=True related='sale_line_id.product_packaging_id' store=True string='Packaging'
  • product_packaging_qty Float
    readonly=True related='sale_line_id.product_packaging_qty' store=True string='Qty. (Pkg.)'
  • product_uom Many2one
    readonly=True related='sale_line_id.product_uom' store=True string='UoM'
  • product_uom_allowed_max_qty Float
    compute='_compute_allowed_max_qty' compute_sudo=True readonly=True store=True string='Max. Qty. (UoM)'
  • product_uom_qty Float
    readonly=True related='sale_line_id.product_uom_qty' string='Qty. (UoM)'
  • sale_line_id Many2one → sale.order.line
    comodel_name='sale.order.line' required=True string='Sale Line'
  • wizard_id Many2one → sale.order.block.wizard
    comodel_name='sale.order.block.wizard' required=True string='Wizard'
Public methods (0)

No public methods.

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_block_no_stock
VERSION
VERSION 1.0.1
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Moduon
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Moduon
COMMITTERS
COMMITTERSRuchir Shukla, OCA-git-bot, oca-ci
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:20:05
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/server-ux:
    - mail_message_destiny_link_template
odoo/odoo:
    - sale_stock
    - sale
    - sales_team
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - account_payment
    - account
    - onboarding
    - product
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - payment
    - utm
    - stock_account
    - stock
    - barcodes_gs1_nomenclature
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module extends the functionality of Sales to support blocking sales and to allow you to ensure you are capable to send product you have in stock.

When a Sale Order is going to be confirmed, it will be checked if the quantity demanded exceeds that of the field selected in the configuration, and in this case a wizard will appear to allow you to fix quantities indicating what is the maximum quantity that can be ordered.

Then, you can adjust UoM quantities, Packaging quantities or move remaining unfixed lines to a new order.

If the user who is confirming an order has a group that is allowed, an extra option to confirm the Order with errors will appear on the Wizard.

This module only can block lines with product type 'product' (storable products).

Internal notes will be posted on sales when adjusting quantities or moving to another orders.

Code Analysis

Views touched (2)
XML IDNameModelTypeStatus
res_config_settings_view_form res.config.settings.view.form.inherit.sale.block res.config.settings xpath Inherits sale.res_config_settings_view_form
sale_order_block_wizard_view Sale Order Block sale.order.block.wizard form New
Models touched (5)

New fields (2)
  • sale_line_block_allowed_groups Many2many → res.groups
    comodel_name='res.groups' help='These groups will be able to bypass the block on the Sale Order Lines if the quantity is not enough' string='Allowed Groups to bypass the block'
  • sale_line_field_block Many2one → ir.model.fields
    comodel_name='ir.model.fields' domain=[('model_id.model', '=', 'sale.order.line'), ('name', 'in', ('free_qty_today', 'qty_available_today', 'virtual_available_at_date'))] help='This field will be checked to block the Sale Order Lines if the quantity is not enough' string='Field to compare quantities on Sale Order Lines'
Public methods (0)

No public methods.

New fields (2)
  • sale_line_block_allowed_groups Many2many
    help='These groups will be able to bypass the block on the Sale Order Lines if the quantity is not enough' readonly=False related='company_id.sale_line_block_allowed_groups'
  • sale_line_field_block Many2one
    help='This field will be checked to block the Sale Order Lines if the quantity is not enough' readonly=False related='company_id.sale_line_field_block'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_confirm(self)
    Check the stock of the products before confirming the sale order.

New fields (4)
  • confirmation_allowed Boolean
    compute='_compute_confirmation_allowed' string='Allowed to confirm'
  • is_packaging_adjustable Boolean
    compute='_compute_is_adjustable' compute_sudo=True readonly=True store=True
  • is_uom_adjustable Boolean
    compute='_compute_is_adjustable' compute_sudo=True readonly=True store=True
  • sale_line_block_ids One2many → sale.order.block.wizard.line
    comodel_name='sale.order.block.wizard.line' inverse_name='wizard_id' string='Sale Block Lines'
Public methods (4)
  • action_adjust_packaging_quantity(self)
    Adjust the quantity of the sale lines to the maximum allowed by the packaging.
  • action_adjust_uom_quantity(self)
    Adjust the quantity of the sale lines to the maximum allowed by the UoM.
  • action_move_to_new_order(self)
    Move the sale lines to a new sale order.
  • confirm(self)
    Confirm the sale orders ignoring next possible wizards.

New fields (11)
  • company_id Many2one
    readonly=True related='sale_line_id.order_id.company_id' store=True string='Company'
  • order_id Many2one
    readonly=True related='sale_line_id.order_id' store=True string='Sale Order'
  • product_id Many2one
    readonly=True related='sale_line_id.product_id' store=True string='Product'
  • product_packaging_allowed_max_qty Float
    compute='_compute_allowed_max_qty' compute_sudo=True readonly=True store=True string='Max. Qty. (Pkg.)'
  • product_packaging_id Many2one
    readonly=True related='sale_line_id.product_packaging_id' store=True string='Packaging'
  • product_packaging_qty Float
    readonly=True related='sale_line_id.product_packaging_qty' store=True string='Qty. (Pkg.)'
  • product_uom Many2one
    readonly=True related='sale_line_id.product_uom' store=True string='UoM'
  • product_uom_allowed_max_qty Float
    compute='_compute_allowed_max_qty' compute_sudo=True readonly=True store=True string='Max. Qty. (UoM)'
  • product_uom_qty Float
    readonly=True related='sale_line_id.product_uom_qty' string='Qty. (UoM)'
  • sale_line_id Many2one → sale.order.line
    comodel_name='sale.order.line' required=True string='Sale Line'
  • wizard_id Many2one → sale.order.block.wizard
    comodel_name='sale.order.block.wizard' required=True string='Wizard'
Public methods (0)

No public methods.

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_block_no_stock
VERSION
VERSION 2.0.0
CATEGORY
CATEGORYSales/Sales
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Moduon
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Moduon
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, oca-ci, Eduardo De Miguel
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:11:57
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/server-ux:
    - mail_message_destiny_link_template
odoo/odoo:
    - sale_stock
    - sale
    - sales_team
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - account_payment
    - account
    - product
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - payment
    - utm
    - stock_account
    - stock
    - barcodes_gs1_nomenclature
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module extends the functionality of Sales to support blocking sales and to allow you to ensure you are capable to send product you have in stock.

When a Sale Order is going to be confirmed, it will be checked if the quantity demanded exceeds that of the field selected in the configuration, and in this case a wizard will appear to allow you to fix quantities indicating what is the maximum quantity that can be ordered.

Then, you can adjust UoM quantities, Packaging quantities or move remaining unfixed lines to a new order.

If the user who is confirming an order has a group that is allowed, an extra option to confirm the Order with errors will appear on the Wizard.

This module only can block lines with product type 'product' (storable products).

Internal notes will be posted on sales when adjusting quantities or moving to another orders.

Code Analysis

Views touched (2)
XML IDNameModelTypeStatus
res_config_settings_view_form res.config.settings.view.form.inherit.sale.block res.config.settings xpath Inherits sale.res_config_settings_view_form
sale_order_block_wizard_view Sale Order Block sale.order.block.wizard form New
Models touched (5)

New fields (2)
  • sale_line_block_allowed_groups Many2many → res.groups
    comodel_name='res.groups' help='These groups will be able to bypass the block on the Sale Order Lines if the quantity is not enough' string='Allowed Groups to bypass the block'
  • sale_line_field_block Many2one → ir.model.fields
    comodel_name='ir.model.fields' domain=[('model_id.model', '=', 'sale.order.line'), ('name', 'in', ('free_qty_today', 'qty_available_today', 'virtual_available_at_date'))] help='This field will be checked to block the Sale Order Lines if the quantity is not enough' string='Field to compare quantities on Sale Order Lines'
Public methods (0)

No public methods.

New fields (2)
  • sale_line_block_allowed_groups Many2many
    help='These groups will be able to bypass the block on the Sale Order Lines if the quantity is not enough' readonly=False related='company_id.sale_line_block_allowed_groups'
  • sale_line_field_block Many2one
    help='This field will be checked to block the Sale Order Lines if the quantity is not enough' readonly=False related='company_id.sale_line_field_block'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_confirm(self)
    Check the stock of the products before confirming the sale order.

New fields (4)
  • confirmation_allowed Boolean
    compute='_compute_confirmation_allowed' string='Allowed to confirm'
  • is_packaging_adjustable Boolean
    compute='_compute_is_adjustable' compute_sudo=True readonly=True store=True
  • is_uom_adjustable Boolean
    compute='_compute_is_adjustable' compute_sudo=True readonly=True store=True
  • sale_line_block_ids One2many → sale.order.block.wizard.line
    comodel_name='sale.order.block.wizard.line' inverse_name='wizard_id' string='Sale Block Lines'
Public methods (4)
  • action_adjust_packaging_quantity(self)
    Adjust the quantity of the sale lines to the maximum allowed by the packaging.
  • action_adjust_uom_quantity(self)
    Adjust the quantity of the sale lines to the maximum allowed by the UoM.
  • action_move_to_new_order(self)
    Move the sale lines to a new sale order.
  • confirm(self)
    Confirm the sale orders ignoring next possible wizards.

New fields (11)
  • company_id Many2one
    readonly=True related='sale_line_id.order_id.company_id' store=True string='Company'
  • order_id Many2one
    readonly=True related='sale_line_id.order_id' store=True string='Sale Order'
  • product_id Many2one
    readonly=True related='sale_line_id.product_id' store=True string='Product'
  • product_packaging_allowed_max_qty Float
    compute='_compute_allowed_max_qty' compute_sudo=True readonly=True store=True string='Max. Qty. (Pkg.)'
  • product_packaging_id Many2one
    readonly=True related='sale_line_id.product_packaging_id' store=True string='Packaging'
  • product_packaging_qty Float
    readonly=True related='sale_line_id.product_packaging_qty' store=True string='Qty. (Pkg.)'
  • product_uom Many2one
    readonly=True related='sale_line_id.product_uom' store=True string='UoM'
  • product_uom_allowed_max_qty Float
    compute='_compute_allowed_max_qty' compute_sudo=True readonly=True store=True string='Max. Qty. (UoM)'
  • product_uom_qty Float
    readonly=True related='sale_line_id.product_uom_qty' string='Qty. (UoM)'
  • sale_line_id Many2one → sale.order.line
    comodel_name='sale.order.line' required=True string='Sale Line'
  • wizard_id Many2one → sale.order.block.wizard
    comodel_name='sale.order.block.wizard' required=True string='Wizard'
Public methods (0)

No public methods.

STATUS
STATUSOpen migration PR - not merged yet for this version
REPOSITORY
REPOSITORYOCA/sale-workflow
PULL REQUEST
PULL REQUEST[19.0][MIG] sale_block_no_stock: Migration to 19.0 (#4181)