Purchase RFQ Bid workflow

purchase_rfq_bid_workflow
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_rfq_bid_workflow
VERSION
VERSION 0.3.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Camptocamp
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Camptocamp
COMMITTERS
COMMITTERSPedro M. Baeza
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
This module improves the standard Purchase module.
==================================================
In standard, RFQs, Bids and PO are all the same object.  The purchase workflow
has been improved with a new 'Draft PO' state to clearly differentiate the
RFQ->Bid workflow and the PO workflow. A type field has also been added to
identify if a document is of type 'rfq' or 'purchase'. This is particularly
useful for canceled state and for datawarehouse.

The 'Requests for Quotation' menu entry shows only documents of type 'rfq' and
the new documents are created in state 'Draft RFQ'. Those documents have lines
with a price, by default, set to 0; it will have to be encoded when the bid is
received. The state 'Bid Received' has been renamed 'Bid Encoded'. This clearly
indicates that the price has been filled in. The bid received date will be
requested when moving to that state.

The 'Purchase Orders' menu entry shows only documents of type 'purchase' and
the new documents are created in state 'Draft PO'.

The logged messages have been improved to notify users at the state changes and
with the right naming.


In the scope of international transactions, some fields have been added:
 - Consignee: the person to whom the shipment is to be delivered
 - Incoterms Place: the standard incoterms field specifies the incoterms rule
   that applies. This field allows to name the place where the goods will be
   available

TODO: describe onchange picking type.

Note: for running the tests, the python package nose is required. It is not
listed as an external dependency because it is not needed in production.

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
action_modal_bid_date action.modal purchase.action_modal.datetime form New
action_modal_cancel_reason action.modal purchase.action_modal.cancel_reason form New
po_line_onchange_form purchase.order.line field Inherits purchase.purchase_order_line_form
view_purchase_cancel_reason_form Purchase Cancel Reason purchase.cancel_reason form New
view_purchase_cancel_reason_tree Purchase Cancel Reasons purchase.cancel_reason tree New
view_purchase_order_form purchase.order.form.inherit purchase.order xpath Inherits purchase.purchase_order_form
view_purchase_order_invoice_form purchase.order.form.invoice.inherit purchase.order xpath Inherits purchase.purchase_order_2_stock_picking
Models touched (7)

New fields (0)

No new fields.

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

New fields (1)
  • reason_id Many2one → purchase.cancel_reason
    required=True args: 'purchase.cancel_reason', 'Reason for Cancellation'
Public methods (0)

No public methods.

New fields (1)
  • datetime Datetime
    args: 'Date'
Public methods (0)

No public methods.

New fields (3)
  • name Char
    required=True size=64 translate=True args: 'Reason'
  • nounlink Boolean
    args: 'No unlink'
  • type Selection
    required=True args: [('rfq', 'RFQ/Bid'), ('purchase', 'Purchase Order')], 'Type'
Public methods (1)
  • unlink(self)
    @api.one
    Prevent to unlink records that are used in the code

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • cancel_reason_id Many2one → purchase.cancel_reason
    readonly=True args: 'purchase.cancel_reason', 'Reason for Cancellation'
  • currency_id Many2one → res.currency
    readonly=True required=True states=STATES args: 'res.currency', 'Currency'
  • incoterm_address Char
    help='Incoterms Place of Delivery. International Commercial Terms are a series of predefined commercial terms used in international transactions.' args: 'Incoterms Place'
  • pricelist_id Many2one → product.pricelist
    help='The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities.' readonly=True required=True states=STATES args: 'product.pricelist', 'Pricelist'
  • type Selection
    default=_default_type readonly=True required=True args: TYPE_SELECTION, 'Type'
Public methods (12)
  • action_cancel(self)
    @api.multi
    Ask a cancel reason
  • action_cancel_ok(self)
    @api.multi
  • bid_received(self)
    @api.multi
  • bid_received_ok(self)
    @api.multi
  • copy(self, default=None)
    @api.one
  • create(self, values)
    @api.model
  • po_tender_requisition_selected(self)
    @api.multi
    Workflow function that write state 'bid selected'
  • print_quotation(self)
    @api.multi
  • wkf_action_cancel(self)
    @api.multi
  • wkf_bid_received(self)
    @api.multi
  • wkf_draft_po(self)
    @api.multi
  • wkf_send_rfq(self)
    @api.multi

New fields (0)

No new fields.

