1# -*- coding: utf-8 -*-
2# Part of Odoo. See LICENSE file for full copyright and licensing details.
3
4import odoo
5
6from odoo import tools
7from odoo.addons.point_of_sale.tests.common import TestPoSCommon
8
9@odoo.tests.tagged('post_install', '-at_install')
10class TestPoSMultipleReceivableAccounts(TestPoSCommon):
11    """ Test for invoiced orders with customers having receivable account different from default
12
13    Thus, for this test, there are two receivable accounts involved and are set in the
14    customers.
15        self.customer -> self.receivable_account
16        self.other_customer -> self.other_receivable_account
17
18    NOTE That both receivable accounts above are different from the pos receivable account.
19    """
20
21    def setUp(self):
22        super(TestPoSMultipleReceivableAccounts, self).setUp()
23        self.config = self.basic_config
24        self.product1 = self.create_product(
25            'Product 1',
26            self.categ_basic,
27            lst_price=10.99,
28            standard_price=5.0,
29            tax_ids=self.taxes['tax7'].ids,
30        )
31        self.product2 = self.create_product(
32            'Product 2',
33            self.categ_basic,
34            lst_price=19.99,
35            standard_price=10.0,
36            tax_ids=self.taxes['tax10'].ids,
37            sale_account=self.other_sale_account,
38        )
39        self.product3 = self.create_product(
40            'Product 3',
41            self.categ_basic,
42            lst_price=30.99,
43            standard_price=15.0,
44            tax_ids=self.taxes['tax_group_7_10'].ids,
45        )
46        self.adjust_inventory([self.product1, self.product2, self.product3], [100, 50, 50])
47
48    def test_01_invoiced_order_from_other_customer(self):
49        """
50        Orders
51        ======
52        +---------+----------+-----------+----------+-----+---------+--------------------------+--------+
53        | order   | payments | invoiced? | product  | qty | untaxed | tax                      | total  |
54        +---------+----------+-----------+----------+-----+---------+--------------------------+--------+
55        | order 1 | cash     | no        | product1 | 10  | 109.9   | 7.69 [7%]                | 117.59 |
56        |         |          |           | product2 | 10  | 181.73  | 18.17 [10%]              | 199.9  |
57        |         |          |           | product3 | 10  | 281.73  | 19.72 [7%] + 28.17 [10%] | 329.62 |
58        +---------+----------+-----------+----------+-----+---------+--------------------------+--------+
59        | order 2 | bank     | no        | product1 | 5   | 54.95   | 3.85 [7%]                | 58.80  |
60        |         |          |           | product2 | 5   | 90.86   | 9.09 [10%]               | 99.95  |
61        +---------+----------+-----------+----------+-----+---------+--------------------------+--------+
62        | order 3 | bank     | yes       | product2 | 5   | 90.86   | 9.09 [10%]               | 99.95  |
63        |         |          |           | product3 | 5   | 140.86  | 9.86 [7%] + 14.09 [10%]  | 164.81 |
64        +---------+----------+-----------+----------+-----+---------+--------------------------+--------+
65
66        Expected Result
67        ===============
68        +---------------------+---------+
69        | account             | balance |
70        +---------------------+---------+
71        | sale_account        | -164.85 |
72        | sale_account        | -281.73 |
73        | other_sale_account  | -272.59 |
74        | tax 7%              |  -31.26 |
75        | tax 10%             |  -55.43 |
76        | pos receivable cash |  647.11 |
77        | pos receivable bank |  423.51 |
78        | other receivable    | -264.76 |
79        +---------------------+---------+
80        | Total balance       |    0.00 |
81        +---------------------+---------+
82        """
83        self.open_new_session()
84
85        # create orders
86        orders = []
87        orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 10), (self.product3, 10)]))
88        orders.append(self.create_ui_order_data(
89            [(self.product1, 5), (self.product2, 5)],
90            payments=[(self.bank_pm, 158.75)],
91        ))
92        orders.append(self.create_ui_order_data(
93            [(self.product2, 5), (self.product3, 5)],
94            payments=[(self.bank_pm, 264.76)],
95            customer=self.other_customer,
96            is_invoiced=True,
97            uid='09876-098-0987',
98        ))
99
100        # sync orders
101        order = self.env['pos.order'].create_from_ui(orders)
102
103        # check values before closing the session
104        self.assertEqual(3, self.pos_session.order_count)
105        orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
106        self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
107
108        # check if there is one invoiced order
109        self.assertEqual(len(self.pos_session.order_ids.filtered(lambda order: order.state == 'invoiced')), 1, 'There should only be one invoiced order.')
110
111        # close the session
112        self.pos_session.action_pos_session_validate()
113
114        session_move = self.pos_session.move_id
115        # There should be no line corresponding the original receivable account
116        # But there should be a line for other_receivable_account because
117        # that is the property_account_receivable_id of the customer
118        # of the invoiced order.
119        receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
120        self.assertFalse(receivable_line, msg='There should be no move line for the original receivable account.')
121        other_receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.other_receivable_account)
122        self.assertAlmostEqual(other_receivable_line.balance, -264.76)
123
124    def test_02_all_orders_invoiced_mixed_customers(self):
125        """
126        Orders
127        ======
128        +---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
129        | order   | payments | invoiced?           | product  | qty | untaxed | tax                      |  total |
130        +---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
131        | order 1 | cash     | yes, other_customer | product1 |  10 |  109.90 | 7.69 [7%]                | 117.59 |
132        |         |          |                     | product2 |  10 |  181.73 | 18.17 [10%]              | 199.90 |
133        |         |          |                     | product3 |  10 |  281.73 | 19.72 [7%] + 28.17 [10%] | 329.62 |
134        +---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
135        | order 2 | bank     | yes, customer       | product1 |   5 |   54.95 | 3.85 [7%]                |  58.80 |
136        |         |          |                     | product2 |   5 |   90.86 | 9.09 [10%]               |  99.95 |
137        +---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
138        | order 3 | bank     | yes, other customer | product2 |   5 |   90.86 | 9.09 [10%]               |  99.95 |
139        |         |          |                     | product3 |   5 |  140.86 | 9.86 [7%] + 14.09 [10%]  | 164.81 |
140        +---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
141
142        Expected Result
143        ===============
144        +------------------+---------+
145        | account          | balance |
146        +------------------+---------+
147        | receivable cash  |  647.11 |
148        | receivable bank  |  423.51 |
149        | other receivable | -911.87 |
150        | receivable       | -158.75 |
151        +------------------+---------+
152        | Total balance    |    0.00 |
153        +------------------+---------+
154
155        """
156        self.open_new_session()
157
158        # create orders
159        orders = []
160        orders.append(self.create_ui_order_data(
161            [(self.product1, 10), (self.product2, 10), (self.product3, 10)],
162            customer=self.other_customer,
163            is_invoiced=True,
164            uid='09876-098-0987',
165        ))
166        orders.append(self.create_ui_order_data(
167            [(self.product1, 5), (self.product2, 5)],
168            payments=[(self.bank_pm, 158.75)],
169            customer=self.customer,
170            is_invoiced=True,
171            uid='09876-098-0988',
172        ))
173        orders.append(self.create_ui_order_data(
174            [(self.product2, 5), (self.product3, 5)],
175            payments=[(self.bank_pm, 264.76)],
176            customer=self.other_customer,
177            is_invoiced=True,
178            uid='09876-098-0989',
179        ))
180
181        # sync orders
182        order = self.env['pos.order'].create_from_ui(orders)
183
184        # check values before closing the session
185        self.assertEqual(3, self.pos_session.order_count)
186        orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
187        self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
188
189        # check if there is one invoiced order
190        self.assertEqual(len(self.pos_session.order_ids.filtered(lambda order: order.state == 'invoiced')), 3, 'All orders should be invoiced.')
191
192        # close the session
193        self.pos_session.action_pos_session_validate()
194
195        session_move = self.pos_session.move_id
196
197        receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
198        self.assertAlmostEqual(receivable_line.balance, -158.75)
199        other_receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.other_receivable_account)
200        self.assertAlmostEqual(other_receivable_line.balance, -911.87)
201        receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
202        self.assertAlmostEqual(receivable_line_bank.balance, 423.51)
203        receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
204        self.assertAlmostEqual(receivable_line_cash.balance, 647.11)
205