Differential tax, adding a new tax type

The differential tax scheme is a margin tax scheme used in Germany for second hand goods and arts.

For example:

selling one product

  • product selling price is 219
  • product cost price is 100

The invoice total is than 219.
The tax base is: selling price - cost price - tax amount, i.e.

  • tax base is 219 - 100 - 19 = 100
  • tax amount is 19 (19%)

My solution is to add a new differential tax type. Compared to the already present tax types (percentage, fixed) the differential tax type requires knowledge of cost price to be processed/computed. The Tax::_process_tax of a new module could be like:

    def _process_tax(self, unit_list_price, unit_cost_price):
        ret = {'differential_amount': Decimal(0)}
        if self.type == 'differential':
            margin = unit_list_price - unit_cost_price
            if margin > Decimal(0):
                base = margin / (1 + self.rate)
                amount = margin - base
                base = Decimal(0)
                amount = Decimal(0)
                'base': base,
                'amount': amount,
                'differential_amount': amount,
                'tax': self,
            ret.update(super(Tax, self)._process_tax(unit_list_price))
        return ret

The real challenge is the TaxableMixin [1]. The TaxableMixin::taxable_lines should consist of tuples with four elements: taxes, unit_price, quantity, cost_price and tax_date. The methods TaxableMixin::_compute_tax_line and TaxableMixin::_get_taxes [2] should be extended to handle the additional new attribute cost_price within the taxable_lines and a new differential_amount key from _process_tax (see code snippet above).

The challenge is to extend the TaxableMixin and all modules using it like account_invoice or sale . As extending modules is a not an issue, thanks to trytons magic. Extending a Mixin is not a straight forward task. The only solutions I’m aware of are to fork tryrton or apply a monke patch on Mixin. The Pool::register_mixin sounds promising, but it adds just a new Mixin to a model, as I understood.

Is there something I’ve missed? Is there any elegant solution to this Mixin issue?

Hi @srgdts,

Welcome to the forum!!

IIRC we have the same scheme for second hand goods in Spain. But also for travel agencies.

On both cases they only pay taxes for the profit they make.

We should probably find a common solution for all countries and your diferential tax type seems like a good starting point!

You can use register_mixin to extend all classes that are a subclass of TaxableMixin. This is the way to go to customize a generic class on a module avoiding forking and monkey patching.

Here is an example of the register_mixin

For me it is not a type of tax that must be created because it is the same tax as the usual one. But the base amount is different. So for me, it should be managed with a flag on the product telling that it is only the profit that should be used as base amount and improve TaxableMixin to allow to modify the base price (unit price for now) with the proper amount.

1 Like

The German differential tax is slightly varied from a usual one. The main difference is, the tax amount should not be visible on invoice. Instead, a legal notice should apply on the invoice, like this one: “Items on this invoice are sold according to the specific rules for the VAT margin scheme for second-hand goods.

Another difference is related to accounting. An account move on invoice posted requires at least four accounts. According to example prices from my first post [1] a sample account move:

                     debit   credit  Tax Line
receivable          219.00     0.00
tax                   0.00    19.00   ( 1 )     # 19% differential tax
revenue (VAT-free)    0.00   100.00   ( 0 )     # cost price
revenue (19% VAT)     0.00   100.00   ( 1 )     # tax base

For SKR03 [2] the corresponding accounts for the two revenue accounts are: 8191 and 8193 [3]. Since 01.07.2020 the tax rates changed and thereby the according accounts. The split of the revenue is requested by tax report.

Maybe there is some more convenient way to get this task done. But however from my point the Tax model is the right place to store the account information as already the field invoice_account does. And then a new tax type could be necessary. The assignation of the tax to product could be done using Product Accounting Categories.

There are some more pitfalls, constraints and exceptions regarding German differential tax scheme. For example:

  • It’s not permitted to apply differential tax beside other taxes on a single invoice
  • The art traders could apply the fixed rate of 30% of the list price as a tax base (on permit of a tax authority)

Yes, applying this scheme is pain in the neck. :face_with_symbols_over_mouth:

The question is, is this kind of taxation in some parts common to other countries, so it’s worth it to create some generic behavior?

1 Like

There is a legal notice field on taxes that is printed on reports. So this is just a mather of configuration.

The same applies for Spain of special regime of second hand goods.

IIRC this is not required on Tryton because you can use a diferent amount for the tax line than in the move line. So with just three lines you will be able.to set the correct values for tax reporting.

This is just creating a special tax with a fixed rate for art trades and use when required.

I’m not sure if we can manage like a normal tax. In this case the user will enter the prices with tax amounts included and the system should reverse compute the tax bases and amounts. Let me put an example:

  • I’ve bougth a table for 100€
  • I sell the table for 150€
  • The aplicable tax rate is 21%

My profit is 50€ so I have to pay the 21% of this profit as taxes. This means:

50/1,21 = 41,32€ is the tax base

41,32 x 0,21 = 8,68€ is the tax amount of the operation.

It is completely manageable as a normal tax because it is only the base that is different. So it is just a matter to determine the base.
The fact that you use VAT-included price does not change the computation but dealing with VAT-included price is the job of the POS not the invoice nor sale. Those documents deal with VAT-excluded price but similar computation can be done.

@pokoli, could you give me a hint how to do that.

My workflow now is: create a sale and quote it -> post an invoice. The post transition of invoice creates an account move and posts it.

You should override the method to compute the taxes on your custom module

How you determine the cost value for the line?

Already done. I thought, maybe there some functionality, some module already provides I’ve overseen.

The cost value is the return value of Product.cost_price_uom().

I’m aware that Product.cost_price is an “amount it costs to purchase or make the variant”. The usage of the Product.cost_price as the taxation cost price could lead to misunderstanding due the semantic difference between the both cost prices. The Product.cost_price is not necessarily equals to taxation cost price.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.