[MERGE] forward port branch saas-11.2 up to cd34fda4ba3
This commit is contained in:
@@ -19,4 +19,7 @@
|
||||
'report/sale_coupon_report_templates.xml',
|
||||
'data/sale_coupon_email_data.xml',
|
||||
],
|
||||
'demo': [
|
||||
'data/sale_coupon_demo.xml',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="10_percent_auto_applied" model="sale.coupon.program">
|
||||
<field name="name">Code for 10% on orders</field>
|
||||
<field name="promo_code_usage">code_needed</field>
|
||||
<field name="promo_code">10pc</field>
|
||||
<field name="discount_apply_on">on_order</field>
|
||||
<field name="discount_type">percentage</field>
|
||||
<field name="discount_percentage">10.0</field>
|
||||
<field name="program_type">promotion_program</field>
|
||||
</record>
|
||||
|
||||
<record id="3_ipad_plus_1_free" model="sale.coupon.program">
|
||||
<field name="name">Buy 3 ipads, get one for free</field>
|
||||
<field name="promo_code_usage">no_code_needed</field>
|
||||
<field name="discount_apply_on">on_order</field>
|
||||
<field name="reward_type">product</field>
|
||||
<field name="program_type">promotion_program</field>
|
||||
<field name="reward_product_id" ref="product.product_product_6"></field>
|
||||
<field name="rule_min_quantity">3</field>
|
||||
<field name="rule_products_domain">[["name","ilike","ipad mini"]]</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -53,15 +53,12 @@ class SaleCoupon(models.Model):
|
||||
def _check_coupon_code(self, order):
|
||||
message = {}
|
||||
applicable_programs = order._get_applicable_programs()
|
||||
amount_total = order.amount_untaxed + order.reward_amount
|
||||
if self.program_id.rule_minimum_amount_tax_inclusion == 'tax_included':
|
||||
amount_total += order.amount_tax
|
||||
if self.state in ('used', 'expired') or \
|
||||
(self.expiration_date and self.expiration_date < order.date_order):
|
||||
message = {'error': _('This coupon %s has been used or is expired.') % (self.code)}
|
||||
elif self.state == 'reserved':
|
||||
message = {'error': _('This coupon %s exists but the origin sales order is not validated yet.') % (self.code)}
|
||||
elif self.program_id._compute_program_amount('rule_minimum_amount', order.currency_id) > amount_total:
|
||||
elif not self.program_id._filter_on_mimimum_amount(order):
|
||||
message = {'error': _('A minimum of %s %s should be purchased to get the reward') % (self.program_id.rule_minimum_amount, self.program_id.currency_id.name)}
|
||||
elif not self.program_id.active:
|
||||
message = {'error': _('The coupon program for %s is in draft or closed state') % (self.code)}
|
||||
|
||||
@@ -10,7 +10,10 @@ class SaleCouponProgram(models.Model):
|
||||
_name = 'sale.coupon.program'
|
||||
_description = "Sales Coupon Program"
|
||||
_inherits = {'sale.coupon.rule': 'rule_id', 'sale.coupon.reward': 'reward_id'}
|
||||
_order = "sequence"
|
||||
# We should apply 'discount' promotion first to avoid offering free product when we should not.
|
||||
# Eg: If the discount lower the SO total below the required threshold
|
||||
# Note: This is only revelant when programs have the same sequence (which they have by default)
|
||||
_order = "sequence, reward_type"
|
||||
|
||||
name = fields.Char(required=True, translate=True)
|
||||
active = fields.Boolean('Active', default=True, help="A program is available for the customers when active")
|
||||
@@ -136,12 +139,9 @@ class SaleCouponProgram(models.Model):
|
||||
def _check_promo_code(self, order, coupon_code):
|
||||
message = {}
|
||||
applicable_programs = order._get_applicable_programs()
|
||||
amount_total = order.amount_untaxed + order.reward_amount
|
||||
if self.rule_minimum_amount_tax_inclusion == 'tax_included':
|
||||
amount_total += order.amount_tax
|
||||
if self.maximum_use_number != 0 and self.order_count >= self.maximum_use_number:
|
||||
message = {'error': _('Promo code %s has been expired.') % (coupon_code)}
|
||||
elif self._compute_program_amount('rule_minimum_amount', order.currency_id) > amount_total:
|
||||
elif not self._filter_on_mimimum_amount(order):
|
||||
message = {'error': _('A minimum of %s %s should be purchased to get the reward') % (self.rule_minimum_amount, self.currency_id.name)}
|
||||
elif self.promo_code and self.promo_code == order.promo_code:
|
||||
message = {'error': _('The promo code is already applied on this order')}
|
||||
@@ -151,7 +151,7 @@ class SaleCouponProgram(models.Model):
|
||||
message = {'error': _('Promo code is invalid')}
|
||||
elif self.rule_date_from and self.rule_date_from > order.date_order or self.rule_date_to and order.date_order > self.rule_date_to:
|
||||
message = {'error': _('Promo code is expired')}
|
||||
elif order.promo_code:
|
||||
elif order.promo_code and self.promo_code_usage == 'code_needed':
|
||||
message = {'error': _('Promotionals codes are not cumulative.')}
|
||||
elif self._is_global_discount_program() and order.applied_coupon_ids.mapped('program_id').filtered(lambda program: program._is_global_discount_program()):
|
||||
message = {'error': _('Global discounts are not cumulative.')}
|
||||
@@ -172,12 +172,16 @@ class SaleCouponProgram(models.Model):
|
||||
|
||||
@api.model
|
||||
def _filter_on_mimimum_amount(self, order):
|
||||
# To get actual total amount of SO without any reward or discount
|
||||
discounted_amount = sum(order.order_line.filtered(lambda line: line.is_reward_line).mapped('price_total'))
|
||||
untaxed_amount = order.amount_untaxed - discounted_amount
|
||||
untaxed_amount = order.amount_untaxed
|
||||
tax_amount = order.amount_tax
|
||||
|
||||
# Some lines should not be considered when checking if threshold is met like delivery
|
||||
untaxed_amount -= sum([line.price_subtotal for line in order._get_no_effect_on_threshold_lines()])
|
||||
tax_amount -= sum([line.price_tax for line in order._get_no_effect_on_threshold_lines()])
|
||||
|
||||
return self.filtered(lambda program:
|
||||
program.rule_minimum_amount_tax_inclusion == 'tax_included' and
|
||||
program._compute_program_amount('rule_minimum_amount', order.currency_id) <= untaxed_amount + order.amount_tax or
|
||||
program._compute_program_amount('rule_minimum_amount', order.currency_id) <= untaxed_amount + tax_amount or
|
||||
program.rule_minimum_amount_tax_inclusion == 'tax_excluded' and
|
||||
program._compute_program_amount('rule_minimum_amount', order.currency_id) <= untaxed_amount)
|
||||
|
||||
|
||||
+23
-13
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
@@ -19,7 +19,15 @@ class SaleOrder(models.Model):
|
||||
@api.depends('order_line')
|
||||
def _compute_reward_total(self):
|
||||
for order in self:
|
||||
order.reward_amount = sum([line.price_subtotal for line in order.order_line.filtered(lambda line: line.is_reward_line)])
|
||||
order.reward_amount = sum([line.price_subtotal for line in order._get_reward_lines()])
|
||||
|
||||
def _get_no_effect_on_threshold_lines(self):
|
||||
self.ensure_one()
|
||||
lines = self.env['sale.order.line']
|
||||
# Do not count already applied promo_code discount; Do not substract itself
|
||||
if self.code_promo_program_id and self.code_promo_program_id.reward_type == 'discount':
|
||||
lines = self.order_line.filtered(lambda l: l.product_id == self.code_promo_program_id.discount_line_product_id)
|
||||
return lines
|
||||
|
||||
@api.multi
|
||||
def recompute_coupon_lines(self):
|
||||
@@ -32,7 +40,7 @@ class SaleOrder(models.Model):
|
||||
@api.returns('self', lambda value: value.id)
|
||||
def copy(self, default=None):
|
||||
order = super(SaleOrder, self).copy(dict(default or {}, order_line=False))
|
||||
for line in self.order_line.filtered(lambda line: not line.is_reward_line):
|
||||
for line in self._get_reward_lines():
|
||||
line.copy({'order_id': order.id})
|
||||
order.with_context(sale_coupon_no_loop=False)._create_new_no_code_promo_reward_lines()
|
||||
return order
|
||||
@@ -73,7 +81,7 @@ class SaleOrder(models.Model):
|
||||
if program._is_valid_product(program.reward_product_id):
|
||||
reward_product_qty = max_product_qty // (program.rule_min_quantity + program.reward_product_quantity)
|
||||
else:
|
||||
reward_product_qty = max_product_qty
|
||||
reward_product_qty = min(max_product_qty, self.order_line.filtered(lambda x: x.product_id == program.reward_product_id).product_uom_qty)
|
||||
|
||||
reward_qty = min(int(int(max_product_qty / program.rule_min_quantity) * program.reward_product_quantity), reward_product_qty)
|
||||
# Take the default taxes on the reward product, mapped with the fiscal position
|
||||
@@ -85,14 +93,16 @@ class SaleOrder(models.Model):
|
||||
'price_unit': - price_unit,
|
||||
'product_uom_qty': reward_qty,
|
||||
'is_reward_line': True,
|
||||
'name': "Free Product - " + program.reward_product_id.name,
|
||||
'name': _("Free Product") + " - " + program.reward_product_id.name,
|
||||
'product_uom': program.reward_product_id.uom_id.id,
|
||||
'tax_id': [(4, tax.id, False) for tax in taxes],
|
||||
}
|
||||
|
||||
def _get_order_lines_untaxed_amount(self):
|
||||
""" Returns the untaxed sale order total amount without the rewards amount"""
|
||||
return sum([x.price_subtotal for x in self.order_line.filtered(lambda x: not x.is_reward_line)])
|
||||
def _get_order_lines_tax_included_amount(self):
|
||||
""" Returns the taxes included sale order total amount without the rewards amount"""
|
||||
free_reward_product = self.env['sale.coupon.program'].search([('reward_type', '=', 'product')]).mapped('discount_line_product_id')
|
||||
return sum([x.price_total for x in self.order_line.filtered(lambda x: not x.is_reward_line or x.product_id in free_reward_product)])
|
||||
|
||||
|
||||
def _get_reward_values_discount_fixed_amount(self, program):
|
||||
total_amount = sum(self.order_line.filtered(lambda line: not line.is_reward_line).mapped('price_total'))
|
||||
@@ -107,15 +117,15 @@ class SaleOrder(models.Model):
|
||||
|
||||
def _get_reward_values_discount_percentage(self, program):
|
||||
discount_amount = 0
|
||||
amount_untaxed = self._get_order_lines_untaxed_amount()
|
||||
amount_total = self._get_order_lines_tax_included_amount()
|
||||
max_amount = program._compute_program_amount('discount_max_amount', self.currency_id)
|
||||
if program.discount_apply_on == 'on_order':
|
||||
discount_amount = amount_untaxed * (program.discount_percentage / 100)
|
||||
discount_amount = amount_total * (program.discount_percentage / 100)
|
||||
if program.discount_apply_on == 'cheapest_product':
|
||||
unit_prices = self._get_lines_unit_prices()
|
||||
discount_amount = (min(unit_prices) * (program.discount_percentage) / 100)
|
||||
if program.discount_apply_on == 'specific_product':
|
||||
discount_amount = sum([(x.price_unit * x.product_uom_qty) * (program.discount_percentage / 100) for x in self.order_line.filtered(
|
||||
discount_amount = sum([(x.price_total * x.product_uom_qty) * (program.discount_percentage / 100) for x in self.order_line.filtered(
|
||||
lambda x: x.product_id == program.discount_specific_product_id)])
|
||||
if program.discount_max_amount and discount_amount > max_amount:
|
||||
discount_amount = max_amount
|
||||
@@ -127,7 +137,7 @@ class SaleOrder(models.Model):
|
||||
elif program.discount_type == 'fixed_amount':
|
||||
discount_amount = self._get_reward_values_discount_fixed_amount(program)
|
||||
return {
|
||||
'name': "Discount: %s" % (program.name),
|
||||
'name': _("Discount: ") + program.name,
|
||||
'product_id': program.discount_line_product_id.id,
|
||||
'price_unit': - discount_amount,
|
||||
'product_uom_qty': 1.0,
|
||||
@@ -181,7 +191,7 @@ class SaleOrder(models.Model):
|
||||
('promo_code_usage', '=', 'no_code_needed'),
|
||||
# ('promo_applicability', '=', 'on_current_order')
|
||||
])._filter_programs_from_common_rules(self)
|
||||
return programs.sorted('sequence')
|
||||
return programs
|
||||
|
||||
def _create_new_no_code_promo_reward_lines(self):
|
||||
'''Apply new programs that are applicable'''
|
||||
|
||||
@@ -5,3 +5,4 @@ from . import test_program_without_code_operations
|
||||
from . import test_program_with_code_operations
|
||||
from . import test_program_rules
|
||||
from . import test_program_rewards
|
||||
from . import test_program_numbers
|
||||
|
||||
@@ -57,3 +57,10 @@ class TestSaleCouponCommon(common.TransactionCase):
|
||||
'rule_products_domain': "[('id', 'in', [%s])]" % (self.product_A.id),
|
||||
'active': True,
|
||||
})
|
||||
|
||||
self.tax_10pc_incl = self.env['account.tax'].create({
|
||||
'name': "10% Tax incl",
|
||||
'amount_type': 'percent',
|
||||
'amount': 10,
|
||||
'price_include': True,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.addons.sale_coupon.tests.common import TestSaleCouponCommon
|
||||
|
||||
class TestSaleCouponProgramNumbers(TestSaleCouponCommon):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSaleCouponProgramNumbers, self).setUp()
|
||||
|
||||
self.iPadMini = self.env.ref('product.product_product_6').copy()
|
||||
self.computerCase = self.env.ref('product.product_product_16').copy()
|
||||
self.littleServer = self.env.ref('product.consu_delivery_02').copy()
|
||||
self.steve = self.env['res.partner'].create({
|
||||
'name': 'Steve Bucknor',
|
||||
'customer': True,
|
||||
'email': 'steve.bucknor@example.com',
|
||||
})
|
||||
self.empty_order = self.env['sale.order'].create({
|
||||
'partner_id': self.steve.id
|
||||
})
|
||||
|
||||
self.p1 = self.env['sale.coupon.program'].create({
|
||||
'name': 'Code for 10% on orders',
|
||||
'promo_code_usage': 'code_needed',
|
||||
'promo_code': 'test_10pc',
|
||||
'discount_type': 'percentage',
|
||||
'discount_percentage': 10.0,
|
||||
'program_type': 'promotion_program',
|
||||
})
|
||||
self.p2 = self.env['sale.coupon.program'].create({
|
||||
'name': 'Buy 3 ipads, get one for free',
|
||||
'promo_code_usage': 'no_code_needed',
|
||||
'reward_type': 'product',
|
||||
'program_type': 'promotion_program',
|
||||
'reward_product_id': self.iPadMini.id,
|
||||
'rule_min_quantity': 3,
|
||||
'rule_products_domain': '[["name","ilike","ipad mini"]]',
|
||||
})
|
||||
self.p3 = self.env['sale.coupon.program'].create({
|
||||
'name': 'Buy 1 computer case, get a free little server',
|
||||
'promo_code_usage': 'no_code_needed',
|
||||
'reward_type': 'product',
|
||||
'program_type': 'promotion_program',
|
||||
'reward_product_id': self.littleServer.id,
|
||||
'rule_products_domain': '[["name","ilike","computer case"]]',
|
||||
})
|
||||
|
||||
def test_program_numbers_free_and_paid_product_qty(self):
|
||||
# These tests will focus on numbers (free product qty, SO total, reduction total..)
|
||||
order = self.empty_order
|
||||
sol1 = self.env['sale.order.line'].create({
|
||||
'product_id': self.iPadMini.id,
|
||||
'name': 'iPad Mini',
|
||||
'product_uom_qty': 4.0,
|
||||
'order_id': order.id,
|
||||
})
|
||||
|
||||
# Check we correctly get a free product
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 2, "We should have 2 lines as we now have one 'Free iPad Mini' line as we bought 4 of them")
|
||||
|
||||
# Check free product's price is not added to total when applying reduction (Or the discount will also be applied on the free product's price)
|
||||
self.env['sale.coupon.apply.code'].sudo().apply_coupon(order, 'test_10pc')
|
||||
self.assertEqual(len(order.order_line.ids), 3, "We should 3 lines as we should have a new line for promo code reduction")
|
||||
self.assertEqual(order.amount_total, 864, "Only paid product should have their price discounted")
|
||||
order.order_line.filtered(lambda x: 'Discount' in x.name).unlink() # Remove Discount
|
||||
|
||||
# Check free product is removed since we are below minimum required quantity
|
||||
sol1.product_uom_qty = 3
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 1, "Free iPad Mini should have been removed")
|
||||
|
||||
# Free product in cart will be considered as paid product when changing quantity of paid product, so the free product quantity computation will be wrong.
|
||||
# 100 iPad in cart, 25 free, set quantity to 10 ipad, you should have 2 free ipad but you get 8 because it add the 25 initial free ipad to the total paid ipad when computing (25+10 > 35 > /4 = 8 free ipad)
|
||||
sol1.product_uom_qty = 100
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(order.order_line.filtered(lambda x: x.is_reward_line).product_uom_qty, 25, "We should have 25 Free iPad Mini")
|
||||
sol1.product_uom_qty = 10
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(order.order_line.filtered(lambda x: x.is_reward_line).product_uom_qty, 2, "We should have 2 Free iPad Mini")
|
||||
|
||||
def test_program_numbers_check_eligibility(self):
|
||||
# These tests will focus on numbers (free product qty, SO total, reduction total..)
|
||||
|
||||
# Check if we have enough paid product to receive free product in case of a free product that is different from the paid product required
|
||||
# Buy A, get free b. (remember we need a paid B in cart to receive free b). If your cart is 4A 1B then you should receive 1b (you are eligible to receive 4 because you have 4A but since you dont have enought B in your cart, you are limited to the B quantity)
|
||||
order = self.empty_order
|
||||
sol1 = self.env['sale.order.line'].create({
|
||||
'product_id': self.computerCase.id,
|
||||
'name': 'Computer Case',
|
||||
'product_uom_qty': 4.0,
|
||||
'order_id': order.id,
|
||||
})
|
||||
sol2 = self.env['sale.order.line'].create({
|
||||
'product_id': self.littleServer.id,
|
||||
'name': 'Little Server',
|
||||
'product_uom_qty': 1.0,
|
||||
'order_id': order.id,
|
||||
})
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 3, "We should have a 'Free Little Server' promotion line")
|
||||
self.assertEqual(order.order_line.filtered(lambda x: x.is_reward_line).product_uom_qty, 1, "We should receive one and only one free Little Server")
|
||||
|
||||
# Check the required value amount to be eligible for the program is correctly computed (eg: it does not add negative value (from free product) to total)
|
||||
# A = free b | Have your cart with A 2B b | cart value should be A + 1B but in code it is only A (free b value is subsstract 2 times)
|
||||
# This is because _amount_all() is summing all SO lines (so + (-b.value)) and again in _check_promo_code() order.amount_untaxed + order.reward_amount | amount_untaxed has already free product value substracted (_amount_all)
|
||||
sol1.product_uom_qty = 1
|
||||
sol2.product_uom_qty = 2
|
||||
self.p1.rule_minimum_amount = 5000
|
||||
order.recompute_coupon_lines()
|
||||
self.env['sale.coupon.apply.code'].sudo().apply_coupon(order, 'test_10pc')
|
||||
self.assertEqual(len(order.order_line.ids), 4, "We should have 4 lines as we should have a new line for promo code reduction")
|
||||
|
||||
# Check you can still have auto applied promotion if you have a promo code set to the order
|
||||
sol4 = self.env['sale.order.line'].create({
|
||||
'product_id': self.iPadMini.id,
|
||||
'name': 'iPad Mini',
|
||||
'product_uom_qty': 4.0,
|
||||
'order_id': order.id,
|
||||
})
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 6, "We should have 2 more lines as we now have one 'Free iPad Mini' line since we bought 4 of them")
|
||||
|
||||
def test_program_numbers_taxes_and_rules(self):
|
||||
percent_tax = self.env['account.tax'].create({
|
||||
'name': "15% Tax",
|
||||
'amount_type': 'percent',
|
||||
'amount': 15,
|
||||
'price_include': True,
|
||||
})
|
||||
p_specific_product = self.env['sale.coupon.program'].create({
|
||||
'name': '20% reduction on ipad in cart',
|
||||
'promo_code_usage': 'no_code_needed',
|
||||
'reward_type': 'discount',
|
||||
'program_type': 'promotion_program',
|
||||
'discount_type': 'percentage',
|
||||
'discount_percentage': 20.0,
|
||||
'rule_minimum_amount': 320.00,
|
||||
'discount_apply_on': 'specific_product',
|
||||
'discount_specific_product_id': self.iPadMini.id,
|
||||
})
|
||||
order = self.empty_order
|
||||
self.iPadMini.taxes_id = percent_tax
|
||||
sol1 = self.env['sale.order.line'].create({
|
||||
'product_id': self.iPadMini.id,
|
||||
'name': 'iPad Mini',
|
||||
'product_uom_qty': 1.0,
|
||||
'order_id': order.id,
|
||||
})
|
||||
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 1, "We should not get the reduction line since we dont have 320$ tax excluded (ipad is 320$ tax included)")
|
||||
sol1.tax_id.price_include = False
|
||||
sol1._compute_tax_id()
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 2, "We should now get the reduction line since we have 320$ tax included (ipad is 320$ tax included)")
|
||||
# (320 +15% tax) - (20% of (320 + 15% tax) = 368 + 73.6 = 294.4
|
||||
self.assertEqual(order.amount_total, 294.4, "Check discount has been applied correctly (eg: on taxes aswell)")
|
||||
|
||||
# test coupon with code works the same as auto applied_programs
|
||||
p_specific_product.write({'promo_code_usage':'code_needed', 'promo_code':'20pc'})
|
||||
order.order_line.filtered(lambda l: l.is_reward_line).unlink()
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 1, "Reduction should be removed since we deleted it and it is now a promo code usage, it shouldn't be automatically reapplied")
|
||||
|
||||
self.env['sale.coupon.apply.code'].sudo().apply_coupon(order, '20pc')
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 2, "We should now get the reduction line since we have 320$ tax included (ipad is 320$ tax included)")
|
||||
|
||||
#check discount applied only on ipad
|
||||
sol2 = self.env['sale.order.line'].create({
|
||||
'product_id': self.computerCase.id,
|
||||
'name': 'Computer Case',
|
||||
'product_uom_qty': 10.0,
|
||||
'order_id': order.id,
|
||||
})
|
||||
order.recompute_coupon_lines()
|
||||
# (10x25) + (320 +15% tax) - (20% of (320 + 15% tax) = 250 + 368 - 73.6 = 544.4
|
||||
self.assertEqual(order.amount_total, 544.4, "We should only get reduction on ipad")
|
||||
@@ -55,7 +55,7 @@ class TestProgramRules(TestSaleCouponCommon):
|
||||
# Test case: Based on the minimum purchased
|
||||
|
||||
self.immediate_promotion_program.write({
|
||||
'rule_minimum_amount': 1000.0,
|
||||
'rule_minimum_amount': 1006,
|
||||
'rule_minimum_amount_tax_inclusion': 'tax_excluded'
|
||||
})
|
||||
|
||||
@@ -81,7 +81,7 @@ class TestProgramRules(TestSaleCouponCommon):
|
||||
order.write({'order_line': [
|
||||
(0, False, {
|
||||
'product_id': self.product_A.id,
|
||||
'name': '1 Product A',
|
||||
'name': '10 Product A',
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10.0,
|
||||
}),
|
||||
@@ -93,7 +93,18 @@ class TestProgramRules(TestSaleCouponCommon):
|
||||
})
|
||||
]})
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 3, "The promo offert should have been applied as the purchased amount is enough")
|
||||
# 10*100 + 5 = 1005
|
||||
self.assertEqual(len(order.order_line.ids), 2, "The promo offert should not be applied as the purchased amount is not enough")
|
||||
|
||||
self.immediate_promotion_program.rule_minimum_amount = 1005
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 3, "The promo offert should be applied as the purchased amount is now enough")
|
||||
|
||||
# 10*(100*1.15) + (5*1.15) = 10*115 + 5.75 = 1155.75
|
||||
self.immediate_promotion_program.rule_minimum_amount = 1006
|
||||
self.immediate_promotion_program.rule_minimum_amount_tax_inclusion = 'tax_included'
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 3, "The promo offert should be applied as the initial amount required is now tax included")
|
||||
|
||||
def test_program_rules_validity_dates_and_uses(self):
|
||||
# Test case: Based on the validity dates and the number of allowed uses
|
||||
|
||||
Reference in New Issue
Block a user