19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:32:12 +01:00
parent 79f83631d5
commit 73afc09215
6267 changed files with 1534193 additions and 1130106 deletions

View file

@ -3,3 +3,5 @@
from . import test_pos_sale_flow
from . import test_pos_sale_report
from . import test_pos_sale_lot
from . import test_taxes_downpayment

View file

@ -0,0 +1,66 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo
from odoo import fields
from odoo.addons.point_of_sale.tests.common import CommonPosTest
@odoo.tests.tagged('post_install', '-at_install')
class TestPointOfSaleFlow(CommonPosTest):
def test_ship_later_lots(self):
self.env.user.group_ids += self.env.ref('account.group_account_manager')
self.stock_location = self.company_data['default_warehouse'].lot_stock_id
self.twenty_dollars_no_tax.product_variant_id.write({
'tracking': 'serial',
'is_storable': True,
'taxes_id': []
})
lot_1 = self.env['stock.lot'].create({
'name': '1001',
'product_id': self.twenty_dollars_no_tax.product_variant_id.id,
'company_id': self.env.company.id,
})
lot_2 = self.env['stock.lot'].create({
'name': '1002',
'product_id': self.twenty_dollars_no_tax.product_variant_id.id,
'company_id': self.env.company.id,
})
self.env['stock.quant'].with_context(inventory_mode=True).create({
'inventory_quantity': 1,
'product_id': self.twenty_dollars_no_tax.product_variant_id.id,
'location_id': self.stock_location.id,
'lot_id': lot_1.id
}).action_apply_inventory()
self.env['stock.quant'].with_context(inventory_mode=True).create({
'inventory_quantity': 1,
'product_id': self.twenty_dollars_no_tax.product_variant_id.id,
'location_id': self.stock_location.id,
'lot_id': lot_2.id
}).action_apply_inventory()
sale_order = self.env['sale.order'].sudo().create({
'partner_id': self.partner_stva.id,
'order_line': [(0, 0, {
'product_id': self.twenty_dollars_no_tax.product_variant_id.id,
'name': self.twenty_dollars_no_tax.product_variant_id.name,
'price_unit': self.twenty_dollars_no_tax.product_variant_id.lst_price,
'product_uom_qty': 2,
})],
})
sale_order.action_confirm()
order, _ = self.create_backend_pos_order({
'order_data': {
'partner_id': self.partner_stva.id,
'shipping_date': fields.Date.today(),
},
'line_data': [{
'product_id': self.twenty_dollars_no_tax.product_variant_id.id,
'pack_lot_ids': [[0, 0, {'lot_name': lot_1.name}]],
'sale_order_line_id': sale_order.order_line[0].id,
'sale_order_origin_id': sale_order.id,
}],
'payment_data': [
{'payment_method_id': self.pos_config_usd.payment_method_ids[0].id}
]
})
self.assertEqual(order.picking_ids.move_line_ids.lot_id, lot_1)

View file

