[FIX] point_of_sale: wrong value in pos sales report

Current behavior:
The pos sale report is showing the wrong value in the "Total (VAT Exl)"
column. The value acutally shown is the total tax included.

Steps to reproduce:
- Create a product with a tax included in price
- Create a pos order with this product
- Validate the order
- Close session and print the pos sales report
- Check the value in the "Total (VAT Exl)" column.

opw-3684937

closes odoo/odoo#157753

X-original-commit: ba58ac0f86e10755f1ffbc80814c3722470517f9
Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
Signed-off-by: Robin Engels (roen) <roen@odoo.com>
This commit is contained in:
roen-odoo
2024-03-15 17:29:55 +00:00
parent ac80ba9bcf
commit fafd931990
4 changed files with 50 additions and 37 deletions
@@ -213,8 +213,9 @@ class ReportSaleDetails(models.AbstractModel):
'price_unit': price_unit,
'discount': discount,
'uom': product.uom_id.name,
'total_paid': product_total
} for (product, price_unit, discount), (qty, product_total) in product_list.items()], key=lambda l: l['product_name']),
'total_paid': product_total,
'base_amount': base_amount,
} for (product, price_unit, discount), (qty, product_total, base_amount) in product_list.items()], key=lambda l: l['product_name']),
}
products.append(category_dictionnary)
products = sorted(products, key=lambda l: str(l['name']))
@@ -230,8 +231,9 @@ class ReportSaleDetails(models.AbstractModel):
'price_unit': price_unit,
'discount': discount,
'uom': product.uom_id.name,
'total_paid': product_total
} for (product, price_unit, discount), (qty, product_total) in product_list.items()], key=lambda l: l['product_name']),
'total_paid': product_total,
'base_amount': base_amount,
} for (product, price_unit, discount), (qty, product_total, base_amount) in product_list.items()], key=lambda l: l['product_name']),
}
refund_products.append(category_dictionnary)
refund_products = sorted(refund_products, key=lambda l: str(l['name']))
@@ -303,9 +305,10 @@ class ReportSaleDetails(models.AbstractModel):
keys1 = line.product_id.product_tmpl_id.pos_categ_ids.mapped("name") or [_('Not Categorized')]
for key1 in keys1:
products.setdefault(key1, {})
products[key1].setdefault(key2, [0.0, 0.0])
products[key1].setdefault(key2, [0.0, 0.0, 0.0])
products[key1][key2][0] += line.qty
products[key1][key2][1] += line.currency_id.round(line.price_unit * line.qty * (100 - line.discount) / 100.0)
products[key1][key2][2] += line.price_subtotal
if line.tax_ids_after_fiscal_position:
line_taxes = line.tax_ids_after_fiscal_position.sudo().compute_all(line.price_unit * (1-(line.discount or 0.0)/100.0), currency, line.qty, product=line.product_id, partner=line.order_id.partner_id or False)
@@ -331,13 +334,13 @@ class ReportSaleDetails(models.AbstractModel):
total_cat = 0
for product in category_dict['products']:
qty_cat += product['quantity']
total_cat += product['total_paid']
total_cat += product['base_amount']
category_dict['total'] = total_cat
category_dict['qty'] = qty_cat
# IMPROVEMENT: It would be better if the `products` are grouped by pos.order.line.id.
unique_products = list({tuple(sorted(product.items())): product for category in categories for product in category['products']}.values())
all_qty = sum([product['quantity'] for product in unique_products])
all_total = sum([product['total_paid'] for product in unique_products])
all_total = sum([product['base_amount'] for product in unique_products])
return categories, {'total': all_total, 'qty': all_qty}
+9
View File
@@ -737,3 +737,12 @@ class TestPoSCommon(ValuationReconciliationTestCommon):
else:
# if the expected_account_move_vals is falsy, the account_move should be falsy.
self.assertFalse(account_move)
def make_payment(self, order, payment_method, amount):
""" Make payment for the order using the given payment method.
"""
payment_context = {"active_id": order.id, "active_ids": order.ids}
return self.env['pos.make.payment'].with_context(**payment_context).create({
'amount': amount,
'payment_method_id': payment_method.id,
}).check()
@@ -12,47 +12,48 @@ class TestReportSession(TestPoSCommon):
def test_report_session(self):
product1 = self.create_product('Product 1', self.categ_basic, 150)
self.open_new_session()
session = self.pos_session
self.tax1 = self.env['account.tax'].create({
'name': 'Tax 1',
'amount': 10,
'price_include': True,
})
self.product1 = self.create_product('Product A', self.categ_basic, 110, self.tax1.id)
self.config.open_ui()
session_id = self.config.current_session_id.id
order = self.env['pos.order'].create({
'session_id': session.id,
'company_id': self.env.company.id,
'session_id': session_id,
'partner_id': self.partner_a.id,
'lines': [(0, 0, {
'name': "OL/0001",
'product_id': product1.id,
'price_unit': 150,
'product_id': self.product1.id,
'price_unit': 110,
'discount': 0,
'qty': 1.0,
'price_subtotal': 150,
'price_subtotal_incl': 150,
}),],
'amount_total': 150.0,
'amount_tax': 0.0,
'amount_paid': 0.0,
'qty': 1,
'tax_ids': [[6, False, [self.tax1.id]]],
'price_subtotal': 100,
'price_subtotal_incl': 110,
})],
'pricelist_id': self.config.pricelist_id.id,
'amount_paid': 110.0,
'amount_total': 110.0,
'amount_tax': 10.0,
'amount_return': 0.0,
'last_order_preparation_change': '{}'
'last_order_preparation_change': '{}',
'to_invoice': False,
})
payment_context = {"active_ids": order.ids, "active_id": order.id}
order_payment = self.env['pos.make.payment'].with_context(**payment_context).create({
'amount': 60,
'payment_method_id': self.bank_split_pm1.id
})
order_payment.with_context(**payment_context).check()
self.make_payment(order, self.bank_split_pm1, 60)
self.make_payment(order, self.bank_pm1, 50)
order_payment = self.env['pos.make.payment'].with_context(**payment_context).create({
'amount': 90,
'payment_method_id': self.bank_pm1.id
})
order_payment.with_context(**payment_context).check()
session.action_pos_session_closing_control(bank_payment_method_diffs={self.bank_split_pm1.id: 50, self.bank_pm1.id: 40})
self.config.current_session_id.action_pos_session_closing_control(bank_payment_method_diffs={self.bank_split_pm1.id: 50, self.bank_pm1.id: 40})
# PoS Orders have negative IDs to avoid conflict, so reports[0] will correspond to the newest order
report = self.env['report.point_of_sale.report_saledetails'].get_sale_details(session_ids=[session.id])
report = self.env['report.point_of_sale.report_saledetails'].get_sale_details(session_ids=[session_id])
split_payment_bank = [p for p in report['payments'] if p.get('id', 0) == self.bank_split_pm1.id]
self.assertEqual(split_payment_bank[0]['cash_moves'][0]['amount'], 50)
bank_payment = [p for p in report['payments'] if p.get('id', 0) == self.bank_pm1.id]
self.assertEqual(bank_payment[0]['cash_moves'][0]['amount'], 40)
self.assertEqual(report['products_info']['total'], 100, "Total amount of products should be 100, as we want total without tax")
self.assertEqual(report['products'][0]['products'][0]['base_amount'], 100, "Base amount of product should be 100, as we want price without tax")
@@ -73,10 +73,10 @@
</td>
<td class="text-end">
<t t-if="currency['position']">
<span t-out='line["total_paid"]' t-options="{'widget': 'float', 'precision': currency['precision']}">567789</span><span t-out='currency["symbol"]'>$</span>
<span t-out='line["base_amount"]' t-options="{'widget': 'float', 'precision': currency['precision']}">567789</span><span t-out='currency["symbol"]'>$</span>
</t>
<t t-else="" >
<span t-out='currency["symbol"]'>$</span><span t-out='line["total_paid"]' t-options="{'widget': 'float', 'precision': currency['precision']}">567789</span>
<span t-out='currency["symbol"]'>$</span><span t-out='line["base_amount"]' t-options="{'widget': 'float', 'precision': currency['precision']}">567789</span>
</t>
<t t-if='line["discount"] != 0'>