从Python代码创建发票 - xiaohao0576/odoo-doc GitHub Wiki

功能说明

从自定义的模块创建发票,账单,贷项发票,贷项账单等。

move_type的类型有以下几种

  • out_invoice代表发票
  • out_refund代表贷项发票,即退款单
  • in_invoice代表账单
  • in_refund代表借项账单,即退货单

字段复用

复用account.moveinvoice_origin字段,类型是char,放入自定义模型订单/订单行名称model._name

复用account.move.linesequence字段,类型是int,放入自定义模型订单行的id

这样在不创建任何字段的情况下,可以在发票/账单和原始的单据建立关联,然后使用_get_html_link()message_post在单据的备注说明中放入原始单据的超链接

创建发票的参考代码

_create_invoices查看源码

_prepare_invoice , 查看源码

_prepare_invoice_line, 查看源码

创建账单的参考代码

action_create_invoice , 查看源码

_prepare_invoice, 查看源码

_prepare_account_move_line , 查看源码

创建发票的示例代码

partners = []
for r in records:
    partners.append(r.x_studio_customer.id)
if len(set(partners)) > 1:
    raise UserError('所有订单的所有者必须相同才能创建发票')

action = env['ir.actions.actions']._for_xml_id('account.action_move_out_invoice_type')
form_view = [(env.ref('account.view_move_form').id, 'form')]
action['views'] = form_view
context = {
        'default_move_type': 'out_invoice',
}
action['context'] = context

# 创建单张发票数据
invoice_vals = {
    'ref': '',
    'move_type': 'out_invoice',
    'currency_id': env.user.company_id.currency_id.id,
    'partner_id': partners[0],
    'partner_shipping_id': partners[0],
    'invoice_origin': model._name,  # 使用模块名称,表明是从哪个模型创建的发票,再加上move_line.sequence作为ID,可以唯一定位证照办理
    'company_id': env.user.company_id.id,
    'invoice_line_ids': [],
}

# 创建发票行列表
invoice_line_vals = []
links = ""

# 创建发票明细行
for r in records:
    # 判断是否已经有发票
    amls = env['account.move.line'].sudo().search([('move_id.move_type','=','out_invoice'),('move_id.invoice_origin','=',model._name),('sequence','=',r.id)])
    if len(amls) > 0:
        raise UserError(f"ID:{r.id} {r.x_studio_id_name}[{r.x_studio_id_number}]已经创建了发票,无法重复创建!")
    else:
        # 订单信息收集
        products = {'一年签证':49, '半年签证':48,'三个月签证':50,'一个月签证':51}
        business_type = r.x_studio_business_type
        product_id = products[business_type]
        product = env['product.product'].browse(product_id)
        partner = r.x_studio_customer
        price_unit = r.x_studio_amount_received
        id_name = r.x_studio_id_name
        id_number = r.x_studio_id_number
        x_remark = r.x_remark or ''
        remark = f'{id_name},{id_number} {x_remark}'
        
        # 创建单行发票明细行
        invoice_line_res = {
            'display_type': 'product',
            'sequence': r.id, #复用sequence字段,建立发票行和证照办理的关联
            'name': remark,
            'product_id': product.id,
            'product_uom_id': product.uom_id.id,
            'quantity': 1,
            'price_unit': price_unit,
            'date_maturity': r.x_studio_date_field_2u1_1hrq6scm9 #签证到期日期
        }
        invoice_line_vals.append(Command.create(invoice_line_res))
        links += r._get_html_link() + ", "
# 创建发票
invoice_vals['invoice_line_ids'] += invoice_line_vals
move = env['account.move'].sudo().with_context(default_move_type='out_invoice').create(invoice_vals)
move.message_post(body= "发票创建自证照办理订单: " + links)
action['res_id'] = move.id