Skip to Content
Menu
This question has been flagged

For invoice drafts, we created a field called x_studio_saleorder_template (Many2One) in Odoo 17. When this field change (chooses a sale.order.template), we just want to add all lines one by one to the new invoice draft by automation trigger onchange. Here is the code:



def add_template_lines(record):
    template_id = record.x_studio_saleorder_template.id
    if not template_id:
        return
    
    template = env['sale.order.template'].browse(template_id)
    if not template.exists():
        return
    
    if record.state != 'draft':
        return
    
    for line in template.sale_order_template_line_ids:
        if line.display_type == 'line_section':
            new_line_vals = {
                'move_id': record.id,
                'display_type': 'line_section',
                'name': line.name,
            }
            record.write({
                'invoice_line_ids': [(0, 0, new_line_vals)],
            })
            continue
            
        if line.display_type == 'line_note':
            new_line_vals = {
                'move_id': record.id,
                'display_type': 'line_note',
                'name': line.name,
            }
            record.write({
                'invoice_line_ids': [(0, 0, new_line_vals)],
            })
            continue
        
        if not line.product_id:
            continue
        
        new_line_vals = {
            'move_id': record.id,
            'product_id': line.product_id.id,
            'name': line.display_name or line.product_id.name,
            'quantity': line.product_uom_qty or 1.0,
            'product_uom_id': line.product_uom_id.id,
            'price_unit': 0.0,
        }
        record.write({
            'invoice_line_ids': [(0, 0, new_line_vals)],
        })
        
    record.write({
        'x_studio_saleorder_template': False,
    })
    
    action = {
        'type': 'ir.actions.act_window',
        'res_model': 'account.move',
        'view_mode': 'form',
        'res_id': record.id,
        'target': 'current',
    }
    return action
            
add_template_lines(record)

But there are some problems i can't find any solution:

  • Actually all lines will be added to the invoice draft, with following problems:
    • product_id and product_uom_id are always False after record.write() inside the line (checked with log). Checking the line.product_id.id and line.product_uom_id.id are correct!
      • Fun fact: invoice line add the right account number of the product, but not the product_id itself (why ever).
    • quantity is always 1 after record.write(); line.product_uom_qty is correct number.
    • name is always perfect!
      • line_section and line_note too.
  • After adding the lines, i try to reload the page, but the lines are not visible until i force a reload with F5.
  • Because the invoice is at draft, the record.id is called "NewId9999" not 9999.
    • Because of this i can't use record.id for move_id in combination with record.create() instead of record.write()
    • I tried some other solutions with save to db etc. but didn't worked out well.

I wanted to use automation instead of creating the own module, but it's possible too for sure, because it's self hosted.

Thanks for any help!

Avatar
Discard
Author Best Answer

Update on my site: This new code works except one thing i can't fix: After the reload i still don't see the list until i click on manual save, or refresh browser with F5!?

# Available variables:
#  - env: environment on which the action is triggered
#  - model: model of the record on which the action is triggered; is a void recordset
#  - record: record on which the action is triggered; may be void
#  - records: recordset of all records on which the action is triggered in multi-mode; may be void
#  - time, datetime, dateutil, timezone: useful Python libraries
#  - float_compare: utility function to compare floats based on specific precision
#  - log: log(message, level='info'): logging function to record debug information in ir.logging table
#  - _logger: _logger.info(message): logger to emit messages in server logs
#  - UserError: exception class for raising user-facing warning messages
#  - Command: x2many commands namespace
# To return an action, assign: action = {...}

def add_template_lines(record):
    template_id = record.x_studio_saleorder_template.id
    if not template_id or record.state != 'draft':
        return
   
    template = env['sale.order.template'].browse(template_id)
    if not template.exists():
        return
   
    new_lines = []

    for line in template.sale_order_template_line_ids:
        if line.display_type in ('line_section', 'line_note'):
            new_line_vals = {
                'move_id': record._origin.id,
                'display_type': line.display_type,
                'name': line.name,
            }
        else:
            if not line.product_id:
                continue
            new_line_vals = {
                'move_id': record._origin.id,
                'product_id': line.product_id.id,
                'name': line.display_name or line.product_id.name,
                'quantity': line.product_uom_qty or 1.0,
                'product_uom_id': line.product_uom_id.id,
                'price_unit': line.product_id.list_price or 0.0,
            }
        new_lines.append(new_line_vals)

    if new_lines:
        env['account.move.line'].create(new_lines)
       
    record.write({'x_studio_saleorder_template': False})

    #action = {
    #    'type': 'ir.actions.client',
    #    'tag': 'pxa_account_move_save_reload_view',
    #    'params': {
    #        'record_id': record.id,
    #    },
    #}
    action = {
        'type': 'ir.actions.client',
        'tag': 'reload',
    }
    return action

add_template_lines(record)


Avatar
Discard
Related Posts Replies Views Activity
7
Dec 24
7545
0
Jul 24
1008
3
Jun 24
2315
0
May 24
1372
0
Apr 24
23