Purchase Request

purchase_request
REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/19.0/purchase_request
VERSION
VERSION 1.0.1
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, oca-ci, Bhavesh Heliconia, mav-adhoc
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:40:50
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase_stock
    - stock_account
    - stock
    - product
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - uom
    - barcodes_gs1_nomenclature
    - barcodes
    - digest
    - portal
    - http_routing
    - auth_signup
    - resource
    - account
    - onboarding
    - analytic
    - purchase
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
You use this module if you wish to give notification of requirements of
materials and/or external services and keep track of such requirements.

Requests can be created either directly or indirectly. "Directly" means
that someone from the requesting department enters a purchase request
manually.

The person creating the request determines what and how much to order,
and the requested date.

"Indirectly" means that the purchase request initiated by the
application automatically, for example, from procurement orders (MO,
SO).

A purchase request is an instruction to Purchasing to procure a certain
quantity of materials services, so that they are available at a certain
point in time.

A line of a request contains the quantity and requested date of the
material to be supplied or the quantity of the service to be performed.
You can indicate the service specifications if needed.

Once request is approved go to the Purchase Request Lines from the menu
entry 'Purchase Requests', and also from the 'Purchase' menu.

Select the lines that you wish to initiate the RFQ for, then go to
'More' and press 'Create RFQ'.

You can choose to select an existing RFQ or create a new one. In the
later, you have to choose a supplier.

In case that you chose to select an existing RFQ, the application will
search for existing lines matching the request line, and will add the
extra quantity to them, recalculating the minimum order quantity, if it
exists for the supplier of that RFQ.

In case that you create a new RFQ, the request lines will also be
consolidated into as few as possible lines in the RFQ.

Code Analysis

Views touched (20)
XML IDNameModelTypeStatus
product_template_form_view_inherit product.template.form.inherit product.template group Inherits stock.view_template_property_form
purchase_order_form purchase.order.form purchase.order xpath Inherits purchase.purchase_order_form
purchase_order_line_form2 purchase.order.line.form2 purchase.order.line field Inherits purchase.purchase_order_line_form2
purchase_order_line_form2_sub purchase.order.line.form2 purchase.order.line form New
purchase_order_line_search_sub purchase.order.line.search purchase.order.line search New
purchase_order_line_tree purchase.order.line.list purchase.order.line xpath Inherits purchase.purchase_order_line_tree
purchase_order_line_tree_sub purchase.order.line.list purchase.order.line list New
purchase_request_allocation purchase.request.allocation purchase.request.allocation list New
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.list purchase.request.line list New
report_purchase_request report_purchase_request ir.ui.view qweb New
view_move_form stock.move.form stock.move group Inherits stock.view_move_form
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_kanban purchase.request.kanban purchase.request kanban New
view_purchase_request_line_details purchase.request.line.details.form purchase.request.line form New
view_purchase_request_line_make_purchase_order Purchase Request Line Make Purchase Order purchase.request.line.make.purchase.order form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.list purchase.request list New
view_stock_move_operations stock.move.operations.form stock.move field Inherits stock.view_stock_move_operations
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (12)

New fields (1)
  • purchase_request Boolean
    company_dependent=True help='Check this box to generate Purchase Request instead of generating Requests For Quotation from procurement.'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • button_confirm(self)
  • unlink(self)

New fields (2)
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='purchase_line_id' string='Purchase Request Allocation'
  • purchase_request_lines Many2many → purchase.request.line
    column1='purchase_order_line_id' column2='purchase_request_line_id' comodel_name='purchase.request.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel'
Public methods (3)
  • action_open_request_line_tree_view(self)
    :return dict: dictionary value for created view
  • update_service_allocations(self, prev_qty_received)
  • write(self, vals)

New fields (19)
  • assigned_to Many2one → res.users
    comodel_name='res.users' domain=<expr> index=True string='Approver' tracking=True
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=False tracking=True
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' string='Creation date' tracking=True
  • description Text
  • estimated_cost Monetary
    compute='_compute_estimated_cost' store=True string='Total Estimated Cost'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • is_name_editable Boolean
    default=<expr>
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    comodel_name='purchase.request.line' copy=True inverse_name='request_id' readonly=False string='Products to Purchase' tracking=True
  • move_count Integer
    compute='_compute_move_count' readonly=True string='Stock Move count'
  • name Char
    default=<expr> required=True string='Request Reference' tracking=True
  • origin Char
    string='Source Document'
  • picking_type_id Many2one → stock.picking.type
    comodel_name='stock.picking.type' default=<expr> required=True string='Picking Type'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='line_ids.product_id' string='Product'
  • purchase_count Integer
    compute='_compute_purchase_count' readonly=True string='Purchases count'
  • requested_by Many2one → res.users
    comodel_name='res.users' copy=False default=<expr> index=True required=True tracking=True
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' tracking=True
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (14)
  • action_view_purchase_order(self)
  • action_view_purchase_request_line(self)
  • action_view_stock_picking(self)
  • button_approved(self)
  • button_done(self)
  • button_draft(self)
  • button_in_progress(self)
  • button_rejected(self)
  • button_to_approve(self)
  • check_auto_reject(self)
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • to_approve_allowed_check(self)
  • write(self, vals)

New fields (10)
  • allocated_product_qty Float
    copy=False help='Quantity of the purchase request line allocated to the stockmove, in the default UoM of the product' string='Allocated Quantity'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True readonly=True related='purchase_request_line_id.request_id.company_id' store=True string='Company'
  • open_product_qty Float
    compute='_compute_open_product_qty' string='Open Quantity'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='purchase_request_line_id.product_id' string='Product'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' readonly=True related='purchase_request_line_id.product_uom_id' required=True string='UoM'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' copy=True help='Service Purchase Order Line' index=True ondelete='cascade' string='Purchase Line'
  • purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=True index=True ondelete='cascade' required=True string='Purchase Request Line'
  • purchase_state Selection
    related='purchase_line_id.state'
  • requested_product_uom_qty Float
    help='Quantity of the purchase request line allocated to thestock move, in the UoM of the Purchase Request Line' string='Requested Quantity'
  • stock_move_id Many2one → stock.move
    comodel_name='stock.move' index=True ondelete='cascade' string='Stock Move'
Public methods (0)

No public methods.

New fields (30)
  • assigned_to Many2one → res.users
    comodel_name='res.users' related='request_id.assigned_to' store=True string='Assigned to'
  • cancelled Boolean
    copy=False default=False readonly=True
  • company_id Many2one → res.company
    comodel_name='res.company' index=True related='request_id.company_id' store=True string='Company'
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' tracking=True
  • date_start Date
    related='request_id.date_start' store=True
  • description Text
    readonly=False related='request_id.description' store=True string='PR Description'
  • estimated_cost Monetary
    currency_field='currency_id' default=0.0 help='Estimated cost of Purchase Request Line, not propagated to PO.'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • move_dest_ids One2many → stock.move
    comodel_name='stock.move' inverse_name='created_purchase_request_line_id' string='Downstream Moves'
  • name Char
    string='Description' tracking=True
  • orderpoint_id Many2one → stock.warehouse.orderpoint
    comodel_name='stock.warehouse.orderpoint' string='Orderpoint'
  • origin Char
    related='request_id.origin' store=True string='Source Document'
  • pending_qty_to_receive Float
    compute='_compute_qty_to_buy' copy=False digits='Product Unit of Measure' store=True string='Pending Qty to Receive'
  • product_id Many2one → product.product
    comodel_name='product.product' domain=[('purchase_ok', '=', True)] string='Product' tracking=True
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity' tracking=True
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' string='UoM' tracking=True
  • purchase_lines Many2many → purchase.order.line
    column1='purchase_request_line_id' column2='purchase_order_line_id' comodel_name='purchase.order.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel' string='Purchase Order Lines'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' inverse_name='purchase_request_line_id' string='Purchase Request Allocation'
  • purchase_state Selection
    compute='_compute_purchase_state' selection=<expr> store=True string='Purchase Status'
  • purchased_qty Float
    compute='_compute_purchased_qty' digits='Product Unit of Measure' string='RFQ/PO Qty'
  • qty_cancelled Float
    compute='_compute_qty_cancelled' digits='Product Unit of Measure' help='Quantity cancelled' readonly=True store=True
  • qty_done Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity completed' readonly=True store=True
  • qty_in_progress Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity in progress.' readonly=True store=True
  • qty_to_buy Boolean
    compute='_compute_qty_to_buy' store=True string='There is some pending qty to buy'
  • request_id Many2one → purchase.request
    comodel_name='purchase.request' index=True ondelete='cascade' readonly=True string='Purchase Request'
  • request_state Selection
    related='request_id.state' store=True string='Request state'
  • requested_by Many2one → res.users
    comodel_name='res.users' related='request_id.requested_by' store=True string='Requested by'
  • specifications Text
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' compute='_compute_supplier_id' compute_sudo=True store=True string='Preferred supplier'
Public methods (5)
  • action_show_details(self)
  • do_cancel(self)
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • write(self, vals)

New fields (4)
  • item_ids One2many → purchase.request.line.make.purchase.order.item
    comodel_name='purchase.request.line.make.purchase.order.item' inverse_name='wiz_id' string='Items'
  • purchase_order_id Many2one → purchase.order
    comodel_name='purchase.order' domain=[('state', '=', 'draft')] string='Purchase Order'
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' context={'res_partner_search_mode': 'supplier'} required=True string='Supplier'
  • sync_data_planned Boolean
    help='When checked, PO lines on the selected purchase order are only reused if the scheduled date matches as well.' string='Match existing PO lines by Scheduled Date'
Public methods (4)
  • create_allocation(self, po_line, pr_line, new_qty, alloc_uom)
  • default_get(self, fields)
    @api.model
  • get_items(self, request_line_ids)
    @api.model
  • make_purchase_order(self)

New fields (8)
  • keep_description Boolean
    help='Set true if you want to keep the descriptions provided in the wizard in the new PO.' string='Copy descriptions to new PO'
  • line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' string='Purchase Request Line'
  • name Char
    required=True string='Description'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=False related='line_id.product_id' string='Product'
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity to purchase'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' required=True string='UoM'
  • request_id Many2one → purchase.request
    comodel_name='purchase.request' readonly=False related='line_id.request_id' string='Purchase Request'
  • wiz_id Many2one → purchase.request.line.make.purchase.order
    comodel_name='purchase.request.line.make.purchase.order' ondelete='cascade' readonly=True required=True string='Wizard'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id')

New fields (3)
  • created_purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=False index=True ondelete='set null' readonly=True string='Created Purchase Request Line'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='stock_move_id' string='Purchase Request Allocation'
  • purchase_request_ids One2many → purchase.request
    comodel_name='purchase.request' compute='_compute_purchase_request_ids' string='Purchase Requests'
Public methods (1)
  • copy_data(self, default=None)
    Propagate request allocation on copy. If this move is being split, or if this move is processed and there is a remaining allocation, move the appropriate quantity over to the new move.

New fields (0)

No new fields.

Public methods (1)
  • allocate(self)

New fields (0)

No new fields.

Public methods (2)
  • create_purchase_request(self, procurement_group)
    Create a purchase request containing procurement order product.
  • is_create_purchase_request_allowed(self, procurement)
    Tell if current procurement order should create a purchase request or not. :return: boolean

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/18.0/purchase_request
VERSION
VERSION 2.5.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow
COMMITTERS
COMMITTERSStefan Rijnhart, Pere Albujer, Carlos Lopez, Andrius Laukavičius, Víctor Martínez, AaronHForgeFlow, Weblate, OCA-git-bot, oca-ci, Hector Vior, LauraCForgeFlow, Andy Quijada, Quoc - Pham Ngoc, César León
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:17
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase_stock
    - stock_account
    - stock
    - product
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - uom
    - barcodes_gs1_nomenclature
    - barcodes
    - digest
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - resource
    - account
    - onboarding
    - analytic
    - purchase
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
You use this module if you wish to give notification of requirements of
materials and/or external services and keep track of such requirements.

Requests can be created either directly or indirectly. "Directly" means
that someone from the requesting department enters a purchase request
manually.

The person creating the request determines what and how much to order,
and the requested date.

"Indirectly" means that the purchase request initiated by the
application automatically, for example, from procurement orders (MO,
SO).

A purchase request is an instruction to Purchasing to procure a certain
quantity of materials services, so that they are available at a certain
point in time.

A line of a request contains the quantity and requested date of the
material to be supplied or the quantity of the service to be performed.
You can indicate the service specifications if needed.

Once request is approved go to the Purchase Request Lines from the menu
entry 'Purchase Requests', and also from the 'Purchase' menu.

Select the lines that you wish to initiate the RFQ for, then go to
'More' and press 'Create RFQ'.

You can choose to select an existing RFQ or create a new one. In the
later, you have to choose a supplier.

In case that you chose to select an existing RFQ, the application will
search for existing lines matching the request line, and will add the
extra quantity to them, recalculating the minimum order quantity, if it
exists for the supplier of that RFQ.

In case that you create a new RFQ, the request lines will also be
consolidated into as few as possible lines in the RFQ.

Code Analysis

Views touched (20)
XML IDNameModelTypeStatus
product_template_form_view_inherit product.template.form.inherit product.template group Inherits stock.view_template_property_form
purchase_order_form purchase.order.form purchase.order xpath Inherits purchase.purchase_order_form
purchase_order_line_form2 purchase.order.line.form2 purchase.order.line field Inherits purchase.purchase_order_line_form2
purchase_order_line_form2_sub purchase.order.line.form2 purchase.order.line form New
purchase_order_line_search_sub purchase.order.line.search purchase.order.line search New
purchase_order_line_tree purchase.order.line.list purchase.order.line xpath Inherits purchase.purchase_order_line_tree
purchase_order_line_tree_sub purchase.order.line.list purchase.order.line list New
purchase_request_allocation purchase.request.allocation purchase.request.allocation list New
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.list purchase.request.line list New
report_purchase_request report_purchase_request ir.ui.view qweb New
view_move_form stock.move.form stock.move group Inherits stock.view_move_form
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_kanban purchase.request.kanban purchase.request kanban New
view_purchase_request_line_details purchase.request.line.details.form purchase.request.line form New
view_purchase_request_line_make_purchase_order Purchase Request Line Make Purchase Order purchase.request.line.make.purchase.order form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.list purchase.request list New
view_stock_move_operations stock.move.operations.form stock.move field Inherits stock.view_stock_move_operations
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (12)

New fields (1)
  • purchase_request Boolean
    company_dependent=True help='Check this box to generate Purchase Request instead of generating Requests For Quotation from procurement.'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • button_confirm(self)
  • unlink(self)

