You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
class AccountTaxInvoice(models.Model):
_name = 'account.tax.invoice'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = '税务发票'
_rec_name = 'name'
name = fields.Char(string='发票编号', default='/')
date = fields.Date(string='开票日期', required=True, default=fields.Date.today())
note = fields.Text(string='备注')
invoice_type = fields.Selection([
('normal', '普票'),
('red', '专票'),
('tax', '电子发票'),
], string='发票类型', default='tax', required=True)
state = fields.Selection([
('draft', '草稿'),
('done', '完成'),
('deprecated', '作废'),
], string='状态', default='draft', copy=False, index=True, tracking=True)
move_id = fields.Many2one('account.move', string='关联单据', required=True)
purchaser_id = fields.Many2one('res.partner', string='购买方', required=True)
seller_id = fields.Many2one('res.partner', string='销售方', required=True)
purchaser_vat = fields.Char(related='purchaser_id.vat', string='购买方税号', readonly=True, store=True)
seller_vat = fields.Char(related='seller_id.vat', string='销售方税号', readonly=True, store=True)
company_id = fields.Many2one('res.company', string='公司', default=lambda self: self.env.company)
currency_id = fields.Many2one('res.currency', string='币种', default=lambda self: self.env.company.currency_id)
line_ids = fields.One2many('account.tax.invoice.line', 'invoice_line_id', string='发票行')
# 计算字段
amount = fields.Monetary(string='未税金额', compute='_compute_amount_total', store=True)
amount_tax = fields.Monetary(string='税额', compute='_compute_amount_total', store=True)
amount_total = fields.Monetary(string='含税总计', compute='_compute_amount_total', store=True)
@api.depends('line_ids', 'line_ids.amount', 'line_ids.amount_tax')
def _compute_amount_total(self):
for rec in self:
if rec.line_ids:
amount = sum(rec.line_ids.mapped('amount'))
amount_tax = sum(rec.line_ids.mapped('amount_tax'))
rec.update({
'amount': amount,
'amount_tax': amount_tax,
'amount_total': amount + amount_tax
})
def confirm(self):
if set(self.mapped('state')) != {'draft'}:
raise ValidationError('非草稿状态无法确认完成开票!')
self.write({'state': 'done'})
def deprecated(self):
"""多实例方法:废弃已完成的税务发票"""
if set(self.mapped('state')) != {'done'}:
raise ValidationError('无法废弃非已完成状态的发票!')
return self.write({'state': 'deprecated'})
def reset_to_draft(self):
"""多实例方法:重置为草稿"""
if set(self.mapped('state')) != {'deprecated'}:
raise ValidationError('无法重置非作废状态的发票!')
return self.write({'state': 'draft'})
def unlink(self):
for rec in self:
if rec.state not in ['draft', 'deprecated']:
raise ValidationError('非草稿或作废状态的税票无法删除!')
return super(AccountTaxInvoice, self).unlink()
class AccountTaxInvoiceLine(models.Model):
_name = 'account.tax.invoice.line'
_description = '税务发票行'
# 基础字段
sequence = fields.Integer(string='序列')
specification = fields.Char(string='规格')
quantity = fields.Float(string='数量', required=True, digits=(16, 4))
price_unit = fields.Float(string='单价', required=True, digits=(16, 4))
# 关系字段
invoice_line_id = fields.Many2one('account.tax.invoice', string='税务发票', required=True, ondelete='cascade')
account_id = fields.Many2one('account.account', string='科目', required=True)
product_id = fields.Many2one('product.product', string='产品', required=True)
uom_id = fields.Many2one('uom.uom', string='单位')
tax_id = fields.Many2one('account.tax', string='税率', required=True)
# 关联字段
currency_id = fields.Many2one(related='invoice_line_id.currency_id', string='币种')
# 计算字段
amount = fields.Monetary(string='金额')
amount_tax = fields.Monetary(string='税额')
amount_total = fields.Monetary(string='含税小计')