@ -2,20 +2,31 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo
from odoo import fields
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
from odoo.addons.point_of_sale.tests.test_frontend import TestPointOfSaleHttpCommon
@odoo.tests.tagged('post_install', '-at_install')
class TestPoSSaleReport(TestPoSCommon):
class TestPoSSaleReport(TestPoSCommon, TestPointOfSaleHttpCommon):
def setUp(self):
super(TestPoSSaleReport, self).setUp()
self.config = self.basic_config
self.product0 = self.create_product('Product 0', self.categ_basic, 0.0, 0.0)
# Ensure that adding a uom to the product with a factor != 1
self.partner_1 = self.env['res.partner'].create({'name': 'Test Partner 1'})
# Ensure that adding a uom to the product with a factor != 1
# does not cause an error in weight and volume calculation
self.product0.uom_id = self.env['uom.uom'].search([('name', '=', 'Dozens')], limit=1)
self.uom_reference = self.env['uom.uom'].create({
'name': 'Reference Unit',
'relative_factor': 1,
})
self.uom_dozen = self.env['uom.uom'].create({
'name': 'Dozen',
'relative_factor': 12,
'relative_uom_id': self.uom_reference.id,
})
self.product0.uom_id = self.uom_dozen
def test_weight_and_volume(self):
self.product0.product_tmpl_id.weight = 3
@ -28,7 +39,7 @@ class TestPoSSaleReport(TestPoSCommon):
# Process two orders
orders.append(self.create_ui_order_data([(self.product0, 3)]))
orders.append(self.create_ui_order_data([(self.product0, 1)]))
self.env['pos.order'].create_from_ui(orders)
self.env['pos.order'].sync_from_ui(orders)
# Duplicate the first line of the first order
session.order_ids[0].lines.copy()
@ -41,6 +52,30 @@ class TestPoSSaleReport(TestPoSCommon):
self.assertEqual(reports[1].weight, 18)
self.assertEqual(reports[1].volume, 24)
def test_refund_line_report_prices_sign(self):
test_product = self.env['product.product'].create({
'name': 'Test Product',
'list_price': 10.00,
'taxes_id': False,
'available_in_pos': True,
})
self.main_pos_config.with_user(self.pos_user).open_ui()
current_session = self.main_pos_config.current_session_id
self.start_tour("/pos/ui/%d" % self.main_pos_config.id, 'refund_multiple_products_amounts_compliance', login="pos_user")
total_cash_payment = sum(current_session.mapped('order_ids.payment_ids').filtered(
lambda payment: payment.payment_method_id.type == 'cash').mapped('amount')
)
current_session.post_closing_cash_details(total_cash_payment)
current_session.close_session_from_ui()
self.assertEqual(current_session.state, 'closed')
report = self.env['sale.report'].sudo().search([('product_id', '=', test_product.id), ('name', 'ilike', '% REFUND')], order='id', limit=1)
self.assertEqual(report.product_uom_qty, -2)
self.assertEqual(report.price_subtotal, report.product_uom_qty * test_product.list_price)
self.assertEqual(report.price_total, report.price_subtotal)
def test_weight_and_volume_product_variant(self):
colors = ['red', 'blue']
prod_attr = self.env['product.attribute'].create({'name': 'Color', 'create_variant': 'dynamic'})
@ -50,7 +85,6 @@ class TestPoSSaleReport(TestPoSCommon):
product_template = self.env['product.template'].create({
'name': 'Sofa',
'uom_id': uom_unit.id,
'uom_po_id': uom_unit.id,
'attribute_line_ids': [(0, 0, {
'attribute_id': prod_attr.id,
'value_ids': [(6, 0, prod_attr_values.ids)]
@ -73,7 +107,7 @@ class TestPoSSaleReport(TestPoSCommon):
session = self.pos_session
order = self.create_ui_order_data([(product_1, 3), (product_2, 3)])
self.env['pos.order'].create_from_ui([order])
self.env['pos.order'].sync_from_ui([order])
session.action_pos_session_closing_control()
@ -86,22 +120,71 @@ class TestPoSSaleReport(TestPoSCommon):
def test_different_shipping_address(self):
product_0 = self.create_product('Product 0', self.categ_basic, 0.0, 0.0)
partner_1 = self.env['res.partner'].create({'name': 'Test Partner 1'})
partner_2 = self.env['res.partner'].create({'name': 'Test Partner 2'})
sale_order = self.env['sale.order'].create({
'partner_id': partner_1.id,
'partner_shipping_id': partner_2.id,
sale_order = self.env['sale.order'].sudo().create({
'partner_id': self.customer.id,
'partner_shipping_id': self.other_customer.id,
'order_line': [(0, 0, {
'product_id': product_0.id,
})],
})
self.open_new_session()
data = self.create_ui_order_data([(product_0, 1)], partner_1, True)
data['data']['lines'][0][2]['sale_order_origin_id'] = sale_order.read()[0]
data['data']['lines'][0][2]['sale_order_line_id'] = sale_order.order_line[0].read()[0]
order_ids = self.env['pos.order'].create_from_ui([data])
data = self.create_ui_order_data([(product_0, 1)], {}, self.customer, True)
data['lines'][0][2]['sale_order_origin_id'] = sale_order.id
data['lines'][0][2]['sale_order_line_id'] = sale_order.order_line[0].id
order_ids = self.env['pos.order'].sync_from_ui([data])
move_id = self.env['account.move'].browse(order_ids[0]['account_move'])
self.assertEqual(move_id.partner_id.id, partner_1.id)
self.assertEqual(move_id.partner_shipping_id.id, partner_2.id)
move_id = self.env['account.move'].browse(order_ids['pos.order'][0]['account_move'])
self.assertEqual(move_id.partner_id.id, self.customer.id)
self.assertEqual(move_id.partner_shipping_id.id, self.other_customer.id)
def test_warehouse(self):
self.open_new_session()
session = self.pos_session
orders = []
# Process two orders
orders.append(self.create_ui_order_data([(self.product0, 3)]))
self.env['pos.order'].sync_from_ui(orders)
session.action_pos_session_closing_control()
reports = self.env['sale.report'].sudo().search([('product_id', '=', self.product0.id)], order='id', limit=2)
self.assertEqual(reports[0].warehouse_id.id, self.config.picking_type_id.warehouse_id.id)
def test_qty_deliverd_qty_to_deliver_in_sales_report(self):
"""
Track the quantity of products ordered based on their picking state. for example : If an order is created for 3 products
with the option to ship later, the products will be listed under qty_to_deliver in the sales report until the picking state
is validated. Once validated and marked as done, the quantity will shift to qty_delivered.
"""
self.config.ship_later = True
self.open_new_session()
session = self.pos_session
orders = []
orders.append(self.create_ui_order_data([(self.product0, 5, 100), (self.product0, 3)], {}, self.partner_1))
orders[0]['shipping_date'] = fields.Date.to_string(fields.Date.today())
order = self.env['pos.order'].sync_from_ui(orders)
order = self.env['pos.order'].browse(order['pos.order'][0]['id'])
session.action_pos_session_closing_control()
report = self.env['sale.report'].sudo().search([('product_id', '=', self.product0.id)], order='id')
self.assertEqual(sum(report.mapped('qty_to_deliver')), 8)
self.assertEqual(sum(report.mapped('qty_delivered')), 0)
order.picking_ids.move_ids.quantity = 8.0
order.picking_ids.button_validate()
# flush computations and clear the cache before checking again the report
self.env.flush_all()
self.env.clear()
report = self.env['sale.report'].sudo().search([('product_id', '=', self.product0.id)], order='id')
self.assertEqual(sum(report.mapped('qty_to_deliver')), 0)
self.assertEqual(sum(report.mapped('qty_delivered')), 8)

View file

@ -0,0 +1,128 @@
from odoo import Command
from odoo.addons.account.tests.test_taxes_downpayment import TestTaxesDownPayment
from odoo.addons.point_of_sale.tests.test_frontend import TestTaxCommonPOS
from odoo.addons.sale.tests.common import TestTaxCommonSale
from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestTaxesDownPaymentPOS(TestTaxCommonPOS, TestTaxCommonSale, TestTaxesDownPayment):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.main_pos_config.down_payment_product_id = cls.env['product.product'].create({
'name': 'downpayment',
'available_in_pos': True,
'pos_categ_ids': [Command.set(cls.pos_desk_misc_test.ids)],
})
cls.main_pos_config.pricelist_id = None
cls.main_pos_config.available_pricelist_ids = [Command.clear()]
def assert_pos_orders_and_invoices(self, tour, tests_with_orders):
all_so = self.env['sale.order']
for _test_code, document, _soft_checking, _amount_type, _amount, _expected_values in tests_with_orders:
so = self.convert_document_to_sale_order(document)
so.currency_id = self.env.company.currency_id # No foreign currency in the POS
so.action_confirm()
all_so += so
super().assert_pos_orders_and_invoices(tour, tests_with_orders)
all_so.action_cancel()
def test_taxes_l10n_in_pos(self):
tests = self._test_taxes_l10n_in()
round_per_line_excluded_tests = [next(tests) for _i in range(22)]
self.ensure_products_on_document(round_per_line_excluded_tests[0][1], 'product_1')
self.assert_pos_orders_and_invoices('test_taxes_l10n_in_pos_downpayment_round_per_line_price_excluded', [
round_per_line_excluded_tests[19],
round_per_line_excluded_tests[18],
round_per_line_excluded_tests[7],
round_per_line_excluded_tests[6],
round_per_line_excluded_tests[1],
round_per_line_excluded_tests[0],
])
round_globally_excluded_tests = [next(tests) for _i in range(22)]
self.ensure_products_on_document(round_globally_excluded_tests[0][1], 'product_2')
self.assert_pos_orders_and_invoices('test_taxes_l10n_in_pos_downpayment_round_globally_price_excluded', [
round_globally_excluded_tests[19],
round_globally_excluded_tests[18],
round_globally_excluded_tests[7],
round_globally_excluded_tests[6],
round_globally_excluded_tests[1],
round_globally_excluded_tests[0],
])
round_per_line_included_tests = [next(tests) for _i in range(22)]
self.ensure_products_on_document(round_per_line_included_tests[0][1], 'product_3')
self.assert_pos_orders_and_invoices('test_taxes_l10n_in_pos_downpayment_round_per_line_price_included', [
round_per_line_included_tests[19],
round_per_line_included_tests[18],
round_per_line_included_tests[7],
round_per_line_included_tests[6],
round_per_line_included_tests[1],
round_per_line_included_tests[0],
])
round_globally_included_tests = [next(tests) for _i in range(22)]
self.ensure_products_on_document(round_globally_included_tests[0][1], 'product_4')
self.assert_pos_orders_and_invoices('test_taxes_l10n_in_pos_downpayment_round_globally_price_included', [
round_globally_included_tests[19],
round_globally_included_tests[18],
round_globally_included_tests[7],
round_globally_included_tests[6],
round_globally_included_tests[1],
round_globally_included_tests[0],
])
def test_taxes_l10n_br_pos(self):
tests = self._test_taxes_l10n_br()
round_per_line_excluded_tests = [next(tests) for _i in range(19)]
self.ensure_products_on_document(round_per_line_excluded_tests[0][1], 'product_1')
self.assert_pos_orders_and_invoices('test_taxes_l10n_br_pos_downpayment_round_per_line_price_excluded', [
round_per_line_excluded_tests[0],
])
round_globally_excluded_tests = [next(tests) for _i in range(19)]
self.ensure_products_on_document(round_globally_excluded_tests[0][1], 'product_2')
self.assert_pos_orders_and_invoices('test_taxes_l10n_br_pos_downpayment_round_globally_price_excluded', [
round_globally_excluded_tests[0],
])
round_per_line_included_tests = [next(tests) for _i in range(19)]
self.ensure_products_on_document(round_per_line_included_tests[0][1], 'product_3')
self.assert_pos_orders_and_invoices('test_taxes_l10n_br_pos_downpayment_round_per_line_price_included', [
round_per_line_included_tests[0],
])
round_globally_included_tests = [next(tests) for _i in range(19)]
self.ensure_products_on_document(round_globally_included_tests[0][1], 'product_4')
self.assert_pos_orders_and_invoices('test_taxes_l10n_br_pos_downpayment_round_globally_price_included', [
round_globally_included_tests[0],
])
def test_taxes_l10n_be_pos(self):
tests = self._test_taxes_l10n_be()
round_per_line_excluded_tests = [next(tests) for _i in range(19)]
self.ensure_products_on_document(round_per_line_excluded_tests[0][1], 'product_1')
self.assert_pos_orders_and_invoices('test_taxes_l10n_be_pos_downpayment_round_per_line_price_excluded', [
round_per_line_excluded_tests[0],
])
round_globally_excluded_tests = [next(tests) for _i in range(19)]
self.ensure_products_on_document(round_globally_excluded_tests[0][1], 'product_2')
self.assert_pos_orders_and_invoices('test_taxes_l10n_be_pos_downpayment_round_globally_price_excluded', [
round_globally_excluded_tests[0],
])
round_per_line_included_tests = [next(tests) for _i in range(19)]
self.ensure_products_on_document(round_per_line_included_tests[0][1], 'product_3')
self.assert_pos_orders_and_invoices('test_taxes_l10n_be_pos_downpayment_round_per_line_price_included', [
round_per_line_included_tests[0],
])
round_globally_included_tests = [next(tests) for _i in range(19)]
self.ensure_products_on_document(round_globally_included_tests[0][1], 'product_4')
self.assert_pos_orders_and_invoices('test_taxes_l10n_be_pos_downpayment_round_globally_price_included', [
round_globally_included_tests[0],
])