New fields (2)
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='purchase_line_id' string='Purchase Request Allocation'
  • purchase_request_lines Many2many → purchase.request.line
    column1='purchase_order_line_id' column2='purchase_request_line_id' comodel_name='purchase.request.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel'
Public methods (3)
  • action_open_request_line_tree_view(self)
    :return dict: dictionary value for created view
  • update_service_allocations(self, prev_qty_received)
  • write(self, vals)

New fields (20)
  • assigned_to Many2one → res.users
    comodel_name='res.users' domain=<expr> index=True string='Approver' tracking=True
  • company_id Many2one → res.company
    comodel_name='res.company' default=_company_get required=False tracking=True
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' string='Creation date' tracking=True
  • description Text
  • estimated_cost Monetary
    compute='_compute_estimated_cost' store=True string='Total Estimated Cost'
  • group_id Many2one → procurement.group
    comodel_name='procurement.group' copy=False index=True string='Procurement Group'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • is_name_editable Boolean
    default=<expr>
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    comodel_name='purchase.request.line' copy=True inverse_name='request_id' readonly=False string='Products to Purchase' tracking=True
  • move_count Integer
    compute='_compute_move_count' readonly=True string='Stock Move count'
  • name Char
    default=<expr> required=True string='Request Reference' tracking=True
  • origin Char
    string='Source Document'
  • picking_type_id Many2one → stock.picking.type
    comodel_name='stock.picking.type' default=_default_picking_type required=True string='Picking Type'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='line_ids.product_id' string='Product'
  • purchase_count Integer
    compute='_compute_purchase_count' readonly=True string='Purchases count'
  • requested_by Many2one → res.users
    comodel_name='res.users' copy=False default=_get_default_requested_by index=True required=True tracking=True
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' tracking=True
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (15)
  • action_view_purchase_order(self)
  • action_view_purchase_request_line(self)
  • action_view_stock_picking(self)
  • button_approved(self)
  • button_done(self)
  • button_draft(self)
  • button_in_progress(self)
  • button_rejected(self)
  • button_to_approve(self)
  • check_auto_reject(self)
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • to_approve_allowed_check(self)
  • unlink(self)
  • write(self, vals)

New fields (10)
  • allocated_product_qty Float
    copy=False help='Quantity of the purchase request line allocated to the stockmove, in the default UoM of the product' string='Allocated Quantity'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True readonly=True related='purchase_request_line_id.request_id.company_id' store=True string='Company'
  • open_product_qty Float
    compute='_compute_open_product_qty' string='Open Quantity'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='purchase_request_line_id.product_id' string='Product'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' readonly=True related='purchase_request_line_id.product_uom_id' required=True string='UoM'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' copy=True help='Service Purchase Order Line' index=True ondelete='cascade' string='Purchase Line'
  • purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=True index=True ondelete='cascade' required=True string='Purchase Request Line'
  • purchase_state Selection
    related='purchase_line_id.state'
  • requested_product_uom_qty Float
    help='Quantity of the purchase request line allocated to thestock move, in the UoM of the Purchase Request Line' string='Requested Quantity'
  • stock_move_id Many2one → stock.move
    comodel_name='stock.move' index=True ondelete='cascade' string='Stock Move'
Public methods (0)

No public methods.

New fields (31)
  • assigned_to Many2one → res.users
    comodel_name='res.users' related='request_id.assigned_to' store=True string='Assigned to'
  • cancelled Boolean
    copy=False default=False readonly=True
  • company_id Many2one → res.company
    comodel_name='res.company' index=True related='request_id.company_id' store=True string='Company'
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' tracking=True
  • date_start Date
    related='request_id.date_start' store=True
  • description Text
    readonly=False related='request_id.description' store=True string='PR Description'
  • estimated_cost Monetary
    currency_field='currency_id' default=0.0 help='Estimated cost of Purchase Request Line, not propagated to PO.'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • move_dest_ids One2many → stock.move
    comodel_name='stock.move' inverse_name='created_purchase_request_line_id' string='Downstream Moves'
  • name Char
    string='Description' tracking=True
  • orderpoint_id Many2one → stock.warehouse.orderpoint
    comodel_name='stock.warehouse.orderpoint' string='Orderpoint'
  • origin Char
    related='request_id.origin' store=True string='Source Document'
  • pending_qty_to_receive Float
    compute='_compute_qty_to_buy' copy=False digits='Product Unit of Measure' store=True string='Pending Qty to Receive'
  • product_id Many2one → product.product
    comodel_name='product.product' domain=[('purchase_ok', '=', True)] string='Product' tracking=True
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity' tracking=True
  • product_uom_category_id Many2one
    related='product_id.uom_id.category_id'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' domain="[('category_id', '=', product_uom_category_id)]" string='UoM' tracking=True
  • purchase_lines Many2many → purchase.order.line
    column1='purchase_request_line_id' column2='purchase_order_line_id' comodel_name='purchase.order.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel' string='Purchase Order Lines'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' inverse_name='purchase_request_line_id' string='Purchase Request Allocation'
  • purchase_state Selection
    compute='_compute_purchase_state' selection=<expr> store=True string='Purchase Status'
  • purchased_qty Float
    compute='_compute_purchased_qty' digits='Product Unit of Measure' string='RFQ/PO Qty'
  • qty_cancelled Float
    compute='_compute_qty_cancelled' digits='Product Unit of Measure' help='Quantity cancelled' readonly=True store=True
  • qty_done Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity completed' readonly=True store=True
  • qty_in_progress Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity in progress.' readonly=True store=True
  • qty_to_buy Boolean
    compute='_compute_qty_to_buy' store=True string='There is some pending qty to buy'
  • request_id Many2one → purchase.request
    auto_join=True comodel_name='purchase.request' index=True ondelete='cascade' readonly=True string='Purchase Request'
  • request_state Selection
    related='request_id.state' store=True string='Request state'
  • requested_by Many2one → res.users
    comodel_name='res.users' related='request_id.requested_by' store=True string='Requested by'
  • specifications Text
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' compute='_compute_supplier_id' compute_sudo=True store=True string='Preferred supplier'
Public methods (6)
  • action_show_details(self)
  • do_cancel(self)
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • unlink(self)
  • write(self, vals)

New fields (4)
  • item_ids One2many → purchase.request.line.make.purchase.order.item
    comodel_name='purchase.request.line.make.purchase.order.item' inverse_name='wiz_id' string='Items'
  • purchase_order_id Many2one → purchase.order
    comodel_name='purchase.order' domain=[('state', '=', 'draft')] string='Purchase Order'
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' context={'res_partner_search_mode': 'supplier'} required=True string='Supplier'
  • sync_data_planned Boolean
    help='When checked, PO lines on the selected purchase order are only reused if the scheduled date matches as well.' string='Match existing PO lines by Scheduled Date'
Public methods (5)
  • check_group(self, request_lines)
    @api.model
  • create_allocation(self, po_line, pr_line, new_qty, alloc_uom)
  • default_get(self, fields)
    @api.model
  • get_items(self, request_line_ids)
    @api.model
  • make_purchase_order(self)

New fields (11)
  • currency_id Many2one → res.currency
    readonly=True related='line_id.currency_id' string='Currency' args: 'res.currency'
  • estimated_cost Monetary
    currency_field='currency_id'
  • keep_description Boolean
    help='Set true if you want to keep the descriptions provided in the wizard in the new PO.' string='Copy descriptions to new PO'
  • keep_estimated_cost Boolean
    help='Set true if you want to keep the estimated cost provided in the wizard in the new PO.' string='Copy estimative cost to new PO'
  • line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' string='Purchase Request Line'
  • name Char
    required=True string='Description'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=False related='line_id.product_id' string='Product'
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity to purchase'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' required=True string='UoM'
  • request_id Many2one → purchase.request
    comodel_name='purchase.request' readonly=False related='line_id.request_id' string='Purchase Request'
  • wiz_id Many2one → purchase.request.line.make.purchase.order
    comodel_name='purchase.request.line.make.purchase.order' ondelete='cascade' readonly=True required=True string='Wizard'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id')

New fields (3)
  • created_purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=False index=True ondelete='set null' readonly=True string='Created Purchase Request Line'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='stock_move_id' string='Purchase Request Allocation'
  • purchase_request_ids One2many → purchase.request
    comodel_name='purchase.request' compute='_compute_purchase_request_ids' string='Purchase Requests'
Public methods (1)
  • copy_data(self, default=None)
    Propagate request allocation on copy. If this move is being split, or if this move is processed and there is a remaining allocation, move the appropriate quantity over to the new move.

New fields (0)

No new fields.

Public methods (1)
  • allocate(self)

New fields (0)

No new fields.

Public methods (2)
  • create_purchase_request(self, procurement_group)
    Create a purchase request containing procurement order product.
  • is_create_purchase_request_allowed(self, procurement)
    Tell if current procurement order should create a purchase request or not. :return: boolean

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/17.0/purchase_request
VERSION
VERSION 2.3.4
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow
COMMITTERS
COMMITTERSStefan Rijnhart, Pedro M. Baeza, Pere Albujer, Víctor Martínez, Jesús Alan Ramos Rodríguez, AaronHForgeFlow, Weblate, OCA-git-bot, Jesús Alan Ramos Rodríguez, oca-ci, augusto-weiss, LauraCForgeFlow, ArnauCForgeFlow, Duy (Đỗ Anh), sonhd91, Celina Devigili, mav-adhoc, youring, Matias Peralta, Fernando Guzman Almonte
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:20:09
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase_stock
    - stock_account
    - stock
    - product
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
    - barcodes_gs1_nomenclature
    - barcodes
    - digest
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - resource
    - account
    - onboarding
    - analytic
    - purchase
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
You use this module if you wish to give notification of requirements of
materials and/or external services and keep track of such requirements.

Requests can be created either directly or indirectly. "Directly" means
that someone from the requesting department enters a purchase request
manually.

The person creating the request determines what and how much to order,
and the requested date.

"Indirectly" means that the purchase request initiated by the
application automatically, for example, from procurement orders (MO,
SO).

A purchase request is an instruction to Purchasing to procure a certain
quantity of materials services, so that they are available at a certain
point in time.

A line of a request contains the quantity and requested date of the
material to be supplied or the quantity of the service to be performed.
You can indicate the service specifications if needed.

Once request is approved go to the Purchase Request Lines from the menu
entry 'Purchase Requests', and also from the 'Purchase' menu.

Select the lines that you wish to initiate the RFQ for, then go to
'More' and press 'Create RFQ'.

You can choose to select an existing RFQ or create a new one. In the
later, you have to choose a supplier.

In case that you chose to select an existing RFQ, the application will
search for existing lines matching the request line, and will add the
extra quantity to them, recalculating the minimum order quantity, if it
exists for the supplier of that RFQ.

In case that you create a new RFQ, the request lines will also be
consolidated into as few as possible lines in the RFQ.

Code Analysis

Views touched (20)
XML IDNameModelTypeStatus
product_template_form_view_inherit product.template.form.inherit product.template group Inherits stock.view_template_property_form
purchase_order_form purchase.order.form purchase.order xpath Inherits purchase.purchase_order_form
purchase_order_line_form2 purchase.order.line.form2 purchase.order.line field Inherits purchase.purchase_order_line_form2
purchase_order_line_form2_sub purchase.order.line.form2 purchase.order.line form New
purchase_order_line_search_sub purchase.order.line.search purchase.order.line search New
purchase_order_line_tree purchase.order.line.tree purchase.order.line xpath Inherits purchase.purchase_order_line_tree
purchase_order_line_tree_sub purchase.order.line.tree purchase.order.line tree New
purchase_request_allocation purchase.request.allocation purchase.request.allocation tree New
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchase_request report_purchase_request ir.ui.view qweb New
view_move_form stock.move.form stock.move group Inherits stock.view_move_form
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_kanban purchase.request.kanban purchase.request kanban New
view_purchase_request_line_details purchase.request.line.details.form purchase.request.line form New
view_purchase_request_line_make_purchase_order Purchase Request Line Make Purchase Order purchase.request.line.make.purchase.order form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
view_stock_move_operations stock.move.operations.form stock.move field Inherits stock.view_stock_move_operations
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (12)

New fields (1)
  • purchase_request Boolean
    company_dependent=True help='Check this box to generate Purchase Request instead of generating Requests For Quotation from procurement.'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • button_confirm(self)
  • unlink(self)

New fields (2)
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='purchase_line_id' string='Purchase Request Allocation'
  • purchase_request_lines Many2many → purchase.request.line
    column1='purchase_order_line_id' column2='purchase_request_line_id' comodel_name='purchase.request.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel'
Public methods (3)
  • action_open_request_line_tree_view(self)
    :return dict: dictionary value for created view
  • update_service_allocations(self, prev_qty_received)
  • write(self, vals)

New fields (20)
  • assigned_to Many2one → res.users
    comodel_name='res.users' domain=<expr> index=True string='Approver' tracking=True
  • company_id Many2one → res.company
    comodel_name='res.company' default=_company_get required=False tracking=True
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' string='Creation date' tracking=True
  • description Text
  • estimated_cost Monetary
    compute='_compute_estimated_cost' store=True string='Total Estimated Cost'
  • group_id Many2one → procurement.group
    comodel_name='procurement.group' copy=False index=True string='Procurement Group'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • is_name_editable Boolean
    default=<expr>
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    comodel_name='purchase.request.line' copy=True inverse_name='request_id' readonly=False string='Products to Purchase' tracking=True
  • move_count Integer
    compute='_compute_move_count' readonly=True string='Stock Move count'
  • name Char
    default=<expr> required=True string='Request Reference' tracking=True
  • origin Char
    string='Source Document'
  • picking_type_id Many2one → stock.picking.type
    comodel_name='stock.picking.type' default=_default_picking_type required=True string='Picking Type'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='line_ids.product_id' string='Product'
  • purchase_count Integer
    compute='_compute_purchase_count' readonly=True string='Purchases count'
  • requested_by Many2one → res.users
    comodel_name='res.users' copy=False default=_get_default_requested_by index=True required=True tracking=True
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' tracking=True
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (15)
  • action_view_purchase_order(self)
  • action_view_purchase_request_line(self)
  • action_view_stock_picking(self)
  • button_approved(self)
  • button_done(self)
  • button_draft(self)
  • button_in_progress(self)
  • button_rejected(self)
  • button_to_approve(self)
  • check_auto_reject(self)
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • to_approve_allowed_check(self)
  • unlink(self)
  • write(self, vals)

