summaryrefslogtreecommitdiff
path: root/addons/website_sale_coupon/tests/test_shop_sale_coupon.py
blob: 2bc2e0ddef6414cdc6b23cd5a0d34dd8c8869571 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import timedelta

from odoo import fields
from odoo.tests import HttpCase, tagged, TransactionCase
from odoo.addons.sale.tests.test_sale_product_attribute_value_config import TestSaleProductAttributeValueCommon


@tagged('post_install', '-at_install')
class TestUi(TestSaleProductAttributeValueCommon, HttpCase):

    @classmethod
    def setUpClass(cls):
        super(TestUi, cls).setUpClass()
        # set currency to not rely on demo data and avoid possible race condition
        cls.currency_ratio = 1.0
        pricelist = cls.env.ref('product.list0')
        new_currency = cls._setup_currency(cls.currency_ratio)
        pricelist.currency_id = new_currency
        pricelist.flush()


    def test_01_admin_shop_sale_coupon_tour(self):
        # pre enable "Show # found" option to avoid race condition...
        public_category = self.env['product.public.category'].create({'name': 'Public Category'})

        large_cabinet = self.env['product.product'].create({
            'name': 'Small Cabinet',
            'list_price': 320.0,
            'type': 'consu',
            'is_published': True,
            'sale_ok': True,
            'public_categ_ids': [(4, public_category.id)],
            'taxes_id': False,
        })

        free_large_cabinet = self.env['product.product'].create({
            'name': 'Free Product - Small Cabinet',
            'type': 'service',
            'taxes_id': False,
            'supplier_taxes_id': False,
            'sale_ok': False,
            'purchase_ok': False,
            'invoice_policy': 'order',
            'default_code': 'FREELARGECABINET',
            'categ_id': self.env.ref('product.product_category_all').id,
            'taxes_id': False,
        })

        ten_percent = self.env['product.product'].create({
            'name': '10.0% discount on total amount',
            'type': 'service',
            'taxes_id': False,
            'supplier_taxes_id': False,
            'sale_ok': False,
            'purchase_ok': False,
            'invoice_policy': 'order',
            'default_code': '10PERCENTDISC',
            'categ_id': self.env.ref('product.product_category_all').id,
            'taxes_id': False,
        })

        self.env['coupon.program'].create({
            'name': "Buy 3 Small Cabinets, get one for free",
            'promo_code_usage': 'no_code_needed',
            'discount_apply_on': 'on_order',
            'reward_type': 'product',
            'program_type': 'promotion_program',
            'reward_product_id': large_cabinet.id,
            'rule_min_quantity': 3,
            'rule_products_domain': "[['name', 'ilike', 'Small Cabinet']]",
            'discount_line_product_id': free_large_cabinet.id
        })

        self.env['coupon.program'].create({
            'name': "Code for 10% on orders",
            'promo_code_usage': 'code_needed',
            'promo_code': 'testcode',
            'discount_apply_on': 'on_order',
            'discount_type': 'percentage',
            'discount_percentage': 10.0,
            'program_type': 'promotion_program',
            'discount_line_product_id': ten_percent.id
        })

        self.env.ref("website_sale.search_count_box").write({"active": True})
        self.start_tour("/", 'shop_sale_coupon', login="admin")


@tagged('post_install', '-at_install')
class TestWebsiteSaleCoupon(TransactionCase):

    def setUp(self):
        super(TestWebsiteSaleCoupon, self).setUp()
        program = self.env['coupon.program'].create({
            'name': '10% TEST Discount',
            'promo_code_usage': 'code_needed',
            'discount_apply_on': 'on_order',
            'discount_type': 'percentage',
            'discount_percentage': 10.0,
            'program_type': 'coupon_program',
        })

        self.env['coupon.generate.wizard'].with_context(active_id=program.id).create({}).generate_coupon()
        self.coupon = program.coupon_ids[0]

        self.steve = self.env['res.partner'].create({
            'name': 'Steve Bucknor',
            'email': 'steve.bucknor@example.com',
        })
        self.empty_order = self.env['sale.order'].create({
            'partner_id': self.steve.id
        })

    def test_01_gc_coupon(self):
        # 1. Simulate a frontend order (website, product)
        order = self.empty_order
        order.website_id = self.env['website'].browse(1)
        self.env['sale.order.line'].create({
            'product_id': self.env['product.product'].create({
                'name': 'Product A',
                'list_price': 100,
                'sale_ok': True,
            }).id,
            'name': 'Product A',
            'product_uom_qty': 2.0,
            'order_id': order.id,
        })

        # 2. Apply the coupon
        self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({
            'coupon_code': self.coupon.code
        }).process_coupon()
        order.recompute_coupon_lines()

        self.assertEqual(len(order.applied_coupon_ids), 1, "The coupon should've been applied on the order")
        self.assertEqual(self.coupon, order.applied_coupon_ids)
        self.assertEqual(self.coupon.state, 'used')

        # 3. Test recent order -> Should not be removed
        order._gc_abandoned_coupons()

        self.assertEqual(len(order.applied_coupon_ids), 1, "The coupon shouldn't have been removed from the order no more than 4 days")
        self.assertEqual(self.coupon.state, 'used', "Should not have been changed")

        # 4. Test order not older than ICP validity -> Should not be removed
        ICP = self.env['ir.config_parameter']
        icp_validity = ICP.create({'key': 'website_sale_coupon.abandonned_coupon_validity', 'value': 5})
        order.flush()
        query = """UPDATE %s SET write_date = %%s WHERE id = %%s""" % (order._table,)
        self.env.cr.execute(query, (fields.Datetime.to_string(fields.datetime.now() - timedelta(days=4, hours=2)), order.id))
        order._gc_abandoned_coupons()

        self.assertEqual(len(order.applied_coupon_ids), 1, "The coupon shouldn't have been removed from the order the order is 4 days old but icp validity is 5 days")
        self.assertEqual(self.coupon.state, 'used', "Should not have been changed (2)")

        # 5. Test order with no ICP and older then 4 default days -> Should be removed
        icp_validity.unlink()
        order._gc_abandoned_coupons()

        self.assertEqual(len(order.applied_coupon_ids), 0, "The coupon should've been removed from the order as more than 4 days")
        self.assertEqual(self.coupon.state, 'new', "Should have been reset.")