[MERGE] forward port branch saas-15 up to ed3eff1427c
This commit is contained in:
+49
-30
@@ -110,7 +110,7 @@ class SaleOrder(models.Model):
|
||||
return 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'))
|
||||
total_amount = sum(self._get_paid_order_lines().mapped('price_total'))
|
||||
fixed_amount = program._compute_program_amount('discount_fixed_amount', self.currency_id)
|
||||
if total_amount < fixed_amount:
|
||||
return total_amount
|
||||
@@ -126,6 +126,15 @@ class SaleOrder(models.Model):
|
||||
return discount_amount
|
||||
|
||||
def _get_reward_values_discount(self, program):
|
||||
if program.discount_type == 'fixed_amount':
|
||||
return [{
|
||||
'name': _("Discount: ") + program.name,
|
||||
'product_id': program.discount_line_product_id.id,
|
||||
'price_unit': - self._get_reward_values_discount_fixed_amount(program),
|
||||
'product_uom_qty': 1.0,
|
||||
'product_uom': program.discount_line_product_id.uom_id.id,
|
||||
'is_reward_line': True,
|
||||
}]
|
||||
reward_dict = {}
|
||||
lines = self._get_paid_order_lines()
|
||||
if program.discount_apply_on == 'cheapest_product':
|
||||
@@ -269,41 +278,51 @@ class SaleOrder(models.Model):
|
||||
|
||||
def _update_existing_reward_lines(self):
|
||||
'''Update values for already applied rewards'''
|
||||
def update_line(order, lines, values):
|
||||
'''Update the lines and return them if they should be deleted'''
|
||||
lines_to_remove = self.env['sale.order.line']
|
||||
# Check commit 6bb42904a03 for next if/else
|
||||
# Remove reward line if price or qty equal to 0
|
||||
if values['product_uom_qty'] and values['price_unit']:
|
||||
order.write({'order_line': [(1, line.id, values) for line in lines]})
|
||||
else:
|
||||
if program.reward_type != 'free_shipping':
|
||||
# Can't remove the lines directly as we might be in a recordset loop
|
||||
lines_to_remove += lines
|
||||
else:
|
||||
value.update(price_unit=0.0)
|
||||
order.write({'order_line': [(1, line.id, values) for line in lines]})
|
||||
return lines_to_remove
|
||||
|
||||
self.ensure_one()
|
||||
order = self
|
||||
applied_programs = order._get_applied_programs_with_rewards_on_current_order()
|
||||
for program in applied_programs:
|
||||
values = order._get_reward_line_values(program)
|
||||
lines = order.order_line.filtered(lambda line: line.product_id == program.discount_line_product_id)
|
||||
lines_to_remove = lines
|
||||
# Values is what discount lines should really be, lines is what we got in the SO at the moment
|
||||
# 1. If values & lines match, we should update the line (or delete it if no qty or price?)
|
||||
# 2. If the value is not in the lines, we should add it
|
||||
# 3. if the lines contains a tax not in value, we should remove it
|
||||
for value in values:
|
||||
value_found = False
|
||||
for line in lines:
|
||||
# Case 1.
|
||||
if not len(set(line.tax_id.mapped('id')).symmetric_difference(set([v[1] for v in value['tax_id']]))):
|
||||
value_found = True
|
||||
# Working on Case 3.
|
||||
lines_to_remove -= line
|
||||
# Check commit 6bb42904a03 for next if/else
|
||||
# Remove reward line if price or qty equal to 0
|
||||
if value['product_uom_qty'] and value['price_unit']:
|
||||
order.write({'order_line': [(1, line.id, value)]})
|
||||
else:
|
||||
if program.reward_type != 'free_shipping':
|
||||
lines_to_remove += line
|
||||
else:
|
||||
value.update(price_unit=0.0)
|
||||
order.write({'order_line': [(1, line.id, value)]})
|
||||
continue
|
||||
# Case 2.
|
||||
if not value_found:
|
||||
order.write({'order_line': [(0, False, value)]})
|
||||
# Case 3.
|
||||
lines_to_remove.unlink()
|
||||
if program.reward_type == 'discount' and program.discount_type == 'percentage':
|
||||
lines_to_remove = lines
|
||||
# Values is what discount lines should really be, lines is what we got in the SO at the moment
|
||||
# 1. If values & lines match, we should update the line (or delete it if no qty or price?)
|
||||
# 2. If the value is not in the lines, we should add it
|
||||
# 3. if the lines contains a tax not in value, we should remove it
|
||||
for value in values:
|
||||
value_found = False
|
||||
for line in lines:
|
||||
# Case 1.
|
||||
if not len(set(line.tax_id.mapped('id')).symmetric_difference(set([v[1] for v in value['tax_id']]))):
|
||||
value_found = True
|
||||
# Working on Case 3.
|
||||
lines_to_remove -= line
|
||||
lines_to_remove += update_line(order, line, value)
|
||||
continue
|
||||
# Case 2.
|
||||
if not value_found:
|
||||
order.write({'order_line': [(0, False, value)]})
|
||||
# Case 3.
|
||||
lines_to_remove.unlink()
|
||||
else:
|
||||
update_line(order, lines, values[0]).unlink()
|
||||
|
||||
def _remove_invalid_reward_lines(self):
|
||||
""" Find programs & coupons that are not applicable anymore.
|
||||
|
||||
@@ -453,3 +453,30 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon):
|
||||
self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({
|
||||
'coupon_code': 'test_10pc'
|
||||
}).process_coupon()
|
||||
|
||||
def test_program_fixed_price(self):
|
||||
# Check fixed amount discount
|
||||
order = self.empty_order
|
||||
fixed_amount_program = self.env['sale.coupon.program'].create({
|
||||
'name': '$249 discount',
|
||||
'promo_code_usage': 'no_code_needed',
|
||||
'program_type': 'promotion_program',
|
||||
'discount_type': 'fixed_amount',
|
||||
'discount_fixed_amount': 249.0,
|
||||
})
|
||||
sol1 = self.env['sale.order.line'].create({
|
||||
'product_id': self.computerCase.id,
|
||||
'name': 'Computer Case',
|
||||
'product_uom_qty': 1.0,
|
||||
'order_id': order.id,
|
||||
})
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(order.amount_total, 0, "Total should be null. The fixed amount discount is higher than the SO total, it should be reduced to the SO total")
|
||||
self.assertEqual(len(order.order_line.ids), 2, "There should be the product line and the reward line")
|
||||
sol1.product_uom_qty = 17
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(order.amount_total, 176, "Fixed amount discount should be totally deduced")
|
||||
self.assertEqual(len(order.order_line.ids), 2, "Number of lines should be unchanged as we just recompute the reward line")
|
||||
fixed_amount_program.write({'active': False}) # Check archived product will remove discount lines on recompute
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 1, "Archiving the program should remove the program reward line")
|
||||
|
||||
Reference in New Issue
Block a user