New fields (10)
  • allocated_product_qty Float
    copy=False help='Quantity of the purchase request line allocated to the stockmove, in the default UoM of the product' string='Allocated Quantity'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True readonly=True related='purchase_request_line_id.request_id.company_id' store=True string='Company'
  • open_product_qty Float
    compute='_compute_open_product_qty' string='Open Quantity'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='purchase_request_line_id.product_id' string='Product'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' readonly=True related='purchase_request_line_id.product_uom_id' required=True string='UoM'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' copy=True help='Service Purchase Order Line' index=True ondelete='cascade' string='Purchase Line'
  • purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=True index=True ondelete='cascade' required=True string='Purchase Request Line'
  • purchase_state Selection
    related='purchase_line_id.state'
  • requested_product_uom_qty Float
    help='Quantity of the purchase request line allocated to thestock move, in the UoM of the Purchase Request Line' string='Requested Quantity'
  • stock_move_id Many2one → stock.move
    comodel_name='stock.move' index=True ondelete='cascade' string='Stock Move'
Public methods (0)

No public methods.

New fields (31)
  • assigned_to Many2one → res.users
    comodel_name='res.users' related='request_id.assigned_to' store=True string='Assigned to'
  • cancelled Boolean
    copy=False default=False readonly=True
  • company_id Many2one → res.company
    comodel_name='res.company' index=True related='request_id.company_id' store=True string='Company'
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' tracking=True
  • date_start Date
    related='request_id.date_start' store=True
  • description Text
    readonly=False related='request_id.description' store=True string='PR Description'
  • estimated_cost Monetary
    currency_field='currency_id' default=0.0 help='Estimated cost of Purchase Request Line, not propagated to PO.'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • move_dest_ids One2many → stock.move
    comodel_name='stock.move' inverse_name='created_purchase_request_line_id' string='Downstream Moves'
  • name Char
    string='Description' tracking=True
  • orderpoint_id Many2one → stock.warehouse.orderpoint
    comodel_name='stock.warehouse.orderpoint' string='Orderpoint'
  • origin Char
    related='request_id.origin' store=True string='Source Document'
  • pending_qty_to_receive Float
    compute='_compute_qty_to_buy' copy=False digits='Product Unit of Measure' store=True string='Pending Qty to Receive'
  • product_id Many2one → product.product
    comodel_name='product.product' domain=[('purchase_ok', '=', True)] string='Product' tracking=True
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity' tracking=True
  • product_uom_category_id Many2one
    related='product_id.uom_id.category_id'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' domain="[('category_id', '=', product_uom_category_id)]" string='UoM' tracking=True
  • purchase_lines Many2many → purchase.order.line
    column1='purchase_request_line_id' column2='purchase_order_line_id' comodel_name='purchase.order.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel' string='Purchase Order Lines'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' inverse_name='purchase_request_line_id' string='Purchase Request Allocation'
  • purchase_state Selection
    compute='_compute_purchase_state' selection=<expr> store=True string='Purchase Status'
  • purchased_qty Float
    compute='_compute_purchased_qty' digits='Product Unit of Measure' string='RFQ/PO Qty'
  • qty_cancelled Float
    compute='_compute_qty_cancelled' digits='Product Unit of Measure' help='Quantity cancelled' readonly=True store=True
  • qty_done Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity completed' readonly=True store=True
  • qty_in_progress Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity in progress.' readonly=True store=True
  • qty_to_buy Boolean
    compute='_compute_qty_to_buy' store=True string='There is some pending qty to buy'
  • request_id Many2one → purchase.request
    auto_join=True comodel_name='purchase.request' index=True ondelete='cascade' readonly=True string='Purchase Request'
  • request_state Selection
    related='request_id.state' store=True string='Request state'
  • requested_by Many2one → res.users
    comodel_name='res.users' related='request_id.requested_by' store=True string='Requested by'
  • specifications Text
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' compute='_compute_supplier_id' compute_sudo=True store=True string='Preferred supplier'
Public methods (6)
  • action_show_details(self)
  • do_cancel(self)
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • unlink(self)
  • write(self, vals)

New fields (4)
  • item_ids One2many → purchase.request.line.make.purchase.order.item
    comodel_name='purchase.request.line.make.purchase.order.item' inverse_name='wiz_id' string='Items'
  • purchase_order_id Many2one → purchase.order
    comodel_name='purchase.order' domain=[('state', '=', 'draft')] string='Purchase Order'
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' context={'res_partner_search_mode': 'supplier'} required=True string='Supplier'
  • sync_data_planned Boolean
    help='When checked, PO lines on the selected purchase order are only reused if the scheduled date matches as well.' string='Match existing PO lines by Scheduled Date'
Public methods (5)
  • check_group(self, request_lines)
    @api.model
  • create_allocation(self, po_line, pr_line, new_qty, alloc_uom)
  • default_get(self, fields)
    @api.model
  • get_items(self, request_line_ids)
    @api.model
  • make_purchase_order(self)

New fields (8)
  • keep_description Boolean
    help='Set true if you want to keep the descriptions provided in the wizard in the new PO.' string='Copy descriptions to new PO'
  • line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' string='Purchase Request Line'
  • name Char
    required=True string='Description'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=False related='line_id.product_id' string='Product'
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity to purchase'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' required=True string='UoM'
  • request_id Many2one → purchase.request
    comodel_name='purchase.request' readonly=False related='line_id.request_id' string='Purchase Request'
  • wiz_id Many2one → purchase.request.line.make.purchase.order
    comodel_name='purchase.request.line.make.purchase.order' ondelete='cascade' readonly=True required=True string='Wizard'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id')

New fields (3)
  • created_purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=False index=True ondelete='set null' readonly=True string='Created Purchase Request Line'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='stock_move_id' string='Purchase Request Allocation'
  • purchase_request_ids One2many → purchase.request
    comodel_name='purchase.request' compute='_compute_purchase_request_ids' string='Purchase Requests'
Public methods (1)
  • copy_data(self, default=None)
    Propagate request allocation on copy. If this move is being split, or if this move is processed and there is a remaining allocation, move the appropriate quantity over to the new move.

New fields (0)

No new fields.

Public methods (1)
  • allocate(self)

New fields (0)

No new fields.

Public methods (2)
  • create_purchase_request(self, procurement_group)
    Create a purchase request containing procurement order product.
  • is_create_purchase_request_allowed(self, procurement)
    Tell if current procurement order should create a purchase request or not. :return: boolean

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/16.0/purchase_request
VERSION
VERSION 2.4.3
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow
COMMITTERS
COMMITTERSStéphane Bidoul, Stefan Rijnhart, Pere Albujer, Víctor Martínez, Thomas Binsfeld, AaronHForgeFlow, Weblate, OCA-git-bot, Benjamin Willig, oca-ci, Saran440, Borruso, Hector Vior, Héctor Vi Or, LauraCForgeFlow, kaynnan, ArnauCForgeFlow, Juan Ignacio Carreras, Celina Devigili, mav-adhoc, Miguel Granda Martínez, youring
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:12:05
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase_stock
    - stock_account
    - stock
    - product
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
    - barcodes_gs1_nomenclature
    - barcodes
    - digest
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - resource
    - account
    - analytic
    - purchase
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
You use this module if you wish to give notification of requirements of
materials and/or external services and keep track of such requirements.

Requests can be created either directly or indirectly. "Directly" means
that someone from the requesting department enters a purchase request
manually.

The person creating the request determines what and how much to order,
and the requested date.

"Indirectly" means that the purchase request initiated by the
application automatically, for example, from procurement orders (MO,
SO).

A purchase request is an instruction to Purchasing to procure a certain
quantity of materials services, so that they are available at a certain
point in time.

A line of a request contains the quantity and requested date of the
material to be supplied or the quantity of the service to be performed.
You can indicate the service specifications if needed.

Once request is approved go to the Purchase Request Lines from the menu
entry 'Purchase Requests', and also from the 'Purchase' menu.

Select the lines that you wish to initiate the RFQ for, then go to
'More' and press 'Create RFQ'.

You can choose to select an existing RFQ or create a new one. In the
later, you have to choose a supplier.

In case that you chose to select an existing RFQ, the application will
search for existing lines matching the request line, and will add the
extra quantity to them, recalculating the minimum order quantity, if it
exists for the supplier of that RFQ.

In case that you create a new RFQ, the request lines will also be
consolidated into as few as possible lines in the RFQ.

Code Analysis

Views touched (21)
XML IDNameModelTypeStatus
product_template_form_view_inherit product.template.form.inherit product.template group Inherits stock.view_template_property_form
purchase_order_form purchase.order.form purchase.order xpath Inherits purchase.purchase_order_form
purchase_order_line_form2 purchase.order.line.form2 purchase.order.line field Inherits purchase.purchase_order_line_form2
purchase_order_line_form2_sub purchase.order.line.form2 purchase.order.line form New
purchase_order_line_search_sub purchase.order.line.search purchase.order.line search New
purchase_order_line_tree purchase.order.line.tree purchase.order.line xpath Inherits purchase.purchase_order_line_tree
purchase_order_line_tree_sub purchase.order.line.tree purchase.order.line tree New
purchase_request_allocation purchase.request.allocation purchase.request.allocation tree New
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchase_request report_purchase_request ir.ui.view qweb New
view_move_form stock.move.form stock.move group Inherits stock.view_move_form
view_picking_form stock.picking.form stock.picking xpath Inherits stock.view_picking_form
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_kanban purchase.request.kanban purchase.request kanban New
view_purchase_request_line_details purchase.request.line.details.form purchase.request.line form New
view_purchase_request_line_make_purchase_order Purchase Request Line Make Purchase Order purchase.request.line.make.purchase.order form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
view_stock_move_operations stock.move.operations.form stock.move field Inherits stock.view_stock_move_operations
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (12)

New fields (1)
  • purchase_request Boolean
    company_dependent=True help='Check this box to generate Purchase Request instead of generating Requests For Quotation from procurement.'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • button_confirm(self)
  • unlink(self)

New fields (2)
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='purchase_line_id' string='Purchase Request Allocation'
  • purchase_request_lines Many2many → purchase.request.line
    column1='purchase_order_line_id' column2='purchase_request_line_id' comodel_name='purchase.request.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel'
Public methods (3)
  • action_open_request_line_tree_view(self)
    :return dict: dictionary value for created view
  • update_service_allocations(self, prev_qty_received)
  • write(self, vals)

New fields (20)
  • assigned_to Many2one → res.users
    comodel_name='res.users' domain=<expr> index=True string='Approver' tracking=True
  • company_id Many2one → res.company
    comodel_name='res.company' default=_company_get required=False tracking=True
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' string='Creation date' tracking=True
  • description Text
  • estimated_cost Monetary
    compute='_compute_estimated_cost' store=True string='Total Estimated Cost'
  • group_id Many2one → procurement.group
    comodel_name='procurement.group' copy=False index=True string='Procurement Group'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • is_name_editable Boolean
    default=<expr>
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    comodel_name='purchase.request.line' copy=True inverse_name='request_id' readonly=True states={'draft': [('readonly', False)]} string='Products to Purchase' tracking=True
  • move_count Integer
    compute='_compute_move_count' readonly=True string='Stock Move count'
  • name Char
    default=<expr> required=True string='Request Reference' tracking=True
  • origin Char
    string='Source Document'
  • picking_type_id Many2one → stock.picking.type
    comodel_name='stock.picking.type' default=_default_picking_type required=True string='Picking Type'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='line_ids.product_id' string='Product'
  • purchase_count Integer
    compute='_compute_purchase_count' readonly=True string='Purchases count'
  • requested_by Many2one → res.users
    comodel_name='res.users' copy=False default=_get_default_requested_by index=True required=True tracking=True
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' tracking=True
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (15)
  • action_view_purchase_order(self)
  • action_view_purchase_request_line(self)
  • action_view_stock_picking(self)
  • button_approved(self)
  • button_done(self)
  • button_draft(self)
  • button_in_progress(self)
  • button_rejected(self)
  • button_to_approve(self)
  • check_auto_reject(self)
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • to_approve_allowed_check(self)
  • unlink(self)
  • write(self, vals)

New fields (10)
  • allocated_product_qty Float
    copy=False help='Quantity of the purchase request line allocated to the stockmove, in the default UoM of the product' string='Allocated Quantity'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True readonly=True related='purchase_request_line_id.request_id.company_id' store=True string='Company'
  • open_product_qty Float
    compute='_compute_open_product_qty' string='Open Quantity'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='purchase_request_line_id.product_id' string='Product'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' readonly=True related='purchase_request_line_id.product_uom_id' required=True string='UoM'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' copy=True help='Service Purchase Order Line' index=True ondelete='cascade' string='Purchase Line'
  • purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=True index=True ondelete='cascade' required=True string='Purchase Request Line'
  • purchase_state Selection
    related='purchase_line_id.state'
  • requested_product_uom_qty Float
    help='Quantity of the purchase request line allocated to thestock move, in the UoM of the Purchase Request Line' string='Requested Quantity'
  • stock_move_id Many2one → stock.move
    comodel_name='stock.move' index=True ondelete='cascade' string='Stock Move'
Public methods (0)

No public methods.

New fields (31)
  • assigned_to Many2one → res.users
    comodel_name='res.users' related='request_id.assigned_to' store=True string='Assigned to'
  • cancelled Boolean
    copy=False default=False readonly=True
  • company_id Many2one → res.company
    comodel_name='res.company' index=True related='request_id.company_id' store=True string='Company'
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' tracking=True
  • date_start Date
    related='request_id.date_start' store=True
  • description Text
    readonly=False related='request_id.description' store=True string='PR Description'
  • estimated_cost Monetary
    currency_field='currency_id' default=0.0 help='Estimated cost of Purchase Request Line, not propagated to PO.'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • move_dest_ids One2many → stock.move
    comodel_name='stock.move' inverse_name='created_purchase_request_line_id' string='Downstream Moves'
  • name Char
    string='Description' tracking=True
  • orderpoint_id Many2one → stock.warehouse.orderpoint
    comodel_name='stock.warehouse.orderpoint' string='Orderpoint'
  • origin Char
    related='request_id.origin' store=True string='Source Document'
  • pending_qty_to_receive Float
    compute='_compute_qty_to_buy' copy=False digits='Product Unit of Measure' store=True string='Pending Qty to Receive'
  • product_id Many2one → product.product
    comodel_name='product.product' domain=[('purchase_ok', '=', True)] string='Product' tracking=True
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity' tracking=True
  • product_uom_category_id Many2one
    related='product_id.uom_id.category_id'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' domain="[('category_id', '=', product_uom_category_id)]" string='UoM' tracking=True
  • purchase_lines Many2many → purchase.order.line
    column1='purchase_request_line_id' column2='purchase_order_line_id' comodel_name='purchase.order.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel' string='Purchase Order Lines'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' inverse_name='purchase_request_line_id' string='Purchase Request Allocation'
  • purchase_state Selection
    compute='_compute_purchase_state' selection=<expr> store=True string='Purchase Status'
  • purchased_qty Float
    compute='_compute_purchased_qty' digits='Product Unit of Measure' string='RFQ/PO Qty'
  • qty_cancelled Float
    compute='_compute_qty_cancelled' digits='Product Unit of Measure' help='Quantity cancelled' readonly=True store=True
  • qty_done Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity completed' readonly=True store=True
  • qty_in_progress Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity in progress.' readonly=True store=True
  • qty_to_buy Boolean
    compute='_compute_qty_to_buy' store=True string='There is some pending qty to buy'
  • request_id Many2one → purchase.request
    auto_join=True comodel_name='purchase.request' index=True ondelete='cascade' readonly=True string='Purchase Request'
  • request_state Selection
    related='request_id.state' store=True string='Request state'
  • requested_by Many2one → res.users
    comodel_name='res.users' related='request_id.requested_by' store=True string='Requested by'
  • specifications Text
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' compute='_compute_supplier_id' compute_sudo=True store=True string='Preferred supplier'
Public methods (6)
  • action_show_details(self)
  • do_cancel(self)
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • unlink(self)
  • write(self, vals)

