diff --git a/addons/point_of_sale/__manifest__.py b/addons/point_of_sale/__manifest__.py
index bdc5f4983ec..1cb4f10517e 100644
--- a/addons/point_of_sale/__manifest__.py
+++ b/addons/point_of_sale/__manifest__.py
@@ -16,7 +16,6 @@
'data/digest_data.xml',
'wizard/pos_box.xml',
'wizard/pos_details.xml',
- 'wizard/pos_discount.xml',
'wizard/pos_open_statement.xml',
'wizard/pos_payment.xml',
'views/pos_templates.xml',
diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py
index 547fd76565e..4fa895bd939 100644
--- a/addons/point_of_sale/models/pos_order.py
+++ b/addons/point_of_sale/models/pos_order.py
@@ -43,6 +43,10 @@ class PosOrder(models.Model):
'date_order': ui_order['creation_date'],
'fiscal_position_id': ui_order['fiscal_position_id'],
'pricelist_id': ui_order['pricelist_id'],
+ 'amount_paid': ui_order['amount_paid'],
+ 'amount_total': ui_order['amount_total'],
+ 'amount_tax': ui_order['amount_tax'],
+ 'amount_return': ui_order['amount_return'],
}
def _payment_fields(self, ui_paymentline):
@@ -463,10 +467,11 @@ class PosOrder(models.Model):
default=lambda self: self.env.uid,
states={'done': [('readonly', True)], 'invoiced': [('readonly', True)]},
)
- amount_tax = fields.Float(compute='_compute_amount_all', string='Taxes', digits=0)
- amount_total = fields.Float(compute='_compute_amount_all', string='Total', digits=0)
- amount_paid = fields.Float(compute='_compute_amount_all', string='Paid', states={'draft': [('readonly', False)]}, readonly=True, digits=0)
- amount_return = fields.Float(compute='_compute_amount_all', string='Returned', digits=0)
+ amount_tax = fields.Float(string='Taxes', digits=0, readonly=True, required=True)
+ amount_total = fields.Float(string='Total', digits=0, readonly=True, required=True)
+ amount_paid = fields.Float(string='Paid', states={'draft': [('readonly', False)]},
+ readonly=True, digits=0, required=True)
+ amount_return = fields.Float(string='Returned', digits=0, required=True, readonly=True)
lines = fields.One2many('pos.order.line', 'order_id', string='Order Lines', states={'draft': [('readonly', False)]}, readonly=True, copy=True)
statement_ids = fields.One2many('account.bank.statement.line', 'pos_statement_id', string='Payments', states={'draft': [('readonly', False)]}, readonly=True)
pricelist_id = fields.Many2one('product.pricelist', string='Pricelist', required=True, states={
@@ -505,10 +510,9 @@ class PosOrder(models.Model):
states={'draft': [('readonly', False)]},
)
- @api.depends('statement_ids', 'lines.price_subtotal_incl', 'lines.discount')
- def _compute_amount_all(self):
+ @api.onchange('statement_ids', 'lines', 'lines')
+ def _onchange_amount_all(self):
for order in self:
- order.amount_paid = order.amount_return = order.amount_tax = 0.0
currency = order.pricelist_id.currency_id
order.amount_paid = sum(payment.amount for payment in order.statement_ids)
order.amount_return = sum(payment.amount < 0 and payment.amount or 0 for payment in order.statement_ids)
@@ -861,10 +865,12 @@ class PosOrder(models.Model):
def add_payment(self, data):
"""Create a new payment for the order"""
+ self.ensure_one()
args = self._prepare_bank_statement_line_payment_values(data)
context = dict(self.env.context)
context.pop('pos_session_id', False)
self.env['account.bank.statement.line'].with_context(context).create(args)
+ self.amount_paid = sum(payment.amount for payment in self.statement_ids)
return args.get('statement_id', False)
@api.multi
@@ -882,6 +888,9 @@ class PosOrder(models.Model):
'date_order': fields.Datetime.now(),
'pos_reference': order.pos_reference,
'lines': False,
+ 'amount_tax': -order.amount_tax,
+ 'amount_total': -order.amount_total,
+ 'amount_paid': 0,
})
for line in order.lines:
clone_line = line.copy({
@@ -889,6 +898,8 @@ class PosOrder(models.Model):
'name': line.name + _(' REFUND'),
'order_id': clone.id,
'qty': -line.qty,
+ 'price_subtotal': -line.price_subtotal,
+ 'price_subtotal_incl': -line.price_subtotal_incl,
})
PosOrder += clone
@@ -931,8 +942,10 @@ class PosOrderLine(models.Model):
product_id = fields.Many2one('product.product', string='Product', domain=[('sale_ok', '=', True)], required=True, change_default=True)
price_unit = fields.Float(string='Unit Price', digits=0)
qty = fields.Float('Quantity', digits=dp.get_precision('Product Unit of Measure'), default=1)
- price_subtotal = fields.Float(compute='_compute_amount_line_all', digits=0, string='Subtotal w/o Tax')
- price_subtotal_incl = fields.Float(compute='_compute_amount_line_all', digits=0, string='Subtotal')
+ price_subtotal = fields.Float(string='Subtotal w/o Tax', digits=0,
+ readonly=True, required=True)
+ price_subtotal_incl = fields.Float(string='Subtotal', digits=0,
+ readonly=True, required=True)
discount = fields.Float(string='Discount (%)', digits=0, default=0.0)
order_id = fields.Many2one('pos.order', string='Order Ref', ondelete='cascade')
create_date = fields.Datetime(string='Creation Date', readonly=True)
@@ -965,17 +978,22 @@ class PosOrderLine(models.Model):
values['name'] = self.env['ir.sequence'].next_by_code('pos.order.line')
return super(PosOrderLine, self).create(values)
- @api.depends('price_unit', 'tax_ids', 'qty', 'discount', 'product_id')
- def _compute_amount_line_all(self):
+ @api.onchange('price_unit', 'tax_ids', 'qty', 'discount', 'product_id')
+ def _onchange_amount_line_all(self):
for line in self:
- fpos = line.order_id.fiscal_position_id
- tax_ids_after_fiscal_position = fpos.map_tax(line.tax_ids, line.product_id, line.order_id.partner_id) if fpos else line.tax_ids
- price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
- taxes = tax_ids_after_fiscal_position.compute_all(price, line.order_id.pricelist_id.currency_id, line.qty, product=line.product_id, partner=line.order_id.partner_id)
- line.update({
- 'price_subtotal_incl': taxes['total_included'],
- 'price_subtotal': taxes['total_excluded'],
- })
+ res = line._compute_amount_line_all()
+ line.update(res)
+
+ def _compute_amount_line_all(self):
+ self.ensure_one()
+ fpos = self.order_id.fiscal_position_id
+ tax_ids_after_fiscal_position = fpos.map_tax(self.tax_ids, self.product_id, self.order_id.partner_id) if fpos else self.tax_ids
+ price = self.price_unit * (1 - (self.discount or 0.0) / 100.0)
+ taxes = tax_ids_after_fiscal_position.compute_all(price, self.order_id.pricelist_id.currency_id, self.qty, product=self.product_id, partner=self.order_id.partner_id)
+ return {
+ 'price_subtotal_incl': taxes['total_included'],
+ 'price_subtotal': taxes['total_excluded'],
+ }
@api.onchange('product_id')
def _onchange_product_id(self):
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index 91e234dafc5..b4a1e0ff6ae 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -1530,6 +1530,8 @@ exports.Orderline = Backbone.Model.extend({
return {
qty: this.get_quantity(),
price_unit: this.get_unit_price(),
+ price_subtotal: this.get_price_without_tax(),
+ price_subtotal_incl: this.get_price_with_tax(),
discount: this.get_discount(),
product_id: this.get_product().id,
tax_ids: [[6, false, _.map(this.get_applicable_taxes(), function(tax){ return tax.id; })]],
@@ -2049,7 +2051,7 @@ exports.Order = Backbone.Model.extend({
}, this));
return {
name: this.get_name(),
- amount_paid: this.get_total_paid(),
+ amount_paid: this.get_total_paid() - this.get_change(),
amount_total: this.get_total_with_tax(),
amount_tax: this.get_total_tax(),
amount_return: this.get_change(),
diff --git a/addons/point_of_sale/tests/test_anglo_saxon.py b/addons/point_of_sale/tests/test_anglo_saxon.py
index b6d27af9505..7fae0de8b83 100644
--- a/addons/point_of_sale/tests/test_anglo_saxon.py
+++ b/addons/point_of_sale/tests/test_anglo_saxon.py
@@ -70,8 +70,14 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
'product_id': self.product.id,
'price_unit': 450,
'discount': 0.0,
- 'qty': 1.0
- })]
+ 'qty': 1.0,
+ 'price_subtotal': 450,
+ 'price_subtotal_incl': 450,
+ })],
+ 'amount_total': 450,
+ 'amount_tax': 0,
+ 'amount_paid': 0,
+ 'amount_return': 0,
})
# I make a payment to fully pay the order
@@ -87,6 +93,7 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
# I check that the order is marked as paid
self.assertEqual(self.pos_order_pos0.state, 'paid', 'Order should be in paid state.')
+ self.assertEqual(self.pos_order_pos0.amount_paid, 450, 'Amount paid for the order should be updated.')
# I close the current session to generate the journal entries
self.pos_config.current_session_id.action_pos_session_close()
diff --git a/addons/point_of_sale/tests/test_point_of_sale_flow.py b/addons/point_of_sale/tests/test_point_of_sale_flow.py
index 94db310f3e6..4f982486bf0 100644
--- a/addons/point_of_sale/tests/test_point_of_sale_flow.py
+++ b/addons/point_of_sale/tests/test_point_of_sale_flow.py
@@ -17,104 +17,6 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
# open all statements/cash registers
self.env['pos.open.statement'].create({}).open_statement()
- def test_order_to_payment(self):
- """
- In order to test the Point of Sale in module, I will do a full flow from the sale to the payment and invoicing.
- I will use two products, one with price including a 10% tax, the other one with 5% tax excluded from the price.
- """
- # I click on create a new session button
- self.pos_config.open_session_cb()
-
- # I create a PoS order with 2 units of PCSC234 at 450 EUR (Tax Incl)
- # and 3 units of PCSC349 at 300 EUR. (Tax Excl)
- self.pos_order_pos0 = self.PosOrder.create({
- 'company_id': self.company_id,
- 'pricelist_id': self.partner1.property_product_pricelist.id,
- 'partner_id': self.partner1.id,
- 'lines': [(0, 0, {
- 'name': "OL/0001",
- 'product_id': self.product3.id,
- 'price_unit': 450,
- 'discount': 0.0,
- 'qty': 2.0,
- 'tax_ids': [(6, 0, self.product3.taxes_id.ids)],
- }), (0, 0, {
- 'name': "OL/0002",
- 'product_id': self.product4.id,
- 'price_unit': 300,
- 'discount': 0.0,
- 'qty': 3.0,
- 'tax_ids': [(6, 0, self.product4.taxes_id.ids)],
- })]
- })
-
- # I check that the total of the order is equal to 450*2 + 300*3*1.05
- # and the tax of the order is equal to 900 -(450 * 2 / 1.1) +
- # 300*0.05*3
- self.assertLess(
- abs(self.pos_order_pos0.amount_total - (450 * 2 + 300 * 3 * 1.05)),
- 0.01, 'The order has a wrong amount, tax included.')
-
- self.assertLess(
- abs(self.pos_order_pos0.amount_tax - (900 - (450 * 2 / 1.1) + 300 * 0.05 * 3)),
- 0.01, 'The order has a wrong tax amount.')
-
- # I want to add a global discount of 5 percent using the wizard
-
- self.pos_discount_0 = self.env['pos.discount'].create({'discount': 5.0})
-
- context = {"active_model": "pos.order", "active_ids": [self.pos_order_pos0.id], "active_id": self.pos_order_pos0.id}
-
- # I click the apply button to set the discount on all lines
- self.pos_discount_0.with_context(context).apply_discount()
-
- # I check that the total of the order is now equal to (450*2 +
- # 300*3*1.05)*0.95
- self.assertLess(
- abs(self.pos_order_pos0.amount_total - (450 * 2 + 300 * 3 * 1.05) * 0.95),
- 0.01, 'The order has a wrong total including tax and discounts')
-
- # I click on the "Make Payment" wizard to pay the PoS order with a
- # partial amount of 100.0 EUR
- context_make_payment = {"active_ids": [self.pos_order_pos0.id], "active_id": self.pos_order_pos0.id}
- self.pos_make_payment_0 = self.PosMakePayment.with_context(context_make_payment).create({
- 'amount': 100.0
- })
-
- # I click on the validate button to register the payment.
- context_payment = {'active_id': self.pos_order_pos0.id}
- self.pos_make_payment_0.with_context(context_payment).check()
-
- # I check that the order is not marked as paid yet
- self.assertEqual(self.pos_order_pos0.state, 'draft', 'Order should be in draft state.')
-
- # On the second payment proposition, I check that it proposes me the
- # remaining balance which is 1790.0 EUR
- defs = self.pos_make_payment_0.with_context({'active_id': self.pos_order_pos0.id}).default_get(['amount'])
-
- self.assertLess(
- abs(defs['amount'] - ((450 * 2 + 300 * 3 * 1.05) * 0.95 - 100.0)), 0.01, "The remaining balance is incorrect.")
-
- #'I pay the remaining balance.
- context_make_payment = {
- "active_ids": [self.pos_order_pos0.id], "active_id": self.pos_order_pos0.id}
-
- self.pos_make_payment_1 = self.PosMakePayment.with_context(context_make_payment).create({
- 'amount': (450 * 2 + 300 * 3 * 1.05) * 0.95 - 100.0
- })
-
- # I click on the validate button to register the payment.
- self.pos_make_payment_1.with_context(context_make_payment).check()
-
- # I check that the order is marked as paid
- self.assertEqual(self.pos_order_pos0.state, 'paid', 'Order should be in paid state.')
-
- # I generate the journal entries
- self.pos_order_pos0._create_account_move_line()
-
- # I test that the generated journal entry is attached to the PoS order
- self.assertTrue(self.pos_order_pos0.account_move, "Journal entry has not been attached to Pos order.")
-
def test_order_refund(self):
# I create a new PoS order with 2 lines
order = self.PosOrder.create({
@@ -128,6 +30,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 5.0,
'qty': 2.0,
'tax_ids': [(6, 0, self.product3.taxes_id.ids)],
+ 'price_subtotal': 450 * (1 - 5/100.0) * 2,
+ 'price_subtotal_incl': 450 * (1 - 5/100.0) * 2,
}), (0, 0, {
'name': "OL/0002",
'product_id': self.product4.id,
@@ -135,7 +39,13 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 5.0,
'qty': 3.0,
'tax_ids': [(6, 0, self.product4.taxes_id.ids)],
- })]
+ 'price_subtotal': 300 * (1 - 5/100.0) * 3,
+ 'price_subtotal_incl': 300 * (1 - 5/100.0) * 3,
+ })],
+ 'amount_total': 1710.0,
+ 'amount_tax': 0.0,
+ 'amount_paid': 1710.0,
+ 'amount_return': 0.0,
})
# I create a refund
@@ -163,11 +73,22 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
TODO: Check the negative picking after changing the picking relation to One2many (also for a mixed use case),
check the quantity, the locations and return picking logic
"""
+
+ def compute_tax(product, price, qty=1, taxes=None):
+ if taxes is None:
+ taxes = product.taxes_id.filtered(lambda t: t.company_id.id == self.env.user.id)
+ currency = self.pos_config.pricelist_id.currency_id
+ res = taxes.compute_all(price, currency, qty, product=product)
+ untax = res['total_excluded']
+ return untax, sum(tax.get('amount', 0.0) for tax in res['taxes'])
+
# I click on create a new session button
self.pos_config.open_session_cb()
# I create a PoS order with 2 units of PCSC234 at 450 EUR
# and 3 units of PCSC349 at 300 EUR.
+ untax1, atax1 = compute_tax(self.product3, 450, 2)
+ untax2, atax2 = compute_tax(self.product4, 300, 3)
self.pos_order_pos1 = self.PosOrder.create({
'company_id': self.company_id,
'pricelist_id': self.partner1.property_product_pricelist.id,
@@ -179,6 +100,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 0.0,
'qty': 2.0,
'tax_ids': [(6, 0, self.product3.taxes_id.ids)],
+ 'price_subtotal': untax1,
+ 'price_subtotal_incl': untax1 + atax1,
}), (0, 0, {
'name': "OL/0002",
'product_id': self.product4.id,
@@ -186,7 +109,13 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 0.0,
'qty': 3.0,
'tax_ids': [(6, 0, self.product4.taxes_id.ids)],
- })]
+ 'price_subtotal': untax2,
+ 'price_subtotal_incl': untax2 + atax2,
+ })],
+ 'amount_tax': atax1 + atax2,
+ 'amount_total': untax1 + untax2 + atax1 + atax2,
+ 'amount_paid': 0,
+ 'amount_return': 0,
})
context_make_payment = {
@@ -194,13 +123,13 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
"active_id": self.pos_order_pos1.id
}
self.pos_make_payment_2 = self.PosMakePayment.with_context(context_make_payment).create({
- 'amount': 1845
+ 'amount': untax1 + untax2 + atax1 + atax2
})
# I click on the validate button to register the payment.
context_payment = {'active_id': self.pos_order_pos1.id}
- self.pos_make_payment_2.with_context(context_payment).check()
+ self.pos_make_payment_2.with_context(context_payment).check()
# I check that the order is marked as paid
self.assertEqual(
self.pos_order_pos1.state,
@@ -208,18 +137,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'Order should be in paid state.'
)
- # I generate the journal entries
- self.pos_order_pos1._create_account_move_line()
-
- # I test that the generated journal entry is attached to the PoS order
- self.assertTrue(
- self.pos_order_pos1.account_move,
- "Journal entry has not been attached to Pos order."
- )
-
- # I test that the pickings are created as expected
+ # I test that the pickings are created as expected during payment
# One picking attached and having all the positive move lines in the correct state
- self.pos_order_pos1.create_picking()
self.assertEqual(
self.pos_order_pos1.picking_id.state,
'done',
@@ -231,6 +150,9 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'Move Lines should be in done state.'
)
+ # I create a second order
+ untax1, atax1 = compute_tax(self.product3, 450, -2)
+ untax2, atax2 = compute_tax(self.product4, 300, -3)
self.pos_order_pos2 = self.PosOrder.create({
'company_id': self.company_id,
'pricelist_id': self.partner1.property_product_pricelist.id,
@@ -242,6 +164,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 0.0,
'qty': (-2.0),
'tax_ids': [(6, 0, self.product3.taxes_id.ids)],
+ 'price_subtotal': untax1,
+ 'price_subtotal_incl': untax1 + atax1,
}), (0, 0, {
'name': "OL/0004",
'product_id': self.product4.id,
@@ -249,7 +173,13 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 0.0,
'qty': (-3.0),
'tax_ids': [(6, 0, self.product4.taxes_id.ids)],
- })]
+ 'price_subtotal': untax2,
+ 'price_subtotal_incl': untax2 + atax2,
+ })],
+ 'amount_tax': atax1 + atax2,
+ 'amount_total': untax1 + untax2 + atax1 + atax2,
+ 'amount_paid': 0,
+ 'amount_return': 0,
})
context_make_payment = {
@@ -257,7 +187,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
"active_id": self.pos_order_pos2.id
}
self.pos_make_payment_3 = self.PosMakePayment.with_context(context_make_payment).create({
- 'amount': (-1845)
+ 'amount': untax1 + untax2 + atax1 + atax2
})
# I click on the validate button to register the payment.
@@ -271,15 +201,6 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'Order should be in paid state.'
)
- # I generate the journal entries
- self.pos_order_pos2._create_account_move_line()
-
- # I test that the generated journal entry is attached to the PoS order
- self.assertTrue(
- self.pos_order_pos2.account_move,
- "Journal entry has not been attached to PoS order."
- )
-
# I test that the pickings are created as expected
# One picking attached and having all the positive move lines in the correct state
self.pos_order_pos2.create_picking()
@@ -294,6 +215,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'Move Lines should be in done state.'
)
+ untax1, atax1 = compute_tax(self.product3, 450, -2)
+ untax2, atax2 = compute_tax(self.product4, 300, 3)
self.pos_order_pos3 = self.PosOrder.create({
'company_id': self.company_id,
'pricelist_id': self.partner1.property_product_pricelist.id,
@@ -305,6 +228,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 0.0,
'qty': (-2.0),
'tax_ids': [(6, 0, self.product3.taxes_id.ids)],
+ 'price_subtotal': untax1,
+ 'price_subtotal_incl': untax1 + atax1,
}), (0, 0, {
'name': "OL/0006",
'product_id': self.product4.id,
@@ -312,7 +237,13 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 0.0,
'qty': 3.0,
'tax_ids': [(6, 0, self.product4.taxes_id.ids)],
- })]
+ 'price_subtotal': untax2,
+ 'price_subtotal_incl': untax2 + atax2,
+ })],
+ 'amount_tax': atax1 + atax2,
+ 'amount_total': untax1 + untax2 + atax1 + atax2,
+ 'amount_paid': 0,
+ 'amount_return': 0,
})
context_make_payment = {
@@ -320,7 +251,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
"active_id": self.pos_order_pos3.id
}
self.pos_make_payment_4 = self.PosMakePayment.with_context(context_make_payment).create({
- 'amount': 45,
+ 'amount': untax1 + untax2 + atax1 + atax2,
})
# I click on the validate button to register the payment.
@@ -334,18 +265,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'Order should be in paid state.'
)
- # I generate the journal entries
- self.pos_order_pos3._create_account_move_line()
-
- # I test that the generated journal entry is attached to the PoS order
- self.assertTrue(
- self.pos_order_pos3.account_move,
- "Journal entry has not been attached to PoS order."
- )
-
# I test that the pickings are created as expected
# One picking attached and having all the positive move lines in the correct state
- self.pos_order_pos3.create_picking()
self.assertEqual(
self.pos_order_pos3.picking_id.state,
'done',
@@ -356,9 +277,22 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
['done'],
'Move Lines should be in done state.'
)
+ # I close the session to generate the journal entries
+ self.pos_config.current_session_id.action_pos_session_closing_control()
+
def test_order_to_invoice(self):
+ def compute_tax(product, price, qty=1, taxes=None):
+ if taxes is None:
+ taxes = product.taxes_id.filtered(lambda t: t.company_id.id == self.env.user.id)
+ currency = self.pos_config.pricelist_id.currency_id
+ res = taxes.compute_all(price, currency, qty, product=product)
+ untax = res['total_excluded']
+ return untax, sum(tax.get('amount', 0.0) for tax in res['taxes'])
+
+ untax1, atax1 = compute_tax(self.product3, 450*0.95, 2)
+ untax2, atax2 = compute_tax(self.product4, 300*0.95, 3)
# I create a new PoS order with 2 units of PC1 at 450 EUR (Tax Incl) and 3 units of PCSC349 at 300 EUR. (Tax Excl)
self.pos_order_pos1 = self.PosOrder.create({
'company_id': self.company_id,
@@ -371,6 +305,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 5.0,
'qty': 2.0,
'tax_ids': [(6, 0, self.product3.taxes_id.ids)],
+ 'price_subtotal': untax1,
+ 'price_subtotal_incl': untax1 + atax1,
}), (0, 0, {
'name': "OL/0002",
'product_id': self.product4.id,
@@ -378,13 +314,19 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'discount': 5.0,
'qty': 3.0,
'tax_ids': [(6, 0, self.product4.taxes_id.ids)],
- })]
+ 'price_subtotal': untax2,
+ 'price_subtotal_incl': untax2 + atax2,
+ })],
+ 'amount_tax': atax1 + atax2,
+ 'amount_total': untax1 + untax2 + atax1 + atax2,
+ 'amount_paid': 0.0,
+ 'amount_return': 0.0,
})
# I click on the "Make Payment" wizard to pay the PoS order
context_make_payment = {"active_ids": [self.pos_order_pos1.id], "active_id": self.pos_order_pos1.id}
self.pos_make_payment = self.PosMakePayment.with_context(context_make_payment).create({
- 'amount': (450 * 2 + 300 * 3 * 1.05) * 0.95,
+ 'amount': untax1 + untax2 + atax1 + atax2,
})
# I click on the validate button to register the payment.
context_payment = {'active_id': self.pos_order_pos1.id}
@@ -401,8 +343,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
# I test that the total of the attached invoice is correct
invoice = self.env['account.invoice'].browse(res['res_id'])
- self.assertEqual(
- float_compare(invoice.amount_total, 1752.75, precision_digits=2), 0, "Invoice not correct")
+ self.assertAlmostEqual(
+ invoice.amount_total, self.pos_order_pos1.amount_total, places=2, msg="Invoice not correct")
"""In order to test the reports on Bank Statement defined in point_of_sale module, I create a bank statement line, confirm it and print the reports"""
@@ -456,15 +398,14 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
"""
Simulation of sales coming from the interface, even after closing the session
"""
- FROMPRODUCT = object()
- def compute_tax(product, price, taxes=FROMPRODUCT, qty=1):
- if taxes is FROMPRODUCT:
- taxes = product.taxes_id
+ def compute_tax(product, price, qty=1, taxes=None):
+ if not taxes:
+ taxes = product.taxes_id.filtered(lambda t: t.company_id.id == self.env.user.id)
currency = self.pos_config.pricelist_id.currency_id
- taxes = taxes.compute_all(price, currency, qty, product=product)['taxes']
- untax = price * qty
- return untax, sum(tax.get('amount', 0.0) for tax in taxes)
+ res = taxes.compute_all(price, currency, qty, product=product)
+ untax = res['total_excluded']
+ return untax, sum(tax.get('amount', 0.0) for tax in res['taxes'])
# I click on create a new session button
self.pos_config.open_session_cb()
@@ -478,7 +419,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'amount_return': 0,
'amount_tax': atax,
'amount_total': untax + atax,
- 'creation_date': fields.Datetime.now(),
+ 'creation_date': fields.Datetime.to_string(fields.Datetime.now()),
'fiscal_position_id': False,
'pricelist_id': self.pos_config.available_pricelist_ids[0].id,
'lines': [[0,
@@ -488,6 +429,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'pack_lot_ids': [],
'price_unit': 0.9,
'product_id': self.led_lamp.id,
+ 'price_subtotal': 0.9,
+ 'price_subtotal_incl': 1.04,
'qty': 1,
'tax_ids': [(6, 0, self.led_lamp.taxes_id.ids)]}]],
'name': 'Order 00042-003-0014',
@@ -512,7 +455,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'amount_return': 0,
'amount_tax': atax,
'amount_total': untax + atax,
- 'creation_date': fields.Datetime.now(),
+ 'creation_date': fields.Datetime.to_string(fields.Datetime.now()),
'fiscal_position_id': False,
'pricelist_id': self.pos_config.available_pricelist_ids[0].id,
'lines': [[0,
@@ -522,6 +465,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'pack_lot_ids': [],
'price_unit': 1.2,
'product_id': self.whiteboard_pen.id,
+ 'price_subtotal': 1.2,
+ 'price_subtotal_incl': 1.38,
'qty': 1,
'tax_ids': [(6, 0, self.whiteboard_pen.taxes_id.ids)]}]],
'name': 'Order 00043-003-0014',
@@ -546,7 +491,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'amount_return': 0,
'amount_tax': atax,
'amount_total': untax + atax,
- 'creation_date': fields.Datetime.now(),
+ 'creation_date': fields.Datetime.to_string(fields.Datetime.now()),
'fiscal_position_id': False,
'pricelist_id': self.pos_config.available_pricelist_ids[0].id,
'lines': [[0,
@@ -556,6 +501,8 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
'pack_lot_ids': [],
'price_unit': 1.28,
'product_id': self.newspaper_rack.id,
+ 'price_subtotal': 1.28,
+ 'price_subtotal_incl': 1.47,
'qty': 1,
'tax_ids': [[6, False, self.newspaper_rack.taxes_id.ids]]}]],
'name': 'Order 00044-003-0014',
diff --git a/addons/point_of_sale/views/pos_order_view.xml b/addons/point_of_sale/views/pos_order_view.xml
index eaf712483a1..d5c61ec4049 100644
--- a/addons/point_of_sale/views/pos_order_view.xml
+++ b/addons/point_of_sale/views/pos_order_view.xml
@@ -41,8 +41,8 @@