Public methods (1)
  • onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, state='draftpo', context=None)
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_rfq_bid_workflow
VERSION
VERSION 0.3.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Camptocamp
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Camptocamp
COMMITTERS
COMMITTERSPedro M. Baeza
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:15:23
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/server-tools:
    - web_context_tunnel
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
This module improves the standard Purchase module.
==================================================
In standard, RFQs, Bids and PO are all the same object.  The purchase workflow
has been improved with a new 'Draft PO' state to clearly differentiate the
RFQ->Bid workflow and the PO workflow. A type field has also been added to
identify if a document is of type 'rfq' or 'purchase'. This is particularly
useful for canceled state and for datawarehouse.

The 'Requests for Quotation' menu entry shows only documents of type 'rfq' and
the new documents are created in state 'Draft RFQ'. Those documents have lines
with a price, by default, set to 0; it will have to be encoded when the bid is
received. The state 'Bid Received' has been renamed 'Bid Encoded'. This clearly
indicates that the price has been filled in. The bid received date will be
requested when moving to that state.

The 'Purchase Orders' menu entry shows only documents of type 'purchase' and
the new documents are created in state 'Draft PO'.

The logged messages have been improved to notify users at the state changes and
with the right naming.


In the scope of international transactions, some fields have been added:
 - Consignee: the person to whom the shipment is to be delivered
 - Incoterms Place: the standard incoterms field specifies the incoterms rule
   that applies. This field allows to name the place where the goods will be
   available

TODO: describe onchange picking type.

Note: for running the tests, the python package nose is required. It is not
listed as an external dependency because it is not needed in production.

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
action_modal_bid_date action.modal purchase.action_modal.datetime form New
action_modal_cancel_reason action.modal purchase.action_modal.cancel_reason form New
po_line_onchange_form purchase.order.line field Inherits purchase.purchase_order_line_form
view_purchase_cancel_reason_form Purchase Cancel Reason purchase.cancel_reason form New
view_purchase_cancel_reason_tree Purchase Cancel Reasons purchase.cancel_reason tree New
view_purchase_order_form purchase.order.form.inherit purchase.order xpath Inherits purchase.purchase_order_form
view_purchase_order_invoice_form purchase.order.form.invoice.inherit purchase.order xpath Inherits purchase.purchase_order_2_stock_picking
Models touched (7)

New fields (0)

No new fields.

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

New fields (1)
  • reason_id Many2one → purchase.cancel_reason
    required=True args: 'purchase.cancel_reason', 'Reason for Cancellation'
Public methods (0)

No public methods.

New fields (1)
  • datetime Datetime
    args: 'Date'
Public methods (0)

No public methods.

New fields (3)
  • name Char
    required=True size=64 translate=True args: 'Reason'
  • nounlink Boolean
    args: 'No unlink'
  • type Selection
    required=True args: [('rfq', 'RFQ/Bid'), ('purchase', 'Purchase Order')], 'Type'
Public methods (1)
  • unlink(self)
    @api.one
    Prevent to unlink records that are used in the code

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • cancel_reason_id Many2one → purchase.cancel_reason
    readonly=True args: 'purchase.cancel_reason', 'Reason for Cancellation'
  • currency_id Many2one → res.currency
    readonly=True required=True states=STATES args: 'res.currency', 'Currency'
  • incoterm_address Char
    help='Incoterms Place of Delivery. International Commercial Terms are a series of predefined commercial terms used in international transactions.' args: 'Incoterms Place'
  • pricelist_id Many2one → product.pricelist
    help='The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities.' readonly=True required=True states=STATES args: 'product.pricelist', 'Pricelist'
  • type Selection
    default=_default_type readonly=True required=True args: TYPE_SELECTION, 'Type'
Public methods (12)
  • action_cancel(self)
    @api.multi
    Ask a cancel reason
  • action_cancel_ok(self)
    @api.multi
  • bid_received(self)
    @api.multi
  • bid_received_ok(self)
    @api.multi
  • copy(self, default=None)
    @api.one
  • create(self, values)
    @api.model
  • po_tender_requisition_selected(self)
    @api.multi
    Workflow function that write state 'bid selected'
  • print_quotation(self)
    @api.multi
  • wkf_action_cancel(self)
    @api.multi
  • wkf_bid_received(self)
    @api.multi
  • wkf_draft_po(self)
    @api.multi
  • wkf_send_rfq(self)
    @api.multi

New fields (0)

No new fields.