New fields (4)
  • item_ids One2many → purchase.request.line.make.purchase.order.item
    comodel_name='purchase.request.line.make.purchase.order.item' inverse_name='wiz_id' string='Items'
  • purchase_order_id Many2one → purchase.order
    comodel_name='purchase.order' domain=[('state', '=', 'draft')] string='Purchase Order'
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' context={'res_partner_search_mode': 'supplier'} required=True string='Supplier'
  • sync_data_planned Boolean
    help='When checked, PO lines on the selected purchase order are only reused if the scheduled date matches as well.' string='Match existing PO lines by Scheduled Date'
Public methods (5)
  • check_group(self, request_lines)
    @api.model
  • create_allocation(self, po_line, pr_line, new_qty, alloc_uom)
  • default_get(self, fields)
    @api.model
  • get_items(self, request_line_ids)
    @api.model
  • make_purchase_order(self)

New fields (11)
  • currency_id Many2one → res.currency
    readonly=True related='line_id.currency_id' string='Currency' args: 'res.currency'
  • estimated_cost Monetary
    currency_field='currency_id'
  • keep_description Boolean
    help='Set true if you want to keep the descriptions provided in the wizard in the new PO.' string='Copy descriptions to new PO'
  • keep_estimated_cost Boolean
    help='Set true if you want to keep the estimated cost provided in the wizard in the new PO.' string='Copy estimative cost to new PO'
  • line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' string='Purchase Request Line'
  • name Char
    required=True string='Description'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=False related='line_id.product_id' string='Product'
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity to purchase'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' required=True string='UoM'
  • request_id Many2one → purchase.request
    comodel_name='purchase.request' readonly=False related='line_id.request_id' string='Purchase Request'
  • wiz_id Many2one → purchase.request.line.make.purchase.order
    comodel_name='purchase.request.line.make.purchase.order' ondelete='cascade' readonly=True required=True string='Wizard'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id')

New fields (3)
  • created_purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=False index=True ondelete='set null' readonly=True string='Created Purchase Request Line'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='stock_move_id' string='Purchase Request Allocation'
  • purchase_request_ids One2many → purchase.request
    comodel_name='purchase.request' compute='_compute_purchase_request_ids' string='Purchase Requests'
Public methods (1)
  • copy_data(self, default=None)
    Propagate request allocation on copy. If this move is being split, or if this move is processed and there is a remaining allocation, move the appropriate quantity over to the new move.

New fields (0)

No new fields.

Public methods (1)
  • allocate(self)

New fields (0)

No new fields.

Public methods (2)
  • create_purchase_request(self, procurement_group)
    Create a purchase request containing procurement order product.
  • is_create_purchase_request_allowed(self, procurement)
    Tell if current procurement order should create a purchase request or not. :return: boolean

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/15.0/purchase_request
VERSION
VERSION 1.2.3
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow
COMMITTERS
COMMITTERSPere Albujer, Florent Xicluna, OCA Transbot, Pablo Paez, nicolas, AaronHForgeFlow, Weblate, OCA-git-bot, Jesús Alan Ramos Rodríguez, oca-ci, Héctor Villarreal Ortega, Saran440, Virginia Bonservizi, Nikul-OSI
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:46:41
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase
    - account
    - base_setup
    - base
    - web
    - product
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - purchase_stock
    - stock_account
    - stock
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (20)
XML IDNameModelTypeStatus
product_template_form_view_inherit product.template.form.inherit product.template group Inherits stock.view_template_property_form
purchase_order_form purchase.order.form purchase.order xpath Inherits purchase.purchase_order_form
purchase_order_line_form2 purchase.order.line.form2 purchase.order.line field Inherits purchase.purchase_order_line_form2
purchase_order_line_form2_sub purchase.order.line.form2 purchase.order.line form New
purchase_order_line_search_sub purchase.order.line.search purchase.order.line search New
purchase_order_line_tree purchase.order.line.tree purchase.order.line xpath Inherits purchase.purchase_order_line_tree
purchase_order_line_tree_sub purchase.order.line.tree purchase.order.line tree New
purchase_request_allocation purchase.request.allocation purchase.request.allocation tree New
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchase_request report_purchase_request ir.ui.view qweb New
view_move_form stock.move.form stock.move group Inherits stock.view_move_form
view_picking_form stock.picking.form stock.picking xpath Inherits stock.view_picking_form
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_line_details purchase.request.line.details.form purchase.request.line form New
view_purchase_request_line_make_purchase_order Purchase Request Line Make Purchase Order purchase.request.line.make.purchase.order form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
view_stock_move_operations stock.move.operations.form stock.move field Inherits stock.view_stock_move_operations
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (12)

New fields (1)
  • purchase_request Boolean
    company_dependent=True help='Check this box to generate Purchase Request instead of generating Requests For Quotation from procurement.'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • button_confirm(self)
  • unlink(self)

New fields (2)
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='purchase_line_id' string='Purchase Request Allocation'
  • purchase_request_lines Many2many → purchase.request.line
    column1='purchase_order_line_id' column2='purchase_request_line_id' comodel_name='purchase.request.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel'
Public methods (3)
  • action_open_request_line_tree_view(self)
    :return dict: dictionary value for created view
  • update_service_allocations(self, prev_qty_received)
  • write(self, vals)

New fields (20)
  • assigned_to Many2one → res.users
    comodel_name='res.users' domain=<expr> index=True string='Approver' tracking=True
  • company_id Many2one → res.company
    comodel_name='res.company' default=_company_get required=False tracking=True
  • currency_id Many2one → res.currency
    comodel_name='res.currency' default=<expr> required=True
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' string='Creation date' tracking=True
  • description Text
  • estimated_cost Monetary
    compute='_compute_estimated_cost' store=True string='Total Estimated Cost'
  • group_id Many2one → procurement.group
    comodel_name='procurement.group' copy=False index=True string='Procurement Group'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • is_name_editable Boolean
    default=<expr>
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    comodel_name='purchase.request.line' copy=True inverse_name='request_id' readonly=True states={'draft': [('readonly', False)]} string='Products to Purchase' tracking=True
  • move_count Integer
    compute='_compute_move_count' readonly=True string='Stock Move count'
  • name Char
    default=<expr> required=True string='Request Reference' tracking=True
  • origin Char
    string='Source Document'
  • picking_type_id Many2one → stock.picking.type
    comodel_name='stock.picking.type' default=_default_picking_type required=True string='Picking Type'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='line_ids.product_id' string='Product'
  • purchase_count Integer
    compute='_compute_purchase_count' readonly=True string='Purchases count'
  • requested_by Many2one → res.users
    comodel_name='res.users' copy=False default=_get_default_requested_by index=True required=True tracking=True
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' tracking=True
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (14)
  • action_view_purchase_order(self)
  • action_view_purchase_request_line(self)
  • action_view_stock_picking(self)
  • button_approved(self)
  • button_done(self)
  • button_draft(self)
  • button_rejected(self)
  • button_to_approve(self)
  • check_auto_reject(self)
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
  • create(self, vals)
    @api.model
  • to_approve_allowed_check(self)
  • unlink(self)
  • write(self, vals)

New fields (10)
  • allocated_product_qty Float
    copy=False help='Quantity of the purchase request line allocated to the stockmove, in the default UoM of the product' string='Allocated Quantity'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True readonly=True related='purchase_request_line_id.request_id.company_id' store=True string='Company'
  • open_product_qty Float
    compute='_compute_open_product_qty' string='Open Quantity'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='purchase_request_line_id.product_id' string='Product'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' readonly=True related='purchase_request_line_id.product_uom_id' required=True string='UoM'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' copy=True help='Service Purchase Order Line' index=True ondelete='cascade' string='Purchase Line'
  • purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=True index=True ondelete='cascade' required=True string='Purchase Request Line'
  • purchase_state Selection
    related='purchase_line_id.state'
  • requested_product_uom_qty Float
    help='Quantity of the purchase request line allocated to thestock move, in the UoM of the Purchase Request Line' string='Requested Quantity'
  • stock_move_id Many2one → stock.move
    comodel_name='stock.move' index=True ondelete='cascade' string='Stock Move'
Public methods (0)

No public methods.

New fields (33)
  • analytic_account_id Many2one → account.analytic.account
    comodel_name='account.analytic.account' string='Analytic Account' tracking=True
  • analytic_tag_ids Many2many → account.analytic.tag
    string='Analytic Tags' tracking=True args: 'account.analytic.tag'
  • assigned_to Many2one → res.users
    comodel_name='res.users' related='request_id.assigned_to' store=True string='Assigned to'
  • cancelled Boolean
    copy=False default=False readonly=True
  • company_id Many2one → res.company
    comodel_name='res.company' related='request_id.company_id' store=True string='Company'
  • currency_id Many2one
    related='request_id.currency_id'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' tracking=True
  • date_start Date
    related='request_id.date_start' store=True
  • description Text
    readonly=False related='request_id.description' store=True string='PR Description'
  • estimated_cost Monetary
    currency_field='currency_id' default=0.0 help='Estimated cost of Purchase Request Line, not propagated to PO.'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True
  • move_dest_ids One2many → stock.move
    comodel_name='stock.move' inverse_name='created_purchase_request_line_id' string='Downstream Moves'
  • name Char
    string='Description' tracking=True
  • orderpoint_id Many2one → stock.warehouse.orderpoint
    comodel_name='stock.warehouse.orderpoint' string='Orderpoint'
  • origin Char
    related='request_id.origin' store=True string='Source Document'
  • pending_qty_to_receive Float
    compute='_compute_qty_to_buy' copy=False digits='Product Unit of Measure' store=True string='Pending Qty to Receive'
  • product_id Many2one → product.product
    comodel_name='product.product' domain=[('purchase_ok', '=', True)] string='Product' tracking=True
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity' tracking=True
  • product_uom_category_id Many2one
    related='product_id.uom_id.category_id'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' domain="[('category_id', '=', product_uom_category_id)]" string='UoM' tracking=True
  • purchase_lines Many2many → purchase.order.line
    column1='purchase_request_line_id' column2='purchase_order_line_id' comodel_name='purchase.order.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel' string='Purchase Order Lines'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' inverse_name='purchase_request_line_id' string='Purchase Request Allocation'
  • purchase_state Selection
    compute='_compute_purchase_state' selection=<expr> store=True string='Purchase Status'
  • purchased_qty Float
    compute='_compute_purchased_qty' digits='Product Unit of Measure' string='RFQ/PO Qty'
  • qty_cancelled Float
    compute='_compute_qty_cancelled' digits='Product Unit of Measure' help='Quantity cancelled' readonly=True store=True
  • qty_done Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity completed' readonly=True store=True
  • qty_in_progress Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity in progress.' readonly=True store=True
  • qty_to_buy Boolean
    compute='_compute_qty_to_buy' store=True string='There is some pending qty to buy'
  • request_id Many2one → purchase.request
    auto_join=True comodel_name='purchase.request' index=True ondelete='cascade' readonly=True string='Purchase Request'
  • request_state Selection
    related='request_id.state' store=True string='Request state'
  • requested_by Many2one → res.users
    comodel_name='res.users' related='request_id.requested_by' store=True string='Requested by'
  • specifications Text
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' compute='_compute_supplier_id' compute_sudo=True store=True string='Preferred supplier'
Public methods (6)
  • action_show_details(self)
  • do_cancel(self)
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • unlink(self)
  • write(self, vals)

New fields (4)
  • item_ids One2many → purchase.request.line.make.purchase.order.item
    comodel_name='purchase.request.line.make.purchase.order.item' inverse_name='wiz_id' string='Items'
  • purchase_order_id Many2one → purchase.order
    comodel_name='purchase.order' domain=[('state', '=', 'draft')] string='Purchase Order'
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' context={'res_partner_search_mode': 'supplier'} required=True string='Supplier'
  • sync_data_planned Boolean
    string='Merge on PO lines with equal Scheduled Date'
Public methods (5)
  • check_group(self, request_lines)
    @api.model
  • create_allocation(self, po_line, pr_line, new_qty, alloc_uom)
  • default_get(self, fields)
    @api.model
  • get_items(self, request_line_ids)
    @api.model
  • make_purchase_order(self)

New fields (8)
  • keep_description Boolean
    help='Set true if you want to keep the descriptions provided in the wizard in the new PO.' string='Copy descriptions to new PO'
  • line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' string='Purchase Request Line'
  • name Char
    required=True string='Description'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=False related='line_id.product_id' string='Product'
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity to purchase'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' required=True string='UoM'
  • request_id Many2one → purchase.request
    comodel_name='purchase.request' readonly=False related='line_id.request_id' string='Purchase Request'
  • wiz_id Many2one → purchase.request.line.make.purchase.order
    comodel_name='purchase.request.line.make.purchase.order' ondelete='cascade' readonly=True required=True string='Wizard'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id')

New fields (3)
  • created_purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=False index=True ondelete='set null' readonly=True string='Created Purchase Request Line'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='stock_move_id' string='Purchase Request Allocation'
  • purchase_request_ids One2many → purchase.request
    comodel_name='purchase.request' compute='_compute_purchase_request_ids' string='Purchase Requests'
