[IMP] account: improve usability of taxes for goods/services
Help search taxes more easily by adding an applicability field stating that the tax should be used only on goods or on services. If not set, can be used anywhere.
This commit is contained in:
@@ -45,8 +45,9 @@ class AccountTax(models.Model):
|
||||
return self.env['account.tax.group'].search([], limit=1)
|
||||
|
||||
name = fields.Char(string='Tax Name', required=True)
|
||||
type_tax_use = fields.Selection(TYPE_TAX_USE, string='Tax Scope', required=True, default="sale",
|
||||
type_tax_use = fields.Selection(TYPE_TAX_USE, string='Tax Type', required=True, default="sale",
|
||||
help="Determines where the tax is selectable. Note : 'None' means a tax can't be used by itself, however it can still be used in a group. 'adjustment' is used to perform tax adjustment.")
|
||||
tax_scope = fields.Selection([('service', 'Services'), ('consu', 'Goods')], string="Tax Scope", help="Restrict the use of taxes to a type of product.")
|
||||
amount_type = fields.Selection(default='percent', string="Tax Computation", required=True,
|
||||
selection=[('group', 'Group of Taxes'), ('fixed', 'Fixed'), ('percent', 'Percentage of Price'), ('division', 'Percentage of Price Tax Included')],
|
||||
help="""
|
||||
@@ -93,7 +94,7 @@ class AccountTax(models.Model):
|
||||
country_id = fields.Many2one(string='Country', comodel_name='res.country', related='company_id.country_id', help="Technical field used to restrict the domain of account tags for tax repartition lines created for this tax.")
|
||||
|
||||
_sql_constraints = [
|
||||
('name_company_uniq', 'unique(name, company_id, type_tax_use)', 'Tax names must be unique !'),
|
||||
('name_company_uniq', 'unique(name, company_id, type_tax_use, tax_scope)', 'Tax names must be unique !'),
|
||||
]
|
||||
|
||||
@api.model
|
||||
@@ -152,7 +153,9 @@ class AccountTax(models.Model):
|
||||
if not tax._check_m2m_recursion('children_tax_ids'):
|
||||
raise ValidationError(_("Recursion found for tax '%s'.") % (tax.name,))
|
||||
if not all(child.type_tax_use in ('none', tax.type_tax_use) for child in tax.children_tax_ids):
|
||||
raise ValidationError(_('The application scope of taxes in a group must be either the same as the group or left empty.'))\
|
||||
raise ValidationError(_('The application scope of taxes in a group must be either the same as the group or left empty.'))
|
||||
if not all(child.tax_scope == tax.tax_scope for child in tax.children_tax_ids):
|
||||
raise ValidationError(_('The application scope of taxes in a group must be either the same as the group or left empty.'))
|
||||
|
||||
@api.constrains('company_id')
|
||||
def _check_company_consistency(self):
|
||||
@@ -185,10 +188,17 @@ class AccountTax(models.Model):
|
||||
return super(AccountTax, self).copy(default=default)
|
||||
|
||||
def name_get(self):
|
||||
if not self._context.get('append_type_to_tax_name'):
|
||||
return super(AccountTax, self).name_get()
|
||||
tax_type = dict(self._fields['type_tax_use']._description_selection(self.env))
|
||||
return [(tax.id, '%s (%s)' % (tax.name, tax_type.get(tax.type_tax_use))) for tax in self]
|
||||
name_list = []
|
||||
type_tax_use = dict(self._fields['type_tax_use']._description_selection(self.env))
|
||||
tax_scope = dict(self._fields['tax_scope']._description_selection(self.env))
|
||||
for record in self:
|
||||
name = record.name
|
||||
if self._context.get('append_type_to_tax_name'):
|
||||
name += ' (%s)' % type_tax_use.get(record.type_tax_use)
|
||||
if record.tax_scope:
|
||||
name += ' (%s)' % tax_scope.get(record.tax_scope)
|
||||
name_list += [(record.id, name)]
|
||||
return name_list
|
||||
|
||||
@api.model
|
||||
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
|
||||
|
||||
@@ -832,8 +832,9 @@ class AccountTaxTemplate(models.Model):
|
||||
chart_template_id = fields.Many2one('account.chart.template', string='Chart Template', required=True)
|
||||
|
||||
name = fields.Char(string='Tax Name', required=True)
|
||||
type_tax_use = fields.Selection(TYPE_TAX_USE, string='Tax Scope', required=True, default="sale",
|
||||
type_tax_use = fields.Selection(TYPE_TAX_USE, string='Tax Type', required=True, default="sale",
|
||||
help="Determines where the tax is selectable. Note : 'None' means a tax can't be used by itself, however it can still be used in a group.")
|
||||
tax_scope = fields.Selection([('service', 'Service'), ('consu', 'Consumable')], help="Restrict the use of taxes to a type of product.")
|
||||
amount_type = fields.Selection(default='percent', string="Tax Computation", required=True,
|
||||
selection=[('group', 'Group of Taxes'), ('fixed', 'Fixed'), ('percent', 'Percentage of Price'), ('division', 'Percentage of Price Tax Included')])
|
||||
active = fields.Boolean(default=True, help="Set active to false to hide the tax without removing it.")
|
||||
@@ -863,7 +864,7 @@ class AccountTaxTemplate(models.Model):
|
||||
help="Account used to transition the tax amount for cash basis taxes. It will contain the tax amount as long as the original invoice has not been reconciled ; at reconciliation, this amount cancelled on this account and put on the regular tax account.")
|
||||
|
||||
_sql_constraints = [
|
||||
('name_company_uniq', 'unique(name, type_tax_use, chart_template_id)', 'Tax names must be unique !'),
|
||||
('name_company_uniq', 'unique(name, type_tax_use, tax_scope, chart_template_id)', 'Tax names must be unique !'),
|
||||
]
|
||||
|
||||
@api.depends('name', 'description')
|
||||
@@ -886,6 +887,7 @@ class AccountTaxTemplate(models.Model):
|
||||
val = {
|
||||
'name': self.name,
|
||||
'type_tax_use': self.type_tax_use,
|
||||
'tax_scope': self.tax_scope,
|
||||
'amount_type': self.amount_type,
|
||||
'active': self.active,
|
||||
'company_id': company.id,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="type_tax_use"/>
|
||||
<field name="tax_scope"/>
|
||||
<field name="description"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<field name="active" widget="boolean_toggle"/>
|
||||
@@ -52,6 +53,7 @@
|
||||
<kanban class="o_kanban_mobile">
|
||||
<field name="name"/>
|
||||
<field name="type_tax_use"/>
|
||||
<field name="tax_scope"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
|
||||
@@ -61,6 +63,7 @@
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<span class="badge badge-pill"><t t-esc="record.type_tax_use.value"/></span>
|
||||
<span class="badge badge-pill"><t t-esc="record.tax_scope.value"/></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -80,11 +83,15 @@
|
||||
<filter string="Sale" name="sale" domain="[('type_tax_use','=','sale')]" />
|
||||
<filter string="Purchase" name="purchase" domain="[('type_tax_use','=','purchase')]" />
|
||||
<separator/>
|
||||
<filter string="Services" name="service" domain="[('tax_scope','=','service')]" />
|
||||
<filter string="Goods" name="goods" domain="[('tax_scope','=','consu')]" />
|
||||
<separator/>
|
||||
<filter name="active" string="Active" domain="[('active','=',True)]" help="Show active taxes"/>
|
||||
<filter name="inactive" string="Inactive" domain="[('active','=',False)]" help="Show inactive taxes"/>
|
||||
<group string="Group By">
|
||||
<filter string="Company" name="company" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
|
||||
<filter string="Tax Application" name="taxapp" domain="[]" context="{'group_by':'type_tax_use'}"/>
|
||||
<filter string="Tax Type" name="taxapp" domain="[]" context="{'group_by':'type_tax_use'}"/>
|
||||
<filter string="Tax Scope" name="taxapp" domain="[]" context="{'group_by':'tax_scope'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
@@ -115,6 +122,7 @@
|
||||
</group>
|
||||
<group>
|
||||
<field name="type_tax_use"/>
|
||||
<field name="tax_scope"/>
|
||||
<label for="amount" attrs="{'invisible':[('amount_type','not in', ('fixed', 'percent', 'division'))]}"/>
|
||||
<div attrs="{'invisible':[('amount_type','not in', ('fixed', 'percent', 'division'))]}">
|
||||
<field name="amount" class="oe_inline"/>
|
||||
|
||||
@@ -70,10 +70,10 @@
|
||||
</page>
|
||||
</page>
|
||||
<xpath expr="//div[@name='pricing']" position="after">
|
||||
<field name="taxes_id" widget="many2many_tags" context="{'default_type_tax_use':'sale'}"/>
|
||||
<field name="taxes_id" widget="many2many_tags" context="{'default_type_tax_use':'sale', 'search_default_sale': 1, 'search_default_service': type == 'service', 'search_default_goods': type == 'consu'}"/>
|
||||
</xpath>
|
||||
<group name="bill" position="inside">
|
||||
<field name="supplier_taxes_id" widget="many2many_tags" context="{'default_type_tax_use':'purchase'}"/>
|
||||
<field name="supplier_taxes_id" widget="many2many_tags" context="{'default_type_tax_use':'purchase', 'search_default_purchase': 1, 'search_default_service': type == 'service', 'search_default_goods': type == 'consu'}"/>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
Reference in New Issue
Block a user