You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo V11:基于已审批报价单创建销售订单行时筛选产品

Got it, let's break down how to create a sales order from your approved quotation, including pulling over all its line items, using your existing model structure. I’m assuming you’re working with Odoo here since the field types (One2many, Many2one) align with its ORM.

Step 1: Add a Quotation Reference Field to the Sales Order Model

First, we need to link the sales order to your approved quotation. Add this field to your sale.order model (you can inherit the base Odoo model or use your custom one):

from odoo import api, models, fields, _
from odoo.exceptions import UserError

class SaleOrder(models.Model):
    _inherit = 'sale.order'  # Or _name if it's your custom sales order model

    quotation_id = fields.Many2one(
        'quotation', 
        string='Source Approved Quotation',
        domain=[('state', '=', 'approved')],  # Restrict to only approved quotes
        help="Select an approved quotation to copy line items from"
    )

Note: Make sure your quotation model has a state field that tracks approval status (e.g., 'draft', 'approved', 'canceled') to use that domain.

Step 2: Add an On-Change Method to Auto-Populate Order Lines

Next, write an on-change method that copies all line items from the selected quotation to the sales order when the user picks a quotation:

@api.onchange('quotation_id')
def _onchange_quotation_id(self):
    if self.quotation_id:
        # Clear existing order lines first to avoid duplicates
        self.order_line = [(5, 0, 0)]
        # Loop through each quote line and create a corresponding sales order line
        for quote_line in self.quotation_id.quote_line:
            self.order_line += [(0, 0, {
                'product_id': quote_line.product_id.id,
                'product_uom_qty': quote_line.product_uom_qty,  # Adjust to match your quote line's quantity field
                'price_unit': quote_line.price_unit,  # Adjust to match your quote line's price field
                # Add any other fields you need to copy (e.g., product_uom, description)
            })]

Tweak the field names here to match what’s actually present on your quotation.line model—add or remove fields as needed.

Step 3: Update the Sales Order Form View

Add the new quotation_id field to your sales order form so users can select the source quotation. Here’s the XML for inheriting Odoo’s default sales order view:

<odoo>
    <record id="sale_order_form_inherit_quotation_ref" model="ir.ui.view">
        <field name="name">sale.order.form.inherit.quotation.ref</field>
        <field name="model">sale.order</field>
        <field name="inherit_id" ref="sale.view_order_form"/>
        <field name="arch" type="xml">
            <!-- Add the field after the partner field -->
            <field name="partner_id" position="after">
                <field name="quotation_id"/>
            </field>
        </field>
    </record>
</odoo>
Step 4: Optional - Add a "Create Sales Order" Button to the Quotation

For a smoother workflow, you can add a button directly on the quotation form to create a sales order in one click. Here’s how:

First, add the method to your quotation model:

class Quotation(models.Model):
    _inherit = 'quotation'  # Or _name if it's your custom model

    def action_create_sale_order(self):
        self.ensure_one()
        # Ensure the quotation is approved before creating the order
        if self.state != 'approved':
            raise UserError(_("Only approved quotations can be converted to sales orders."))
        
        # Create the sales order header
        sale_order = self.env['sale.order'].create({
            'partner_id': self.partner_id.id,  # Adjust to match your quotation's partner field
            'quotation_id': self.id,
            # Add other required sales order fields (e.g., date_order, pricelist_id)
        })

        # Create the sales order lines from the quotation lines
        for line in self.quote_line:
            self.env['sale.order.line'].create({
                'order_id': sale_order.id,
                'product_id': line.product_id.id,
                'product_uom_qty': line.product_uom_qty,
                'price_unit': line.price_unit,
            })

        # Open the newly created sales order form
        return {
            'type': 'ir.actions.act_window',
            'name': _('Sales Order'),
            'res_model': 'sale.order',
            'res_id': sale_order.id,
            'view_mode': 'form',
            'target': 'current',
        }

Then add the button to your quotation form view:

<odoo>
    <record id="quotation_form_inherit_create_order" model="ir.ui.view">
        <field name="name">quotation.form.inherit.create.order</field>
        <field name="model">quotation</field>
        <field name="inherit_id" ref="your_module.view_quotation_form"/>  <!-- Replace with your base quotation view ID -->
        <field name="arch" type="xml">
            <!-- Add the button after existing action buttons -->
            <button name="action_draft" position="after">
                <button 
                    name="action_create_sale_order" 
                    string="Create Sales Order" 
                    type="object" 
                    states="approved"
                    class="btn-primary"
                />
            </button>
        </field>
    </record>
</odoo>

Quick Notes to Keep in Mind

  • Double-check all field names match your actual model definitions—if your quotation line uses qty instead of product_uom_qty, adjust accordingly.
  • If your sales order requires additional mandatory fields (like payment terms, delivery address), make sure to populate them in the create() method.
  • Test the workflow end-to-end to ensure line items copy correctly and only approved quotations are used.

内容的提问来源于stack exchange,提问作者Lekha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:37:01