Public methods (1)
  • copy_data(self, default=None)

New fields (0)

No new fields.

Public methods (1)
  • allocate(self)

New fields (0)

No new fields.

Public methods (2)
  • create_purchase_request(self, procurement_group)
    Create a purchase request containing procurement order product.
  • is_create_purchase_request_allowed(self, procurement)
    Tell if current procurement order should create a purchase request or not. :return: boolean

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/14.0/purchase_request
VERSION
VERSION 2.2.1
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow
COMMITTERS
COMMITTERSStefan Rijnhart, GitHub, Daniel Reis, Akim Juillerat, Pere Albujer, OCA Transbot, Sébastien Alix, Thomas Binsfeld, oca-travis, Weblate, OCA-git-bot, Simone Orsi, Iryna Vyshnevska, Anna Janiszewska, oca-ci, Kitti U, newtratip, Héctor Villarreal Ortega, Saran440, Alessandro Uffreduzzi, Matthieu Méquignon, Virginia Bonservizi, Kaynnan Lemes, Frosina, Elizabeth M Smith
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:41:09
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase
    - account
    - base_setup
    - base
    - web
    - product
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - purchase_stock
    - stock_account
    - stock
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (20)
XML IDNameModelTypeStatus
product_template_form_view_inherit product.template.form.inherit product.template group Inherits stock.view_template_property_form
purchase_order_form purchase.order.form purchase.order xpath Inherits purchase.purchase_order_form
purchase_order_line_form2 purchase.order.line.form2 purchase.order.line field Inherits purchase.purchase_order_line_form2
purchase_order_line_form2_sub purchase.order.line.form2 purchase.order.line form New
purchase_order_line_search_sub purchase.order.line.search purchase.order.line search New
purchase_order_line_tree purchase.order.line.tree purchase.order.line xpath Inherits purchase.purchase_order_line_tree
purchase_order_line_tree_sub purchase.order.line.tree purchase.order.line tree New
purchase_request_allocation purchase.request.allocation purchase.request.allocation tree New
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchase_request report_purchase_request ir.ui.view qweb New
res_config_settings_view_form res.config.settings div Inherits account.res_config_settings_view_form
view_move_form stock.move.form stock.move group Inherits stock.view_move_form
view_picking_form stock.picking.form stock.picking xpath Inherits stock.view_picking_form
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_line_make_purchase_order Purchase Request Line Make Purchase Order purchase.request.line.make.purchase.order form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
view_stock_move_operations stock.move.operations.form stock.move field Inherits stock.view_stock_move_operations
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (15)

New fields (1)
  • purchase_request Boolean
    company_dependent=True help='Check this box to generate Purchase Request instead of generating Requests For Quotation from procurement.'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • button_confirm(self)
  • unlink(self)

New fields (2)
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='purchase_line_id' string='Purchase Request Allocation'
  • purchase_request_lines Many2many → purchase.request.line
    column1='purchase_order_line_id' column2='purchase_request_line_id' comodel_name='purchase.request.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel' string='Purchase Request Lines'
Public methods (3)
  • action_open_request_line_tree_view(self)
    :return dict: dictionary value for created view
  • update_service_allocations(self, prev_qty_received)
  • write(self, vals)

New fields (20)
  • assigned_to Many2one → res.users
    comodel_name='res.users' domain=<expr> index=True string='Approver' tracking=True
  • company_id Many2one → res.company
    comodel_name='res.company' default=_company_get required=True string='Company' tracking=True
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' string='Creation date' tracking=True
  • description Text
    string='Description'
  • estimated_cost Monetary
    compute='_compute_estimated_cost' store=True string='Total Estimated Cost'
  • group_id Many2one → procurement.group
    comodel_name='procurement.group' copy=False index=True string='Procurement Group'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • is_name_editable Boolean
    default=<expr>
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    comodel_name='purchase.request.line' copy=True inverse_name='request_id' readonly=False string='Products to Purchase' tracking=True
  • move_count Integer
    compute='_compute_move_count' readonly=True string='Stock Move count'
  • name Char
    default=<expr> required=True string='Request Reference' tracking=True
  • origin Char
    string='Source Document'
  • picking_type_id Many2one → stock.picking.type
    comodel_name='stock.picking.type' default=_default_picking_type required=True string='Picking Type'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='line_ids.product_id' string='Product'
  • purchase_count Integer
    compute='_compute_purchase_count' readonly=True string='Purchases count'
  • requested_by Many2one → res.users
    comodel_name='res.users' copy=False default=_get_default_requested_by index=True required=True string='Requested by' tracking=True
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' tracking=True
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (14)
  • action_view_purchase_order(self)
  • action_view_purchase_request_line(self)
  • action_view_stock_move(self)
  • button_approved(self)
  • button_done(self)
  • button_draft(self)
  • button_rejected(self)
  • button_to_approve(self)
  • check_auto_reject(self)
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
  • create(self, vals)
    @api.model
  • to_approve_allowed_check(self)
  • unlink(self)
  • write(self, vals)

New fields (10)
  • allocated_product_qty Float
    copy=False help='Quantity of the purchase request line allocated to the stockmove, in the default UoM of the product' string='Allocated Quantity'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True readonly=True related='purchase_request_line_id.request_id.company_id' store=True string='Company'
  • open_product_qty Float
    compute='_compute_open_product_qty' string='Open Quantity'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='purchase_request_line_id.product_id' string='Product'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' readonly=True related='purchase_request_line_id.product_uom_id' required=True string='UoM'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' copy=True help='Service Purchase Order Line' index=True ondelete='cascade' string='Purchase Line'
  • purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=True index=True ondelete='cascade' required=True string='Purchase Request Line'
  • purchase_state Selection
    related='purchase_line_id.state'
  • requested_product_uom_qty Float
    help='Quantity of the purchase request line allocated to thestock move, in the UoM of the Purchase Request Line' string='Requested Quantity'
  • stock_move_id Many2one → stock.move
    comodel_name='stock.move' index=True ondelete='cascade' string='Stock Move'
Public methods (0)

No public methods.

New fields (33)
  • analytic_account_id Many2one → account.analytic.account
    comodel_name='account.analytic.account' string='Analytic Account' tracking=True
  • analytic_tag_ids Many2many → account.analytic.tag
    string='Analytic Tags' tracking=True args: 'account.analytic.tag'
  • assigned_to Many2one → res.users
    comodel_name='res.users' related='request_id.assigned_to' store=True string='Assigned to'
  • cancelled Boolean
    copy=False default=False readonly=True string='Cancelled'
  • company_id Many2one → res.company
    comodel_name='res.company' related='request_id.company_id' store=True string='Company'
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' tracking=True
  • date_start Date
    related='request_id.date_start' store=True
  • description Text
    readonly=False related='request_id.description' store=True string='PR Description'
  • estimated_cost Monetary
    currency_field='currency_id' default=0.0 help='Estimated cost of Purchase Request Line, not propagated to PO.' string='Estimated Cost'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • move_dest_ids One2many → stock.move
    comodel_name='stock.move' inverse_name='created_purchase_request_line_id' string='Downstream Moves'
  • name Char
    string='Description' tracking=True
  • orderpoint_id Many2one → stock.warehouse.orderpoint
    comodel_name='stock.warehouse.orderpoint' string='Orderpoint'
  • origin Char
    related='request_id.origin' store=True string='Source Document'
  • pending_qty_to_receive Float
    compute='_compute_qty_to_buy' copy=False digits='Product Unit of Measure' store=True string='Pending Qty to Receive'
  • product_id Many2one → product.product
    comodel_name='product.product' domain=[('purchase_ok', '=', True)] string='Product' tracking=True
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity' tracking=True
  • product_uom_category_id Many2one
    related='product_id.uom_id.category_id'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' domain="[('category_id', '=', product_uom_category_id)]" string='UoM' tracking=True
  • purchase_lines Many2many → purchase.order.line
    column1='purchase_request_line_id' column2='purchase_order_line_id' comodel_name='purchase.order.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel' string='Purchase Order Lines'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' inverse_name='purchase_request_line_id' string='Purchase Request Allocation'
  • purchase_state Selection
    compute='_compute_purchase_state' selection=<expr> store=True string='Purchase Status'
  • purchased_qty Float
    compute='_compute_purchased_qty' digits='Product Unit of Measure' string='RFQ/PO Qty'
  • qty_cancelled Float
    compute='_compute_qty_cancelled' digits='Product Unit of Measure' help='Quantity cancelled' readonly=True store=True string='Qty Cancelled'
  • qty_done Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity completed' readonly=True store=True string='Qty Done'
  • qty_in_progress Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity in progress.' readonly=True store=True string='Qty In Progress'
  • qty_to_buy Boolean
    compute='_compute_qty_to_buy' store=True string='There is some pending qty to buy'
  • request_id Many2one → purchase.request
    auto_join=True comodel_name='purchase.request' index=True ondelete='cascade' readonly=True string='Purchase Request'
  • request_state Selection
    related='request_id.state' store=True string='Request state'
  • requested_by Many2one → res.users
    comodel_name='res.users' related='request_id.requested_by' store=True string='Requested by'
  • specifications Text
    string='Specifications'
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' compute='_compute_supplier_id' compute_sudo=True store=True string='Preferred supplier'
Public methods (5)
  • do_cancel(self)
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • unlink(self)
  • write(self, vals)

New fields (4)
  • item_ids One2many → purchase.request.line.make.purchase.order.item
    comodel_name='purchase.request.line.make.purchase.order.item' inverse_name='wiz_id' string='Items'
  • purchase_order_id Many2one → purchase.order
    comodel_name='purchase.order' domain=[('state', '=', 'draft')] string='Purchase Order'
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' required=True string='Supplier'
  • sync_data_planned Boolean
    string='Merge on PO lines with equal Scheduled Date'
Public methods (5)
  • check_group(self, request_lines)
    @api.model
  • create_allocation(self, po_line, pr_line, new_qty, alloc_uom)
  • default_get(self, fields)
    @api.model
  • get_items(self, request_line_ids)
    @api.model
  • make_purchase_order(self)

New fields (11)
  • currency_id Many2one → res.currency
    readonly=True related='line_id.currency_id' string='Currency' args: 'res.currency'
  • estimated_cost Monetary
    currency_field='currency_id' string='Estimated Cost'
  • keep_description Boolean
    help='Set true if you want to keep the descriptions provided in the wizard in the new PO.' string='Copy descriptions to new PO'
  • keep_estimated_cost Boolean
    help='Set true if you want to keep the estimated cost provided in the wizard in the new PO.' string='Copy estimative cost to new PO'
  • line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' string='Purchase Request Line'
  • name Char
    required=True string='Description'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=False related='line_id.product_id' string='Product'
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity to purchase'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' required=True string='UoM'
  • request_id Many2one → purchase.request
    comodel_name='purchase.request' readonly=False related='line_id.request_id' string='Purchase Request'
  • wiz_id Many2one → purchase.request.line.make.purchase.order
    comodel_name='purchase.request.line.make.purchase.order' ondelete='cascade' readonly=True required=True string='Wizard'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id')

New fields (1)
  • notify_request_allocations Boolean
    default=True string='Send emails on confirmaion'
Public methods (0)

No public methods.

New fields (1)
  • notify_request_allocations Boolean
    readonly=False related='company_id.notify_request_allocations' string='Send emails with request confirmaion'
Public methods (0)

No public methods.

New fields (3)
  • created_purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=False index=True ondelete='set null' readonly=True string='Created Purchase Request Line'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='stock_move_id' string='Purchase Request Allocation'
  • purchase_request_ids One2many → purchase.request
    comodel_name='purchase.request' compute='_compute_purchase_request_ids' string='Purchase Requests'
Public methods (1)
  • copy_data(self, default=None)

New fields (0)

No new fields.

Public methods (1)
  • allocate(self)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • create_purchase_request(self, procurement_group)
    Create a purchase request containing procurement order product.
  • is_create_purchase_request_allowed(self, procurement)
    Tell if current procurement order should create a purchase request or not. :return: boolean

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/13.0/purchase_request
VERSION
VERSION 4.3.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), ForgeFlow
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), ForgeFlow
COMMITTERS
COMMITTERSHolger Brunn, mreficent, Lois Rilo, Gabriela Mogollón, Swapnesh Shah, OCA Transbot, Thomas Binsfeld, João Marques, oca-travis, Weblate, OCA-git-bot, oca-ci, hveficent, Héctor Villarreal Ortega, kongrattapong, Virginia Bonservizi, hda
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:34:18
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase
    - account
    - base_setup
    - base
    - web
    - product
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - purchase_stock
    - stock_account
    - stock
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (19)
XML IDNameModelTypeStatus
product_template_form_view_inherit product.template.form.inherit product.template field Inherits stock.view_template_property_form
purchase_order_form purchase.order.form purchase.order xpath Inherits purchase.purchase_order_form
purchase_order_line_form2 purchase.order.line.form2 purchase.order.line field Inherits purchase.purchase_order_line_form2
purchase_order_line_form2_sub purchase.order.line.form2 purchase.order.line form New
purchase_order_line_search_sub purchase.order.line.search purchase.order.line search New
purchase_order_line_tree purchase.order.line.tree purchase.order.line xpath Inherits purchase.purchase_order_line_tree
purchase_order_line_tree_sub purchase.order.line.tree purchase.order.line tree New
purchase_request_allocation purchase.request.allocation purchase.request.allocation tree New
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchase_request report_purchase_request ir.ui.view qweb New
view_move_form stock.move.form stock.move group Inherits stock.view_move_form
view_picking_form stock.picking.form stock.picking xpath Inherits stock.view_picking_form
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_line_make_purchase_order Purchase Request Line Make Purchase Order purchase.request.line.make.purchase.order form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
view_stock_move_operations stock.move.operations.form stock.move field Inherits stock.view_stock_move_operations
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (13)

New fields (1)
  • purchase_request Boolean
    company_dependent=True help='Check this box to generate Purchase Request instead of generating Requests For Quotation from procurement.'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • button_confirm(self)
  • unlink(self)

New fields (2)
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='purchase_line_id' string='Purchase Request Allocation'
  • purchase_request_lines Many2many → purchase.request.line
    column1='purchase_order_line_id' column2='purchase_request_line_id' comodel_name='purchase.request.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel' string='Purchase Request Lines'
Public methods (3)
  • action_openRequestLineTreeView(self)
    :return dict: dictionary value for created view
  • update_service_allocations(self, prev_qty_received)
  • write(self, vals)

