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

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).


1. No-Code Approach: Use Odoo's Automated Actions

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:

  1. Go to Settings > Technical > Automation > Automated Actions (you’ll need developer mode enabled).
  2. 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})
      
  3. Add the custom field: You’ll need a boolean field on sale.order called x_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.

2. Custom Module Approach (More Flexible)

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:

  1. 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,
}
  1. 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 state value in your triggers—if your team uses a custom "Closed" state instead of Odoo’s default done, adjust the condition accordingly.
  • Test this with a test order first to make sure it doesn’t break your existing workflows!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:41:57