[ADD] sale_coupon_delivery: Allow to offer a free shipping from a coupon

This commit is contained in:
pgu-odoo
2016-12-20 14:48:01 +01:00
committed by Yannick Tivisse
commit 1925b23fbd
9 changed files with 178 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import models
+15
View File
@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': "Sale Coupon Delivery",
'summary': """Allows to offer free shippings in coupon reward""",
'description': """Integrate coupon mechanism with shipping costs.""",
'category': 'Sales',
'version': '1.0',
'depends': ['sale_coupon', 'delivery'],
'data': [
],
'demo': [
],
'auto_install': True,
}
+6
View File
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import sale_order
import sale_coupon_program
import sale_coupon_reward
+14
View File
@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, _
class SaleCoupon(models.Model):
_inherit = "sale.coupon"
def _check_coupon_code(self, order):
if self.program_id.reward_type == 'free_shipping' and not order.order_line.filtered(lambda line: line.is_delivery):
return {'error': _('The shipping costs are not in the order lines.')}
return super(SaleCoupon, self)._check_coupon_code(order)
+26
View File
@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, _
class SaleCouponProgram(models.Model):
_inherit = "sale.coupon.program"
def _filter_not_ordered_reward_programs(self, order):
"""
Returns the programs when the reward is actually in the order lines
"""
programs = super(SaleCouponProgram, self)._filter_not_ordered_reward_programs(order)
for program in self:
if program.reward_type == 'free_shipping' and \
not order.order_line.filtered(lambda line: line.is_delivery):
programs -= program
return programs
def _check_promo_code(self, order, coupon_code):
if self.reward_type == 'free_shipping' and not order.order_line.filtered(lambda line: line.is_delivery):
return {'error': _('The shipping costs are not in the order lines.')}
return super(SaleCouponProgram, self)._check_promo_code(order, coupon_code)
+19
View File
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, _
class SaleCouponReward(models.Model):
_inherit = 'sale.coupon.reward'
_description = "Sales Coupon Reward"
reward_type = fields.Selection(selection_add=[('free_shipping', 'Free Shipping')])
def name_get(self):
result = []
reward_names = super(SaleCouponReward, self).name_get()
free_shipping_reward_ids = self.filtered(lambda reward: reward.reward_type == 'free_shipping').ids
for res in reward_names:
result.append((res[0], res[0] in free_shipping_reward_ids and _("Free Shipping") or res[1]))
return result
+31
View File
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
class SaleOrder(models.Model):
_inherit = "sale.order"
def _get_order_lines_untaxed_amount(self):
""" Returns the untaxed sale order total amount without the rewards and shipping amount"""
return sum([x.price_subtotal for x in self.order_line.filtered(lambda x: not (x.is_reward_line or x.is_delivery))])
def _get_reward_line_values(self, program):
if program.reward_type == 'free_shipping':
return self._get_reward_values_free_shipping(program)
else:
return super(SaleOrder, self)._get_reward_line_values(program)
def _get_reward_values_free_shipping(self, program):
return {
'name': "Discount: %s" % (program.name),
'product_id': program.discount_line_product_id.id,
'price_unit': - self.order_line.filtered(lambda x: x.is_delivery).price_unit,
'product_uom_qty': 1.0,
'product_uom': program.discount_line_product_id.uom_id.id,
'order_id': self.id,
'is_reward_line': True
}
def _get_lines_unit_prices(self):
return [x.price_unit for x in self.order_line.filtered(lambda x: not x.is_delivery and not x.program_id)]
+4
View File
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import test_free_shipping_reward
+59
View File
@@ -0,0 +1,59 @@
# -*- 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 TestSaleCouponProgramRules(TestSaleCouponCommon):
# Test a free shipping reward + some expected behavior
# (automatic line addition or removal)
def test_free_shipping_reward(self):
# Test case 1: The minimum amount is not reached, the reward should
# not be created
self.immediate_promotion_program.active = False
self.env['sale.coupon.program'].create({
'name': 'Free Shipping if at least 100 euros',
'promo_code_usage': 'no_code_needed',
'reward_type': 'free_shipping',
'rule_minimum_amount': 100.0,
'active': True,
})
order = self.env['sale.order'].create({
'partner_id': self.steve.id,
})
order.write({'order_line': [
(0, False, {
'product_id': self.product_B.id,
'name': 'Product B',
'product_uom': self.uom_unit.id,
'product_uom_qty': 1.0,
})
]})
self.assertEqual(len(order.order_line.ids), 1)
order.carrier_id = self.env['delivery.carrier'].search([])[1]
order.delivery_set()
self.assertEqual(len(order.order_line.ids), 2)
# Test case 2: the amount is sufficient, the shipping should
# be reimbursed
order.write({'order_line': [
(0, False, {
'product_id': self.product_A.id,
'name': 'Product 1',
'product_uom': self.uom_unit.id,
'product_uom_qty': 1.0,
'price_unit': 1000
})
]})
self.assertEqual(len(order.order_line.ids), 4)
# Test case 3: the amount is not sufficient now, the reward should be removed
order.write({'order_line': [
(2, order.order_line.filtered(lambda line: line.product_id.id == self.product_A.id).id, False)
]})
self.assertEqual(len(order.order_line.ids), 2)