New fields (17)
  • assigned_to Many2one → res.users
    comodel_name='res.users' domain=<expr> index=True string='Approver' track_visibility='onchange'
  • company_id Many2one → res.company
    comodel_name='res.company' default=_company_get required=True string='Company' track_visibility='onchange'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' string='Creation date' track_visibility='onchange'
  • description Text
    string='Description'
  • group_id Many2one → procurement.group
    comodel_name='procurement.group' copy=False index=True string='Procurement Group'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    comodel_name='purchase.request.line' copy=True inverse_name='request_id' readonly=False string='Products to Purchase' track_visibility='onchange'
  • move_count Integer
    compute='_compute_move_count' readonly=True string='Stock Move count'
  • name Char
    default=_get_default_name required=True string='Request Reference' track_visibility='onchange'
  • origin Char
    string='Source Document'
  • picking_type_id Many2one → stock.picking.type
    comodel_name='stock.picking.type' default=_default_picking_type required=True string='Picking Type'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='line_ids.product_id' string='Product'
  • purchase_count Integer
    compute='_compute_purchase_count' readonly=True string='Purchases count'
  • requested_by Many2one → res.users
    comodel_name='res.users' copy=False default=_get_default_requested_by index=True required=True string='Requested by' track_visibility='onchange'
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' track_visibility='onchange'
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (14)
  • action_view_purchase_order(self)
  • action_view_purchase_request_line(self)
  • action_view_stock_move(self)
  • button_approved(self)
  • button_done(self)
  • button_draft(self)
  • button_rejected(self)
  • button_to_approve(self)
  • check_auto_reject(self)
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
  • create(self, vals)
    @api.model
  • to_approve_allowed_check(self)
  • unlink(self)
  • write(self, vals)

New fields (10)
  • allocated_product_qty Float
    copy=False help='Quantity of the purchase request line allocated to the stockmove, in the default UoM of the product' string='Allocated Quantity'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True readonly=True related='purchase_request_line_id.request_id.company_id' store=True string='Company'
  • open_product_qty Float
    compute='_compute_open_product_qty' string='Open Quantity'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='purchase_request_line_id.product_id' string='Product'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' readonly=True related='purchase_request_line_id.product_uom_id' required=True string='UoM'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' copy=True help='Service Purchase Order Line' index=True ondelete='cascade' string='Purchase Line'
  • purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=True index=True ondelete='cascade' required=True string='Purchase Request Line'
  • purchase_state Selection
    related='purchase_line_id.state'
  • requested_product_uom_qty Float
    help='Quantity of the purchase request line allocated to thestock move, in the UoM of the Purchase Request Line' string='Requested Quantity'
  • stock_move_id Many2one → stock.move
    comodel_name='stock.move' index=True ondelete='cascade' string='Stock Move'
Public methods (0)

No public methods.

New fields (33)
  • analytic_account_id Many2one → account.analytic.account
    comodel_name='account.analytic.account' string='Analytic Account' track_visibility='onchange'
  • analytic_tag_ids Many2many → account.analytic.tag
    string='Analytic Tags' track_visibility='onchange' args: 'account.analytic.tag'
  • assigned_to Many2one → res.users
    comodel_name='res.users' related='request_id.assigned_to' store=True string='Assigned to'
  • cancelled Boolean
    copy=False default=False readonly=True string='Cancelled'
  • company_id Many2one → res.company
    comodel_name='res.company' related='request_id.company_id' store=True string='Company'
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' track_visibility='onchange'
  • date_start Date
    related='request_id.date_start' store=True
  • description Text
    readonly=False related='request_id.description' store=True string='PR Description'
  • estimated_cost Monetary
    currency_field='currency_id' default=0.0 help='Estimated cost of Purchase Request Line, not propagated to PO.' string='Estimated Cost'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • move_dest_ids One2many → stock.move
    comodel_name='stock.move' inverse_name='created_purchase_request_line_id' string='Downstream Moves'
  • name Char
    string='Description' track_visibility='onchange'
  • orderpoint_id Many2one → stock.warehouse.orderpoint
    comodel_name='stock.warehouse.orderpoint' string='Orderpoint'
  • origin Char
    related='request_id.origin' store=True string='Source Document'
  • pending_qty_to_receive Float
    compute='_compute_qty_to_buy' copy=False digits='Product Unit of Measure' store=True string='Pending Qty to Receive'
  • product_id Many2one → product.product
    comodel_name='product.product' domain=[('purchase_ok', '=', True)] string='Product' track_visibility='onchange'
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity' track_visibility='onchange'
  • product_uom_category_id Many2one
    related='product_id.uom_id.category_id'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' domain="[('category_id', '=', product_uom_category_id)]" string='Product Unit of Measure' track_visibility='onchange'
  • purchase_lines Many2many → purchase.order.line
    column1='purchase_request_line_id' column2='purchase_order_line_id' comodel_name='purchase.order.line' copy=False readonly=True relation='purchase_request_purchase_order_line_rel' string='Purchase Order Lines'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' inverse_name='purchase_request_line_id' string='Purchase Request Allocation'
  • purchase_state Selection
    compute='_compute_purchase_state' selection=<expr> store=True string='Purchase Status'
  • purchased_qty Float
    compute='_compute_purchased_qty' digits='Product Unit of Measure' string='Quantity in RFQ or PO'
  • qty_cancelled Float
    compute='_compute_qty_cancelled' digits='Product Unit of Measure' help='Quantity cancelled' readonly=True store=True string='Qty Cancelled'
  • qty_done Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity completed' readonly=True store=True string='Qty Done'
  • qty_in_progress Float
    compute='_compute_qty' digits='Product Unit of Measure' help='Quantity in progress.' readonly=True store=True string='Qty In Progress'
  • qty_to_buy Boolean
    compute='_compute_qty_to_buy' store=True string='There is some pending qty to buy'
  • request_id Many2one → purchase.request
    auto_join=True comodel_name='purchase.request' index=True ondelete='cascade' readonly=True string='Purchase Request'
  • request_state Selection
    related='request_id.state' selection=_STATES store=True string='Request state'
  • requested_by Many2one → res.users
    comodel_name='res.users' related='request_id.requested_by' store=True string='Requested by'
  • specifications Text
    string='Specifications'
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' compute='_compute_supplier_id' compute_sudo=True store=True string='Preferred supplier'
Public methods (5)
  • do_cancel(self)
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • unlink(self)
  • write(self, vals)

New fields (4)
  • item_ids One2many → purchase.request.line.make.purchase.order.item
    comodel_name='purchase.request.line.make.purchase.order.item' inverse_name='wiz_id' string='Items'
  • purchase_order_id Many2one → purchase.order
    comodel_name='purchase.order' domain=[('state', '=', 'draft')] string='Purchase Order'
  • supplier_id Many2one → res.partner
    comodel_name='res.partner' context={'res_partner_search_mode': 'supplier', 'default_is_company': True} domain=[('is_company', '=', True)] required=True string='Supplier'
  • sync_data_planned Boolean
    string='Merge on PO lines with equal Scheduled Date'
Public methods (5)
  • check_group(self, request_lines)
    @api.model
  • create_allocation(self, po_line, pr_line, new_qty, alloc_uom)
  • default_get(self, fields)
    @api.model
  • get_items(self, request_line_ids)
    @api.model
  • make_purchase_order(self)

New fields (8)
  • keep_description Boolean
    help='Set true if you want to keep the descriptions provided in the wizard in the new PO.' string='Copy descriptions to new PO'
  • line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' string='Purchase Request Line'
  • name Char
    required=True string='Description'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=False related='line_id.product_id' string='Product'
  • product_qty Float
    digits='Product Unit of Measure' string='Quantity to purchase'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' required=True string='UoM'
  • request_id Many2one → purchase.request
    comodel_name='purchase.request' readonly=False related='line_id.request_id' string='Purchase Request'
  • wiz_id Many2one → purchase.request.line.make.purchase.order
    comodel_name='purchase.request.line.make.purchase.order' ondelete='cascade' readonly=True required=True string='Wizard'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id')

New fields (3)
  • created_purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=False index=True ondelete='set null' readonly=True string='Created Purchase Request Line'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='stock_move_id' string='Purchase Request Allocation'
  • purchase_request_ids One2many → purchase.request
    comodel_name='purchase.request' compute='_compute_purchase_request_ids' string='Purchase Requests'
Public methods (1)
  • copy_data(self, default=None)

New fields (0)

No new fields.

Public methods (1)
  • allocate(self)

New fields (0)

No new fields.

Public methods (1)
  • action_done(self)

New fields (0)

No new fields.

Public methods (2)
  • create_purchase_request(self, procurement_group)
    Create a purchase request containing procurement order product.
  • is_create_purchase_request_allowed(self, procurement)
    Tell if current procurement order should create a purchase request or not. :return: boolean

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/12.0/purchase_request
VERSION
VERSION 5.4.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Eficent
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Eficent
COMMITTERS
COMMITTERSHolger Brunn, Sylvain LE GAL, GitHub, mreficent, Moisés López, Andrea, Enric Tobella, Andrii Skrypka, Swapnesh Shah, OCA Transbot, Miquel Raïch, João Marques, ahenriquez, oca-travis, Weblate, OCA-git-bot, oca-ci, hveficent, Marcel Savegnago, Alessandro Fiorino
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:29:23
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase
    - account
    - base_setup
    - base
    - web
    - product
    - decimal_precision
    - mail
    - bus
    - web_tour
    - uom
    - analytic
    - portal
    - http_routing
    - digest
    - purchase_stock
    - stock_account
    - stock
    - barcodes
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (19)
XML IDNameModelTypeStatus
product_template_form_view_inherit product.template.form.inherit product.template field Inherits stock.view_template_property_form
purchase_order_form purchase.order.form purchase.order xpath Inherits purchase.purchase_order_form
purchase_order_line_form2 purchase.order.line.form2 purchase.order.line field Inherits purchase.purchase_order_line_form2
purchase_order_line_form2_sub purchase.order.line.form2 purchase.order.line form New
purchase_order_line_search_sub purchase.order.line.search purchase.order.line search New
purchase_order_line_tree purchase.order.line.tree purchase.order.line xpath Inherits purchase.purchase_order_line_tree
purchase_order_line_tree_sub purchase.order.line.tree purchase.order.line tree New
purchase_request_allocation purchase.request.allocation purchase.request.allocation tree New
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchase_request report_purchase_request ir.ui.view qweb New
view_move_form stock.move.form stock.move group Inherits stock.view_move_form
view_move_picking_form stock.move.form stock.move group Inherits stock.view_move_picking_form
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_line_make_purchase_order Purchase Request Line Make Purchase Order purchase.request.line.make.purchase.order form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
view_stock_move_operations stock.move.operations.form stock.move field Inherits stock.view_stock_move_operations
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (13)

New fields (1)
  • purchase_request Boolean
    company_dependent=True help='Check this box to generate Purchase Request instead of generating Requests For Quotation from procurement.'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • button_confirm(self)
    @api.multi
  • unlink(self)
    @api.multi

New fields (2)
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='purchase_line_id' string='Purchase Request Allocation'
  • purchase_request_lines Many2many → purchase.request.line
    copy=False readonly=True args: 'purchase.request.line', 'purchase_request_purchase_order_line_rel', 'purchase_order_line_id', 'purchase_request_line_id', 'Purchase Request Lines'
Public methods (3)
  • action_openRequestLineTreeView(self)
    @api.multi
    :return dict: dictionary value for created view
  • update_service_allocations(self, prev_qty_received)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (17)
  • assigned_to Many2one → res.users
    domain=<expr> track_visibility='onchange' args: 'res.users', 'Approver'
  • company_id Many2one → res.company
    default=_company_get required=True track_visibility='onchange' args: 'res.company', 'Company'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' track_visibility='onchange' args: 'Creation date'
  • description Text
    args: 'Description'
  • group_id Many2one → procurement.group
    copy=False string='Procurement Group' args: 'procurement.group'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    copy=True readonly=False track_visibility='onchange' args: 'purchase.request.line', 'request_id', 'Products to Purchase'
  • move_count Integer
    compute='_compute_move_count' readonly=True string='Stock Move count'
  • name Char
    default=_get_default_name required=True track_visibility='onchange' args: 'Request Reference'
  • origin Char
    args: 'Source Document'
  • picking_type_id Many2one → stock.picking.type
    default=_default_picking_type required=True args: 'stock.picking.type', 'Picking Type'
  • product_id Many2one → product.product
    readonly=True related='line_ids.product_id' string='Product' args: 'product.product'
  • purchase_count Integer
    compute='_compute_purchase_count' readonly=True string='Purchases count'
  • requested_by Many2one → res.users
    copy=False default=_get_default_requested_by required=True track_visibility='onchange' args: 'res.users', 'Requested by'
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' track_visibility='onchange'
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (14)
  • action_view_purchase_order(self)
    @api.multi
  • action_view_purchase_request_line(self)
    @api.multi
  • action_view_stock_move(self)
    @api.multi
  • button_approved(self)
    @api.multi
  • button_done(self)
    @api.multi
  • button_draft(self)
    @api.multi
  • button_rejected(self)
    @api.multi
  • button_to_approve(self)
    @api.multi
  • check_auto_reject(self)
    @api.multi
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
    @api.multi
  • create(self, vals)
    @api.model
  • to_approve_allowed_check(self)
    @api.multi
  • unlink(self)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (10)
  • allocated_product_qty Float
    copy=False help='Quantity of the purchase request line allocated to the stockmove, in the default UoM of the product' args: 'Allocated Quantity'
  • company_id Many2one → res.company
    comodel_name='res.company' index=True readonly=True related='purchase_request_line_id.request_id.company_id' store=True string='Company'
  • open_product_qty Float
    compute='_compute_open_product_qty' args: 'Open Quantity'
  • product_id Many2one → product.product
    comodel_name='product.product' readonly=True related='purchase_request_line_id.product_id' string='Product'
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' readonly=True related='purchase_request_line_id.product_uom_id' required=True string='UoM'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' copy=True help='Service Purchase Order Line' ondelete='cascade' string='Purchase Line'
  • purchase_request_line_id Many2one → purchase.request.line
    comodel_name='purchase.request.line' copy=True ondelete='cascade' required=True string='Purchase Request Line'
  • purchase_state Selection
    related='purchase_line_id.state'
  • requested_product_uom_qty Float
    help='Quantity of the purchase request line allocated to thestock move, in the UoM of the Purchase Request Line' args: 'Requested Quantity'
  • stock_move_id Many2one → stock.move
    comodel_name='stock.move' index=True ondelete='cascade' string='Stock Move'
Public methods (0)

No public methods.

