Odoo销售订单自动化:自动生成并验证DC与发票方案咨询
Got it, let's tackle this problem step by step. Your goal is to automate the creation and validation of DC (Delivery Confirmation/Order) and invoices right after a sales order is closed, skipping all picking/packaging steps—without breaking the default Odoo flow. Here are two solid approaches depending on your technical comfort level:
First, a quick pre-check: Set your SIM card product type to Service (not Stockable Goods). This eliminates default picking/packaging steps entirely, which will make your automation work without inventory-related roadblocks (this is probably why your earlier inventory function calls failed—stockable products require available stock and proper picking workflows).
This is perfect if you want to avoid writing custom code and keep things lightweight, while leaving the default flow untouched.
Steps to set it up:
- Go to Settings > Technical > Automation > Automated Actions (you’ll need developer mode enabled).
- Create a new Automated Action with these details:
- Model:
sale.order(Sales Order) - Trigger: On update (when the sales order’s state changes)
- Condition: Add a domain filter to trigger only when the order is closed. Assuming "closed" means the order is marked as Done (adjust if your workflow uses a different state):
[('state', '=', 'done'), ('x_is_auto_processed', '=', False)] - Action Type: Execute Python Code
- Python Code: Paste this snippet (it creates/validates the DC and invoice, then marks the order as processed to avoid repeats):
# Create and validate Delivery Order (DC) picking = env['stock.picking'].create({ 'partner_id': record.partner_id.id, 'picking_type_id': env.ref('stock.picking_type_out').id, 'origin': record.name, 'move_ids_without_package': [ (0, 0, { 'product_id': line.product_id.id, 'product_uom_qty': line.product_uom_qty, 'product_uom': line.product_uom.id, 'location_id': env.ref('stock.stock_location_stock').id, 'location_dest_id': record.partner_id.property_stock_customer.id, }) for line in record.order_line ] }) picking.button_validate() # Create and validate Invoice invoice = record._create_invoices() invoice.action_post() # Mark order as processed to prevent duplicate runs record.write({'x_is_auto_processed': True})
- Model:
- Add the custom field: You’ll need a boolean field on
sale.ordercalledx_is_auto_processed(default value:False) to track if the automation has run. You can create this via Settings > Technical > Fields > Fields, or use the Studio app if you have it.
If you need to add complex logic (like integrating with other modules, conditional rules, or scaling later), a custom module is the way to go. This keeps your changes isolated and won’t interfere with Odoo’s default code.
Example Module Code:
- Create a new module (e.g.,
sale_auto_sim_process) with these files:
models/sale_order.py
from odoo import models, fields, api class SaleOrder(models.Model): _inherit = 'sale.order' x_is_auto_processed = fields.Boolean(string="Automated Process Completed", default=False) @api.multi def write(self, vals): # Run the super method first to apply the state change res = super(SaleOrder, self).write(vals) # Trigger automation only when the order is marked as Done and not processed yet if 'state' in vals and vals['state'] == 'done' and not self.x_is_auto_processed: self._process_sim_order() return res def _process_sim_order(self): self.ensure_one() # Create and validate Delivery Order (DC) picking_vals = { 'partner_id': self.partner_id.id, 'picking_type_id': self.env.ref('stock.picking_type_out').id, 'origin': self.name, 'move_ids_without_package': [], } for line in self.order_line: picking_vals['move_ids_without_package'].append((0, 0, { 'product_id': line.product_id.id, 'product_uom_qty': line.product_uom_qty, 'product_uom': line.product_uom.id, 'location_id': self.env.ref('stock.stock_location_stock').id, 'location_dest_id': self.partner_id.property_stock_customer.id, })) picking = self.env['stock.picking'].create(picking_vals) picking.button_validate() # Create and validate Invoice invoice = self._create_invoices() invoice.action_post() # Mark the order as processed self.write({'x_is_auto_processed': True})
__manifest__.py
{ 'name': 'Auto Process SIM Sales Orders', 'version': '1.0', 'author': 'Your Name', 'category': 'Sales', 'depends': ['sale', 'stock', 'account'], 'data': [], 'installable': True, 'auto_install': False, }
- Install the module in your Odoo instance, and it will automatically trigger whenever a sales order is marked as Done.
Key Notes:
- If you don’t actually need a DC (Delivery Order) for SIM cards (since they’re virtual), you can remove the entire picking creation/validation block and just generate the invoice directly.
- Double-check the
statevalue in your triggers—if your team uses a custom "Closed" state instead of Odoo’s defaultdone, adjust the condition accordingly. - Test this with a test order first to make sure it doesn’t break your existing workflows!
内容的提问来源于stack exchange,提问作者NinjaBat

