This question has been flagged
2610 Views
In France, The puzzle: The formula with an alcoholic drink... 
In the case of a 10 € formula including a slice of pizza with a beer. 
Since beer is an alcoholic beverage (no joke), it does not have the same VAT rate as pizza. 
We can not assign the same rate to the whole formula. 

So how to calculate the amount HT of a formula with products that do not have the same VAT rate? 
This is where it gets complicated, in the case of a formula including alcoholic beverages, you need to break down the share of each product within the formula. 

First step: 

Establish the report of the price WITH TAXES to the map of your products in the formula Let's imagine that the pizza has an off-formula value of 8 € and 3 € for beer. 
Which gives a total value of 11 € to both products. 

So we divide the non-formula price of each product by the sum of the two products to determine the share of each product in the formula. 
For pizza = Price excluding pizza formula / Total price = 8 / (8 + 3) = 0.72 = 0.72 x 100 = 72% 
We therefore know that pizza represents 72% of the formula. 

So the beer represents (100 - 72 = 28) 28% of the formula. 

Now that we have determined the share of each product in the formula, we can calculate the price of each product in the TTC formula. 

Second step: 

Calculate the price including tax of each product within the formula according to their share Price inclusive of pizza in the formula = Price of the formula WITH TAXES / Share of the pizza within the formula = 
10 x 0.72 = 7.20 € 
All tax included Price inclusive of beer in the formula = Price of the formula TTC / Share of the beer within the formula = 10 x 0, 28 = 2.80 € 

All tax included Now that we have the prices inclusive of each product distributed in the formula, it remains only to calculate the price of each product HT to have the price HT of the formula. 

Third step: 

Calculate the price of both products The VAT rate applicable for pizza is 10%. 
As beer is an alcoholic beverage, the applicable VAT rate is 20%. Price of the pizza = price incl. Of the pizza / (1 + VAT rate) = 7.20 / (1 + 0.10) = 6.54 € HT Price of the beer = Price including VAT of the beer / (1 + VAT rate) = 2.80 / (1 + 0.20) = 2.33 € HT 

So the price without taxes of the formula is 6.54 + 2.33 = 8.87 € HT


I would therefore like to extend the methods of calculating taxes on specific products for example 'is_pack' that can accept 2 VAT rates and 2 percentage of prices in order to perform the calculation explained above.
Can you help me ?

i Tried this : 

class AccountTaxRepartition(models.Model):
    _inherit = "account.tax"

    def _compute_amount(self, base_amount, price_unit, quantity=1.0, product=None, partner=None):

        self.ensure_one()
        if product:
            if product.compound:
                print("Product > ", product)
                print(self)
                if self.name == "TVA 10,0%":
                    print('TVA 10')
                    price_percent = (quantity * price_unit) * product.price_percent_1 / 100
                    print(price_percent)
                    tva = price_percent / (1 + 0.10)
                    return price_percent - tva

                if self.name == "TVA 20,0%":
                    print('TVA 20')
                    price_percent = (quantity * price_unit) * product.price_percent_2 / 100
                    print(price_percent)
                    tva = price_percent / (1 + 0.20)
                    return price_percent - tva

        if self.amount_type == 'fixed':
            if base_amount:
                return math.copysign(quantity, base_amount) * self.amount
            else:
                return quantity * self.amount
        if (self.amount_type == 'percent' and not self.price_include) or (self.amount_type == 'division' and self.price_include):
            return base_amount * self.amount / 100
        if self.amount_type == 'percent' and self.price_include:
            return base_amount - (base_amount / (1 + self.amount / 100))
        if self.amount_type == 'division' and not self.price_include:
            return base_amount / (1 - self.amount / 100) - base_amount

    @api.multi
    def compute_all(self, price_unit, currency=None, quantity=1.0, product=None, partner=None):

        if len(self) == 0:
            company_id = self.env.user.company_id
        else:
            company_id = self[0].company_id
        if not currency:
            currency = company_id.currency_id
        taxes = []
        prec = currency.decimal_places


        round_tax = False if company_id.tax_calculation_rounding_method == 'round_globally' else True
        round_total = True
        if 'round' in self.env.context:
            round_tax = bool(self.env.context['round'])
            round_total = bool(self.env.context['round'])

        if not round_tax:
            prec += 5

        base_values = self.env.context.get('base_values')
        if not base_values:
            total_excluded = total_included = base = round(price_unit * quantity, prec)
        else:
            total_excluded, total_included, base = base_values


        for tax in self.sorted(key=lambda r: r.sequence):
            if tax.amount_type == 'group':
                children = tax.children_tax_ids.with_context(base_values=(total_excluded, total_included, base))
                ret = children.compute_all(price_unit, currency, quantity, product, partner)
                total_excluded = ret['total_excluded']
                base = ret['base'] if tax.include_base_amount else base
                total_included = ret['total_included']
                tax_amount = total_included - total_excluded
                taxes += ret['taxes']
                continue

            tax_amount = tax._compute_amount(base, price_unit, quantity, product, partner)
            if not round_tax:
                tax_amount = round(tax_amount, prec)
            else:
                tax_amount = currency.round(tax_amount)

            if tax.price_include:
                total_excluded -= tax_amount
                base -= tax_amount
            else:
                total_included += tax_amount

            if product:
                if product.compound and tax.name == "TVA 10,0%":
                    print("Compute all TVA 10%")
                    base = (quantity * price_unit) * product.price_percent_1 / 100
                if product.compound and tax.name == "TVA 20,0%":
                    print("Compute all TVA 20%")
                    base = (quantity * price_unit) * product.price_percent_2 / 100

            tax_base = base

            if tax.include_base_amount:
                base += tax_amount

            taxes.append({
                'id': tax.id,
                'name': tax.with_context(**{'lang': partner.lang} if partner else {}).name,
                'amount': tax_amount,
                'base': tax_base,
                'sequence': tax.sequence,
                'account_id': tax.account_id.id,
                'refund_account_id': tax.refund_account_id.id,
                'analytic': tax.analytic,
                'price_include': tax.price_include,
            })

        return {
            'taxes': sorted(taxes, key=lambda k: k['sequence']),
            'total_excluded': currency.round(total_excluded) if round_total else total_excluded,
            'total_included': currency.round(total_included) if round_total else total_included,
            'base': base,
        }




it works for a billing or quote but not on the POS


on the pos I can not quite calculate in the models.Orderline methods : 

_compute_all, compute_all or get_all_prices
Avatar
Discard