New fields (32)
  • analytic_account_id Many2one → account.analytic.account
    track_visibility='onchange' args: 'account.analytic.account', 'Analytic Account'
  • analytic_tag_ids Many2many → account.analytic.tag
    string='Analytic Tags' track_visibility='onchange' args: 'account.analytic.tag'
  • assigned_to Many2one → res.users
    related='request_id.assigned_to' store=True string='Assigned to' args: 'res.users'
  • cancelled Boolean
    copy=False default=False readonly=True string='Cancelled'
  • company_id Many2one → res.company
    related='request_id.company_id' store=True string='Company' args: 'res.company'
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' track_visibility='onchange'
  • date_start Date
    related='request_id.date_start' store=True
  • description Text
    readonly=False related='request_id.description' store=True string='PR Description'
  • estimated_cost Monetary
    currency_field='currency_id' default=0.0 help='Estimated cost of Purchase Request Line, not propagated to PO.' string='Estimated Cost'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • move_dest_ids One2many → stock.move
    args: 'stock.move', 'created_purchase_request_line_id', 'Downstream Moves'
  • name Char
    track_visibility='onchange' args: 'Description'
  • orderpoint_id Many2one → stock.warehouse.orderpoint
    args: 'stock.warehouse.orderpoint', 'Orderpoint'
  • origin Char
    related='request_id.origin' store=True string='Source Document'
  • pending_qty_to_receive Float
    compute='_compute_qty_to_buy' copy=False digits=dp.get_precision('Product Unit of Measure') store=True string='Pending Qty to Receive'
  • product_id Many2one → product.product
    domain=[('purchase_ok', '=', True)] index=True track_visibility='onchange' args: 'product.product', 'Product'
  • product_qty Float
    digits=dp.get_precision('Product Unit of Measure') track_visibility='onchange' args: 'Quantity'
  • product_uom_id Many2one → uom.uom
    track_visibility='onchange' args: 'uom.uom', 'Product Unit of Measure'
  • purchase_lines Many2many → purchase.order.line
    copy=False readonly=True args: 'purchase.order.line', 'purchase_request_purchase_order_line_rel', 'purchase_request_line_id', 'purchase_order_line_id', 'Purchase Order Lines'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' inverse_name='purchase_request_line_id' string='Purchase Request Allocation'
  • purchase_state Selection
    compute='_compute_purchase_state' selection=<expr> store=True string='Purchase Status'
  • purchased_qty Float
    compute='_compute_purchased_qty' digits=dp.get_precision('Product Unit of Measure') string='Quantity in RFQ or PO'
  • qty_cancelled Float
    compute='_compute_qty_cancelled' digits=dp.get_precision('Product Unit of Measure') help='Quantity cancelled' readonly=True store=True args: 'Qty Cancelled'
  • qty_done Float
    compute='_compute_qty' digits=dp.get_precision('Product Unit of Measure') help='Quantity completed' readonly=True store=True args: 'Qty Done'
  • qty_in_progress Float
    compute='_compute_qty' digits=dp.get_precision('Product Unit of Measure') help='Quantity in progress.' readonly=True store=True args: 'Qty In Progress'
  • qty_to_buy Boolean
    compute='_compute_qty_to_buy' store=True string='There is some pending qty to buy'
  • request_id Many2one → purchase.request
    ondelete='cascade' readonly=True args: 'purchase.request', 'Purchase Request'
  • request_state Selection
    related='request_id.state' selection=_STATES store=True string='Request state'
  • requested_by Many2one → res.users
    related='request_id.requested_by' store=True string='Requested by' args: 'res.users'
  • specifications Text
    string='Specifications'
  • supplier_id Many2one → res.partner
    compute='_compute_supplier_id' compute_sudo=True store=True string='Preferred supplier' args: 'res.partner'
Public methods (6)
  • check_done(self)
  • do_cancel(self)
    @api.multi
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    @api.multi
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • unlink(self)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (4)
  • item_ids One2many → purchase.request.line.make.purchase.order.item
    string='Items' args: 'purchase.request.line.make.purchase.order.item', 'wiz_id'
  • purchase_order_id Many2one → purchase.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'purchase.order'
  • supplier_id Many2one → res.partner
    domain=[('supplier', '=', True), ('is_company', '=', True)] required=True string='Supplier' args: 'res.partner'
  • sync_data_planned Boolean
    string='Merge on PO lines with equal Scheduled Date'
Public methods (5)
  • check_group(self, request_lines)
    @api.model
  • create_allocation(self, po_line, pr_line, new_qty, alloc_uom)
  • default_get(self, fields)
    @api.model
  • get_items(self, request_line_ids)
    @api.model
  • make_purchase_order(self)
    @api.multi

New fields (11)
  • currency_id Many2one → res.currency
    readonly=True related='line_id.currency_id' string='Currency' args: 'res.currency'
  • estimated_cost Monetary
    currency_field='currency_id' string='Estimated Cost'
  • keep_description Boolean
    help='Set true if you want to keep the descriptions provided in the wizard in the new PO.' string='Copy descriptions to new PO'
  • keep_estimated_cost Boolean
    help='Set true if you want to keep the estimated cost provided in the wizard in the new PO.' string='Copy estimative cost to new PO'
  • line_id Many2one → purchase.request.line
    string='Purchase Request Line' args: 'purchase.request.line'
  • name Char
    required=True string='Description'
  • product_id Many2one → product.product
    readonly=False related='line_id.product_id' string='Product' args: 'product.product'
  • product_qty Float
    digits=dp.get_precision('Product Unit of Measure') string='Quantity to purchase'
  • product_uom_id Many2one → uom.uom
    required=True string='UoM' args: 'uom.uom'
  • request_id Many2one → purchase.request
    readonly=False related='line_id.request_id' string='Purchase Request' args: 'purchase.request'
  • wiz_id Many2one → purchase.request.line.make.purchase.order
    ondelete='cascade' readonly=True required=True string='Wizard' args: 'purchase.request.line.make.purchase.order'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id')

New fields (3)
  • created_purchase_request_line_id Many2one → purchase.request.line
    copy=False ondelete='set null' readonly=True args: 'purchase.request.line', 'Created Purchase Request Line'
  • purchase_request_allocation_ids One2many → purchase.request.allocation
    comodel_name='purchase.request.allocation' copy=False inverse_name='stock_move_id' string='Purchase Request Allocation'
  • purchase_request_ids One2many → purchase.request
    comodel_name='purchase.request' compute='_compute_purchase_request_ids' string='Purchase Requests'
Public methods (1)
  • copy_data(self, default=None)

New fields (0)

No new fields.

Public methods (1)
  • allocate(self)

New fields (0)

No new fields.

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

New fields (0)

No new fields.

Public methods (2)
  • create_purchase_request(self, product_id, product_qty, product_uom, origin, values)
    @api.multi
    Create a purchase request containing procurement order product.
  • is_create_purchase_request_allowed(self, product_id)
    @api.multi
    Tell if current procurement order should create a purchase request or not. :return: boolean

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/11.0/purchase_request
VERSION
VERSION 1.2.6
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Eficent
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Eficent
COMMITTERS
COMMITTERSBhavesh Odedra, Jordi Ballester Alomar, OCA Transbot, oca-travis, Weblate, OCA-git-bot, Aaron Henriquez, hveficent
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:24:01
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase
    - stock_account
    - stock
    - product
    - base
    - decimal_precision
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - barcodes
    - web_planner
    - account
    - analytic
    - portal
    - http_routing
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (15)
XML IDNameModelTypeStatus
product_template_form_view_inherit product.template.form.inherit product.template Inherits stock.view_template_property_form
purchase_order_form purchase.order.form purchase.order Inherits purchase.purchase_order_form
purchase_order_line_form2 purchase.order.line.form2 purchase.order.line Inherits purchase.purchase_order_line_form2
purchase_order_line_form2_sub purchase.order.line.form2 purchase.order.line form New
purchase_order_line_search_sub purchase.order.line.search purchase.order.line search New
purchase_order_line_tree purchase.order.line.tree purchase.order.line Inherits purchase.purchase_order_line_tree
purchase_order_line_tree_sub purchase.order.line.tree purchase.order.line tree New
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchase_request report_purchase_request ir.ui.view qweb New
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_line_make_purchase_order Purchase Request Line Make Purchase Order purchase.request.line.make.purchase.order form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (11)

New fields (0)

No new fields.

Public methods (2)
  • create_purchase_request(self, product_id, product_qty, product_uom, origin, values)
    @api.multi
    Create a purchase request containing procurement order product.
  • is_create_purchase_request_allowed(self, product_id)
    @api.multi
    Tell if current procurement order should create a purchase request or not. :return: boolean

New fields (1)
  • purchase_request Boolean
    help='Check this box to generate purchase request instead of generating requests for quotation from procurement.' string='Purchase Request'
Public methods (0)

No public methods.

New fields (0)

No new fields.

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

New fields (1)
  • purchase_request_lines Many2many → purchase.request.line
    copy=False readonly=True args: 'purchase.request.line', 'purchase_request_purchase_order_line_rel', 'purchase_order_line_id', 'purchase_request_line_id', 'Purchase Request Lines'
Public methods (1)
  • action_openRequestLineTreeView(self)
    @api.multi
    :return dict: dictionary value for created view

New fields (15)
  • assigned_to Many2one → res.users
    domain=<expr> track_visibility='onchange' args: 'res.users', 'Approver'
  • company_id Many2one → res.company
    default=_company_get required=True track_visibility='onchange' args: 'res.company', 'Company'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' track_visibility='onchange' args: 'Creation date'
  • description Text
    args: 'Description'
  • group_id Many2one → procurement.group
    copy=False string='Procurement Group' args: 'procurement.group'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    copy=True readonly=False track_visibility='onchange' args: 'purchase.request.line', 'request_id', 'Products to Purchase'
  • name Char
    default=_get_default_name required=True track_visibility='onchange' args: 'Request Reference'
  • origin Char
    args: 'Source Document'
  • picking_type_id Many2one → stock.picking.type
    default=_default_picking_type required=True args: 'stock.picking.type', 'Picking Type'
  • product_id Many2one → product.product
    readonly=True related='line_ids.product_id' string='Product' args: 'product.product'
  • requested_by Many2one → res.users
    default=_get_default_requested_by required=True track_visibility='onchange' args: 'res.users', 'Requested by'
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' track_visibility='onchange'
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (11)
  • action_view_purchase_request_line(self)
    @api.multi
  • button_approved(self)
    @api.multi
  • button_done(self)
    @api.multi
  • button_draft(self)
    @api.multi
  • button_rejected(self)
    @api.multi
  • button_to_approve(self)
    @api.multi
  • check_auto_reject(self)
    @api.multi
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
    @api.multi
  • create(self, vals)
    @api.model
  • to_approve_allowed_check(self)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (25)
  • analytic_account_id Many2one → account.analytic.account
    track_visibility='onchange' args: 'account.analytic.account', 'Analytic Account'
  • assigned_to Many2one → res.users
    readonly=True related='request_id.assigned_to' store=True string='Assigned to' args: 'res.users'
  • cancelled Boolean
    copy=False default=False readonly=True string='Cancelled'
  • company_id Many2one → res.company
    readonly=True related='request_id.company_id' store=True string='Company' args: 'res.company'
  • currency_id Many2one
    readonly=True related='company_id.currency_id'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' track_visibility='onchange'
  • date_start Date
    readonly=True related='request_id.date_start' store=True string='Request Date'
  • description Text
    readonly=True related='request_id.description' store=True string='Description'
  • estimated_cost Monetary
    currency_field='currency_id' default=0.0 help='Estimated cost of Purchase Request Line, not propagated to PO.' string='Estimated Cost'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • move_dest_ids One2many → stock.move
    args: 'stock.move', 'created_purchase_request_line_id', 'Downstream Moves'
  • name Char
    track_visibility='onchange' args: 'Description'
  • orderpoint_id Many2one → stock.warehouse.orderpoint
    args: 'stock.warehouse.orderpoint', 'Orderpoint'
  • origin Char
    readonly=True related='request_id.origin' store=True string='Source Document'
  • product_id Many2one → product.product
    domain=[('purchase_ok', '=', True)] track_visibility='onchange' args: 'product.product', 'Product'
  • product_qty Float
    digits=dp.get_precision('Product Unit of Measure') track_visibility='onchange' args: 'Quantity'
  • product_uom_id Many2one → product.uom
    track_visibility='onchange' args: 'product.uom', 'Product Unit of Measure'
  • purchase_lines Many2many → purchase.order.line
    copy=False readonly=True args: 'purchase.order.line', 'purchase_request_purchase_order_line_rel', 'purchase_request_line_id', 'purchase_order_line_id', 'Purchase Order Lines'
  • purchase_state Selection
    compute='_compute_purchase_state' selection=<expr> store=True string='Purchase Status'
  • purchased_qty Float
    compute='_compute_purchased_qty' digits=dp.get_precision('Product Unit of Measure') string='Quantity in RFQ or PO'
  • request_id Many2one → purchase.request
    ondelete='cascade' readonly=True args: 'purchase.request', 'Purchase Request'
  • request_state Selection
    readonly=True related='request_id.state' selection=_STATES store=True string='Request state'
  • requested_by Many2one → res.users
    readonly=True related='request_id.requested_by' store=True string='Requested by' args: 'res.users'
  • specifications Text
    string='Specifications'
  • supplier_id Many2one → res.partner
    compute='_compute_supplier_id' string='Preferred supplier' args: 'res.partner'
Public methods (5)
  • do_cancel(self)
    @api.multi
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    @api.multi
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • unlink(self)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (4)
  • item_ids One2many → purchase.request.line.make.purchase.order.item
    string='Items' args: 'purchase.request.line.make.purchase.order.item', 'wiz_id'
  • purchase_order_id Many2one → purchase.order
    domain=[('state', '=', 'draft')] string='Purchase Order' args: 'purchase.order'
  • supplier_id Many2one → res.partner
    domain=[('supplier', '=', True), ('is_company', '=', True)] required=True string='Supplier' args: 'res.partner'
  • sync_data_planned Boolean
    string='Merge on PO lines with equal Scheduled Date'
Public methods (2)
  • default_get(self, fields)
    @api.model
  • make_purchase_order(self)
    @api.multi