Public methods (1)
  • onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, state='draftpo', context=None)
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_rfq_bid_workflow
VERSION
VERSION 0.3.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Camptocamp
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Camptocamp
COMMITTERS
COMMITTERSStéphane Bidoul, Yannick Vaucher, Alexandre Fayolle, Leonardo Pistone, OCA Transbot, oca-travis, Weblate
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:11:26
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/server-tools:
    - web_context_tunnel
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
This module improves the standard Purchase module.
==================================================
In standard, RFQs, Bids and PO are all the same object.  The purchase workflow
has been improved with a new 'Draft PO' state to clearly differentiate the
RFQ->Bid workflow and the PO workflow. A type field has also been added to
identify if a document is of type 'rfq' or 'purchase'. This is particularly
useful for canceled state and for datawarehouse.

The 'Requests for Quotation' menu entry shows only documents of type 'rfq' and
the new documents are created in state 'Draft RFQ'. Those documents have lines
with a price, by default, set to 0; it will have to be encoded when the bid is
received. The state 'Bid Received' has been renamed 'Bid Encoded'. This clearly
indicates that the price has been filled in. The bid received date will be
requested when moving to that state.

The 'Purchase Orders' menu entry shows only documents of type 'purchase' and
the new documents are created in state 'Draft PO'.

The logged messages have been improved to notify users at the state changes and
with the right naming.


In the scope of international transactions, some fields have been added:
 - Consignee: the person to whom the shipment is to be delivered
 - Incoterms Place: the standard incoterms field specifies the incoterms rule
   that applies. This field allows to name the place where the goods will be
   available

TODO: describe onchange picking type.

Note: for running the tests, the python package nose is required. It is not
listed as an external dependency because it is not needed in production.

Code Analysis

Views touched (7)
XML IDNameModelTypeStatus
action_modal_bid_date action.modal purchase.action_modal.datetime form New
action_modal_cancel_reason action.modal purchase.action_modal.cancel_reason form New
po_line_onchange_form purchase.order.line field Inherits purchase.purchase_order_line_form
view_purchase_cancel_reason_form Purchase Cancel Reason purchase.cancel_reason form New
view_purchase_cancel_reason_tree Purchase Cancel Reasons purchase.cancel_reason tree New
view_purchase_order_form purchase.order.form.inherit purchase.order xpath Inherits purchase.purchase_order_form
view_purchase_order_invoice_form purchase.order.form.invoice.inherit purchase.order xpath Inherits purchase.purchase_order_2_stock_picking
Models touched (7)

New fields (0)

No new fields.

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

New fields (1)
  • reason_id Many2one → purchase.cancel_reason
    required=True args: 'purchase.cancel_reason', 'Reason for Cancellation'
Public methods (0)

No public methods.

New fields (1)
  • datetime Datetime
    args: 'Date'
Public methods (0)

No public methods.

New fields (3)
  • name Char
    required=True size=64 translate=True args: 'Reason'
  • nounlink Boolean
    args: 'No unlink'
  • type Selection
    required=True args: [('rfq', 'RFQ/Bid'), ('purchase', 'Purchase Order')], 'Type'
Public methods (1)
  • unlink(self)
    @api.one
    Prevent to unlink records that are used in the code

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (5)
  • cancel_reason_id Many2one → purchase.cancel_reason
    readonly=True args: 'purchase.cancel_reason', 'Reason for Cancellation'
  • currency_id Many2one → res.currency
    readonly=True required=True states=STATES args: 'res.currency', 'Currency'
  • incoterm_address Char
    help='Incoterms Place of Delivery. International Commercial Terms are a series of predefined commercial terms used in international transactions.' args: 'Incoterms Place'
  • pricelist_id Many2one → product.pricelist
    help='The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities.' readonly=True required=True states=STATES args: 'product.pricelist', 'Pricelist'
  • type Selection
    default=_default_type readonly=True required=True args: TYPE_SELECTION, 'Type'
Public methods (12)
  • action_cancel(self)
    @api.multi
    Ask a cancel reason
  • action_cancel_ok(self)
    @api.multi
  • bid_received(self)
    @api.multi
  • bid_received_ok(self)
    @api.multi
  • copy(self, default=None)
    @api.one
  • create(self, values)
    @api.model
  • po_tender_requisition_selected(self)
    @api.multi
    Workflow function that write state 'bid selected'
  • print_quotation(self)
    @api.multi
  • wkf_action_cancel(self)
    @api.multi
  • wkf_bid_received(self)
    @api.multi
  • wkf_draft_po(self)
    @api.multi
  • wkf_send_rfq(self)
    @api.multi

New fields (0)

No new fields.

Public methods (1)
  • onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, state='draftpo', context=None)