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.
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.
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.
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>
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
qtyinstead ofproduct_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