New fields (8)
  • keep_description Boolean
    help='Set true if you want to keep the descriptions provided in the wizard in the new PO.' string='Copy descriptions to new PO'
  • line_id Many2one → purchase.request.line
    string='Purchase Request Line' args: 'purchase.request.line'
  • name Char
    required=True string='Description'
  • product_id Many2one → product.product
    related='line_id.product_id' string='Product' args: 'product.product'
  • product_qty Float
    digits=dp.get_precision('Product Unit of Measure') string='Quantity to purchase'
  • product_uom_id Many2one → product.uom
    string='UoM' args: 'product.uom'
  • request_id Many2one → purchase.request
    related='line_id.request_id' string='Purchase Request' args: 'purchase.request'
  • wiz_id Many2one → purchase.request.line.make.purchase.order
    ondelete='cascade' readonly=True required=True string='Wizard' args: 'purchase.request.line.make.purchase.order'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id')

New fields (1)
  • created_purchase_request_line_id Many2one → purchase.request.line
    copy=False ondelete='set null' readonly=True args: 'purchase.request.line', 'Created Purchase Request Line'
Public methods (0)

No public methods.

New fields (0)

No new fields.

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

New fields (0)

No new fields.

Public methods (0)

No public methods.

REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/10.0/purchase_request
VERSION
VERSION 1.2.2
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Eficent Business and IT Consulting Services S.L.
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Eficent Business and IT Consulting Services S.L.
COMMITTERS
COMMITTERSPedro M. Baeza, Jordi Ballester Alomar, OCA Transbot, ahenriquez, Adrien Peiffer (ACSONE), oca-travis, Weblate, OCA-git-bot, aheficent, Sylvain GARANCHER, hparfr, Benjamin Willig, Benoit Aimont
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:20:01
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase
    - stock_account
    - stock
    - product
    - base
    - decimal_precision
    - mail
    - base_setup
    - web_kanban
    - web
    - bus
    - web_tour
    - report
    - procurement
    - barcodes
    - web_planner
    - account
    - analytic
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchaserequests report_purchaserequests ir.ui.view qweb New
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (2)

New fields (14)
  • assigned_to Many2one → res.users
    track_visibility='onchange' args: 'res.users', 'Approver'
  • company_id Many2one → res.company
    default=_company_get required=True track_visibility='onchange' args: 'res.company', 'Company'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' track_visibility='onchange' args: 'Creation date'
  • description Text
    args: 'Description'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • line_count Integer
    compute='_compute_line_count' readonly=True string='Purchase Request Line count'
  • line_ids One2many → purchase.request.line
    copy=True readonly=False track_visibility='onchange' args: 'purchase.request.line', 'request_id', 'Products to Purchase'
  • name Char
    default=_get_default_name required=True size=32 track_visibility='onchange' args: 'Request Reference'
  • origin Char
    size=32 args: 'Source Document'
  • picking_type_id Many2one → stock.picking.type
    default=_default_picking_type required=True args: 'stock.picking.type', 'Picking Type'
  • product_id Many2one → product.product
    readonly=True related='line_ids.product_id' string='Product' args: 'product.product'
  • requested_by Many2one → res.users
    copy=False default=_get_default_requested_by required=True track_visibility='onchange' args: 'res.users', 'Requested by'
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' track_visibility='onchange'
  • to_approve_allowed Boolean
    compute='_compute_to_approve_allowed'
Public methods (12)
  • action_view_purchase_request_line(self)
    @api.multi
  • button_approved(self)
    @api.multi
  • button_done(self)
    @api.multi
  • button_draft(self)
    @api.multi
  • button_rejected(self)
    @api.multi
  • button_to_approve(self)
    @api.multi
  • check_auto_reject(self)
    @api.multi
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
    @api.multi
  • create(self, vals)
    @api.model
  • to_approve_allowed_check(self)
    @api.multi
  • unlink(self)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (19)
  • analytic_account_id Many2one → account.analytic.account
    track_visibility='onchange' args: 'account.analytic.account', 'Analytic Account'
  • assigned_to Many2one → res.users
    readonly=True related='request_id.assigned_to' store=True string='Assigned to' args: 'res.users'
  • cancelled Boolean
    copy=False default=False readonly=True string='Cancelled'
  • company_id Many2one → res.company
    readonly=True related='request_id.company_id' store=True string='Company' args: 'res.company'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' track_visibility='onchange'
  • date_start Date
    readonly=True related='request_id.date_start' store=True
  • description Text
    readonly=True related='request_id.description' store=True string='Description'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • name Char
    size=256 track_visibility='onchange' args: 'Description'
  • origin Char
    readonly=True related='request_id.origin' size=32 store=True string='Source Document'
  • procurement_id Many2one → procurement.order
    copy=False readonly=True args: 'procurement.order', 'Procurement Order'
  • product_id Many2one → product.product
    domain=[('purchase_ok', '=', True)] track_visibility='onchange' args: 'product.product', 'Product'
  • product_qty Float
    digits=dp.get_precision('Product Unit of Measure') track_visibility='onchange' args: 'Quantity'
  • product_uom_id Many2one → product.uom
    track_visibility='onchange' args: 'product.uom', 'Product Unit of Measure'
  • request_id Many2one → purchase.request
    ondelete='cascade' readonly=True args: 'purchase.request', 'Purchase Request'
  • request_state Selection
    readonly=True related='request_id.state' selection=_STATES store=True string='Request state'
  • requested_by Many2one → res.users
    readonly=True related='request_id.requested_by' store=True string='Requested by' args: 'res.users'
  • specifications Text
    string='Specifications'
  • supplier_id Many2one → res.partner
    compute='_compute_supplier_id' string='Preferred supplier' args: 'res.partner'
Public methods (5)
  • do_cancel(self)
    @api.multi
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    @api.multi
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • unlink(self)
    @api.multi
  • write(self, vals)
    @api.multi
REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/9.0/purchase_request
VERSION
VERSION 1.0.3
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Eficent Business and IT Consulting Services S.L.
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Eficent Business and IT Consulting Services S.L.
COMMITTERS
COMMITTERSPedro M. Baeza, GitHub, Denis Roussel, Jordi Ballester Alomar, Jordi Ballester, OCA Transbot, ahenriquez, jbeficent, aheficent, lreficent, Zakaria Makrelouf, gmeficent
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:15:23
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase
    - stock_account
    - stock
    - product
    - base
    - decimal_precision
    - mail
    - base_setup
    - web_kanban
    - web
    - bus
    - report
    - procurement
    - barcodes
    - web_planner
    - account
    - analytic
    - web_tip
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchaserequests report_purchaserequests ir.ui.view qweb New
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (3)

New fields (1)
  • request_id Many2one → purchase.request
    comodel_name='purchase.request' copy=False ondelete='restrict' string='Latest Purchase Request'
Public methods (0)

No public methods.

New fields (11)
  • assigned_to Many2one → res.users
    track_visibility='onchange' args: 'res.users', 'Approver'
  • company_id Many2one → res.company
    default=_company_get required=True track_visibility='onchange' args: 'res.company', 'Company'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' track_visibility='onchange' args: 'Creation date'
  • description Text
    args: 'Description'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • line_ids One2many → purchase.request.line
    copy=True readonly=False track_visibility='onchange' args: 'purchase.request.line', 'request_id', 'Products to Purchase'
  • name Char
    default=_get_default_name required=True size=32 track_visibility='onchange' args: 'Request Reference'
  • origin Char
    size=32 args: 'Source Document'
  • picking_type_id Many2one → stock.picking.type
    comodel_name='stock.picking.type' default=_default_picking_type domain="[('code', '=', 'incoming')]" required=True string='Picking Type'
  • requested_by Many2one → res.users
    default=_get_default_requested_by required=True track_visibility='onchange' args: 'res.users', 'Requested by'
  • state Selection
    copy=False default='draft' index=True required=True selection=_STATES string='Status' track_visibility='onchange'
Public methods (9)
  • button_approved(self)
    @api.multi
  • button_done(self)
    @api.multi
  • button_draft(self)
    @api.multi
  • button_rejected(self)
    @api.multi
  • button_to_approve(self)
    @api.multi
  • check_auto_reject(self)
    @api.multi
    When all lines are cancelled the purchase request should be auto-rejected.
  • copy(self, default=None)
    @api.multi
  • create(self, vals)
    @api.model
  • write(self, vals)
    @api.multi

New fields (19)
  • analytic_account_id Many2one → account.analytic.account
    track_visibility='onchange' args: 'account.analytic.account', 'Analytic Account'
  • assigned_to Many2one → res.users
    readonly=True related='request_id.assigned_to' store=True string='Assigned to' args: 'res.users'
  • cancelled Boolean
    copy=False default=False readonly=True string='Cancelled'
  • company_id Many2one → res.company
    readonly=True related='request_id.company_id' store=True string='Company' args: 'res.company'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' track_visibility='onchange'
  • date_start Date
    readonly=True related='request_id.date_start' store=True string='Request Date'
  • description Text
    readonly=True related='request_id.description' store=True string='Description'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • name Char
    size=256 track_visibility='onchange' args: 'Description'
  • origin Char
    readonly=True related='request_id.origin' size=32 store=True string='Source Document'
  • procurement_id Many2one → procurement.order
    copy=False readonly=True args: 'procurement.order', 'Procurement Order'
  • product_id Many2one → product.product
    domain=[('purchase_ok', '=', True)] track_visibility='onchange' args: 'product.product', 'Product'
  • product_qty Float
    digits_compute=dp.get_precision('Product Unit of Measure') track_visibility='onchange' args: 'Quantity'
  • product_uom_id Many2one → product.uom
    track_visibility='onchange' args: 'product.uom', 'Product Unit of Measure'
  • request_id Many2one → purchase.request
    index=True ondelete='cascade' readonly=True args: 'purchase.request', 'Purchase Request'
  • request_state Selection
    readonly=True related='request_id.state' selection=_STATES store=True string='Request state'
  • requested_by Many2one → res.users
    readonly=True related='request_id.requested_by' store=True string='Requested by' args: 'res.users'
  • specifications Text
    string='Specifications'
  • supplier_id Many2one → res.partner
    compute='_compute_supplier_id' string='Preferred supplier' args: 'res.partner'
Public methods (4)
  • do_cancel(self)
    @api.multi
    Actions to perform when cancelling a purchase request line.
  • do_uncancel(self)
    @api.multi
    Actions to perform when uncancelling a purchase request line.
  • onchange_product_id(self)
    @api.onchange('product_id')
  • write(self, vals)
    @api.multi
REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/8.0/purchase_request
VERSION
VERSION 1.1.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Eficent
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Eficent
COMMITTERS
COMMITTERSStéphane Bidoul, GitHub, Stéphane Bidoul (ACSONE), Jordi Ballester Alomar, OCA Transbot, jbeficent, Moises Lopez - https://www.vauxoo.com/, oca-travis, Weblate
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:11:26
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase
    - stock_account
    - stock
    - product
    - base
    - decimal_precision
    - mail
    - base_setup
    - web_kanban
    - web
    - report
    - procurement
    - board
    - web_kanban_gauge
    - web_kanban_sparkline
    - account
    - analytic
    - edi
    - email_template
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
purchase_request_line_form purchase.request.line.form purchase.request.line form New
purchase_request_line_search purchase.request.line.search purchase.request.line search New
purchase_request_line_tree purchase.request.line.tree purchase.request.line tree New
report_purchaserequests report_purchaserequests ir.ui.view qweb New
view_purchase_request_form purchase.request.form purchase.request form New
view_purchase_request_search purchase.request.list.select purchase.request search New
view_purchase_request_tree purchase.request.tree purchase.request tree New
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (2)

New fields (11)
  • assigned_to Many2one → res.users
    track_visibility='onchange' args: 'res.users', 'Approver'
  • company_id Many2one → res.company
    default=_company_get required=True track_visibility='onchange' args: 'res.company', 'Company'
  • date_start Date
    default=fields.Date.context_today help='Date when the user initiated the request.' track_visibility='onchange' args: 'Creation date'
  • description Text
    args: 'Description'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • line_ids One2many → purchase.request.line
    copy=True readonly=False track_visibility='onchange' args: 'purchase.request.line', 'request_id', 'Products to Purchase'
  • name Char
    default=_get_default_name required=True size=32 track_visibility='onchange' args: 'Request Reference'
  • origin Char
    size=32 args: 'Source Document'
  • picking_type_id Many2one → stock.picking.type
    default=_default_picking_type required=True args: 'stock.picking.type', 'Picking Type'
  • requested_by Many2one → res.users
    default=_get_default_requested_by required=True track_visibility='onchange' args: 'res.users', 'Requested by'
  • state Selection
    default='draft' required=True selection=_STATES string='Status' track_visibility='onchange'
Public methods (7)
  • button_approved(self)
    @api.multi
  • button_draft(self)
    @api.multi
  • button_rejected(self)
    @api.multi
  • button_to_approve(self)
    @api.multi
  • copy(self, default=None)
    @api.multi
  • create(self, vals)
    @api.model
  • write(self, vals)
    @api.multi

New fields (18)
  • analytic_account_id Many2one → account.analytic.account
    track_visibility='onchange' args: 'account.analytic.account', 'Analytic Account'
  • assigned_to Many2one → res.users
    readonly=True related='request_id.assigned_to' store=True string='Assigned to' args: 'res.users'
  • company_id Many2one → res.company
    readonly=True related='request_id.company_id' store=True string='Company' args: 'res.company'
  • date_required Date
    default=fields.Date.context_today required=True string='Request Date' track_visibility='onchange'
  • date_start Date
    readonly=True related='request_id.date_start' store=True string='Request Date'
  • description Text
    readonly=True related='request_id.description' store=True string='Description'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is editable'
  • name Char
    size=256 track_visibility='onchange' args: 'Description'
  • origin Char
    readonly=True related='request_id.origin' size=32 store=True string='Source Document'
  • procurement_id Many2one → procurement.order
    readonly=True args: 'procurement.order', 'Procurement Order'
  • product_id Many2one → product.product
    domain=[('purchase_ok', '=', True)] track_visibility='onchange' args: 'product.product', 'Product'
  • product_qty Float
    digits_compute=dp.get_precision('Product Unit of Measure') track_visibility='onchange' args: 'Quantity'
  • product_uom_id Many2one → product.uom
    track_visibility='onchange' args: 'product.uom', 'Product Unit of Measure'
  • request_id Many2one → purchase.request
    ondelete='cascade' readonly=True args: 'purchase.request', 'Purchase Request'
  • request_state Selection
    readonly=True related='request_id.state' selection=_STATES store=True string='Request state'
  • requested_by Many2one → res.users
    readonly=True related='request_id.requested_by' store=True string='Requested by' args: 'res.users'
  • specifications Text
    string='Specifications'
  • supplier_id Many2one → res.partner
    compute='_compute_supplier_id' string='Preferred supplier' args: 'res.partner'
Public methods (1)
  • onchange_product_id(self)
    @api.onchange('product_id', 'product_uom_id')