123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- # -*- coding: utf-8 -*-
- # Part of Odoo. See LICENSE file for full copyright and licensing details.
- import odoo
- from odoo.addons.point_of_sale.tests.test_frontend import TestPointOfSaleHttpCommon
- from odoo.tests.common import Form
- @odoo.tests.tagged('post_install', '-at_install')
- class TestPoSSale(TestPointOfSaleHttpCommon):
- def test_settle_order_with_kit(self):
- if not self.env["ir.module.module"].search([("name", "=", "mrp"), ("state", "=", "installed")]):
- self.skipTest("mrp module is required for this test")
- self.kit = self.env['product.product'].create({
- 'name': 'Pizza Chicken',
- 'available_in_pos': True,
- 'type': 'product',
- 'lst_price': 10.0,
- })
- self.component_a = self.env['product.product'].create({
- 'name': 'Chicken',
- 'type': 'product',
- 'available_in_pos': True,
- 'uom_id': self.env.ref('uom.product_uom_gram').id,
- 'uom_po_id': self.env.ref('uom.product_uom_gram').id,
- 'lst_price': 10.0,
- })
- self.location = self.env['stock.location'].create({
- 'name': 'Test location',
- 'usage': 'internal',
- })
- self.env['stock.quant']._update_available_quantity(self.component_a, self.location, 100000)
- bom_product_form = Form(self.env['mrp.bom'])
- bom_product_form.product_id = self.kit
- bom_product_form.product_tmpl_id = self.kit.product_tmpl_id
- bom_product_form.product_qty = 1.0
- bom_product_form.type = 'phantom'
- with bom_product_form.bom_line_ids.new() as bom_line:
- bom_line.product_id = self.component_a
- bom_line.product_qty = 300.0
- self.bom_a = bom_product_form.save()
- sale_order = self.env['sale.order'].create({
- 'partner_id': self.env.ref('base.res_partner_2').id,
- 'order_line': [(0, 0, {
- 'product_id': self.kit.id,
- 'name': self.kit.name,
- 'product_uom_qty': 10,
- 'product_uom': self.kit.uom_id.id,
- 'price_unit': self.kit.lst_price,
- })],
- })
- sale_order.action_confirm()
- picking = sale_order.picking_ids
- picking.move_ids.quantity_done = 300
- action = picking.button_validate()
- wizard = Form(self.env[action['res_model']].with_context(action['context']))
- wizard.save().process()
- self.assertEqual(sale_order.order_line.qty_delivered, 1)
- self.main_pos_config.open_ui()
- self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrder', login="accountman")
- #assert that sales order qty are correctly updated
- self.assertEqual(sale_order.order_line.qty_delivered, 3)
- self.assertEqual(sale_order.picking_ids[0].move_ids.product_qty, 2100) # 7 left to deliver => 300 * 7 = 2100
- self.assertEqual(sale_order.picking_ids[0].move_ids.quantity_done, 0)
- self.assertEqual(sale_order.picking_ids[1].move_ids.product_qty, 300)
- self.assertEqual(sale_order.picking_ids[1].move_ids.quantity_done, 300) # 1 delivered => 300 * 2 = 600
- def test_settle_order_with_incompatible_partner(self):
- """ If the partner of the sale order is not compatible with the current pos order,
- then a new pos order should be to settle the newly selected sale order.
- """
- product1 = self.env['product.product'].create({
- 'name': 'product1',
- 'available_in_pos': True,
- 'type': 'product',
- 'lst_price': 10,
- 'taxes_id': [odoo.Command.clear()],
- })
- product2 = self.env['product.product'].create({
- 'name': 'product2',
- 'available_in_pos': True,
- 'type': 'product',
- 'lst_price': 11,
- 'taxes_id': [odoo.Command.clear()],
- })
- self.env['sale.order'].create({
- 'partner_id': self.env.ref('base.res_partner_1').id,
- 'partner_shipping_id': self.env.ref('base.res_partner_2').id,
- 'order_line': [(0, 0, {'product_id': product1.id})],
- })
- self.env['sale.order'].create({
- 'partner_id': self.env.ref('base.res_partner_1').id,
- 'partner_shipping_id': self.env.ref('base.res_partner_1').id,
- 'order_line': [(0, 0, {'product_id': product2.id})],
- })
- self.main_pos_config.open_ui()
- self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrderIncompatiblePartner', login="accountman")
- def test_settle_order_with_different_product(self):
- """This test create an order and settle it in the PoS. But only one of the product is delivered.
- And we need to make sure the quantity are correctly updated on the sale order.
- """
- #create 2 products
- product_a = self.env['product.product'].create({
- 'name': 'Product A',
- 'available_in_pos': True,
- 'type': 'product',
- 'lst_price': 10.0,
- })
- product_b = self.env['product.product'].create({
- 'name': 'Product B',
- 'available_in_pos': True,
- 'type': 'product',
- 'lst_price': 10.0,
- })
- #create a sale order with 2 lines
- sale_order = self.env['sale.order'].create({
- 'partner_id': self.env.ref('base.res_partner_2').id,
- 'order_line': [(0, 0, {
- 'product_id': product_a.id,
- 'name': product_a.name,
- 'product_uom_qty': 1,
- 'product_uom': product_a.uom_id.id,
- 'price_unit': product_a.lst_price,
- }), (0, 0, {
- 'product_id': product_b.id,
- 'name': product_b.name,
- 'product_uom_qty': 1,
- 'product_uom': product_b.uom_id.id,
- 'price_unit': product_b.lst_price,
- })],
- })
- sale_order.action_confirm()
- self.assertEqual(sale_order.order_line[0].qty_delivered, 0)
- self.assertEqual(sale_order.order_line[1].qty_delivered, 0)
- self.main_pos_config.open_ui()
- self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrder2', login="accountman")
- self.assertEqual(sale_order.order_line[0].qty_delivered, 1)
- self.assertEqual(sale_order.order_line[1].qty_delivered, 0)
- orderline_product_a = sale_order.order_line.filtered(lambda l: l.product_id.id == product_a.id)
- orderline_product_b = sale_order.order_line.filtered(lambda l: l.product_id.id == product_b.id)
- # nothing to deliver for product a because already handled in pos.
- self.assertEqual(orderline_product_a.move_ids.product_uom_qty, 0)
- # 1 item to deliver for product b.
- self.assertEqual(orderline_product_b.move_ids.product_uom_qty, 1)
- def test_settle_order_unreserve_order_lines(self):
- #create a product category that use the closest location for the removal strategy
- self.removal_strategy = self.env['product.removal'].search([('method', '=', 'closest')], limit=1)
- self.product_category = self.env['product.category'].create({
- 'name': 'Product Category',
- 'removal_strategy_id': self.removal_strategy.id,
- })
- self.product = self.env['product.product'].create({
- 'name': 'Product',
- 'available_in_pos': True,
- 'type': 'product',
- 'lst_price': 10.0,
- 'taxes_id': False,
- 'categ_id': self.product_category.id,
- })
- #create 2 stock location Shelf 1 and Shelf 2
- self.warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1)
- self.shelf_1 = self.env['stock.location'].create({
- 'name': 'Shelf 1',
- 'usage': 'internal',
- 'location_id': self.warehouse.lot_stock_id.id,
- })
- self.shelf_2 = self.env['stock.location'].create({
- 'name': 'Shelf 2',
- 'usage': 'internal',
- 'location_id': self.warehouse.lot_stock_id.id,
- })
- quants = self.env['stock.quant'].with_context(inventory_mode=True).create({
- 'product_id': self.product.id,
- 'inventory_quantity': 2,
- 'location_id': self.shelf_1.id,
- })
- quants |= self.env['stock.quant'].with_context(inventory_mode=True).create({
- 'product_id': self.product.id,
- 'inventory_quantity': 5,
- 'location_id': self.shelf_2.id,
- })
- quants.action_apply_inventory()
- sale_order = self.env['sale.order'].create({
- 'partner_id': self.env.ref('base.res_partner_2').id,
- 'order_line': [(0, 0, {
- 'product_id': self.product.id,
- 'name': self.product.name,
- 'product_uom_qty': 4,
- 'price_unit': self.product.lst_price,
- })],
- })
- sale_order.action_confirm()
- self.assertEqual(sale_order.order_line.move_ids.move_line_ids[0].reserved_qty, 2)
- self.assertEqual(sale_order.order_line.move_ids.move_line_ids[0].location_id.id, self.shelf_1.id)
- self.assertEqual(sale_order.order_line.move_ids.move_line_ids[1].reserved_qty, 2)
- self.assertEqual(sale_order.order_line.move_ids.move_line_ids[1].location_id.id, self.shelf_2.id)
- self.config = self.env['res.config.settings'].create({
- 'update_stock_quantities': 'real',
- })
- self.config.execute()
- self.main_pos_config.open_ui()
- self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrderRealTime', login="accountman")
- pos_order = self.env['pos.order'].search([], order='id desc', limit=1)
- self.assertEqual(pos_order.picking_ids.move_line_ids[0].qty_done, 2)
- self.assertEqual(pos_order.picking_ids.move_line_ids[0].location_id.id, self.shelf_1.id)
- self.assertEqual(pos_order.picking_ids.move_line_ids[1].qty_done, 2)
- self.assertEqual(pos_order.picking_ids.move_line_ids[1].location_id.id, self.shelf_2.id)
- self.assertEqual(sale_order.order_line.move_ids.move_lines_count, 0)
- def test_downpayment_refund(self):
- #create a sale order
- sale_order = self.env['sale.order'].create({
- 'partner_id': self.env.ref('base.res_partner_2').id,
- 'order_line': [(0, 0, {
- 'product_id': self.product_a.id,
- 'name': self.product_a.name,
- 'product_uom_qty': 1,
- 'price_unit': 100,
- 'product_uom': self.product_a.uom_id.id
- })],
- })
- sale_order.action_confirm()
- #set downpayment product in pos config
- self.downpayment_product = self.env['product.product'].create({
- 'name': 'Down Payment',
- 'available_in_pos': True,
- 'type': 'service',
- })
- self.main_pos_config.write({
- 'down_payment_product_id': self.downpayment_product.id,
- })
- self.main_pos_config.open_ui()
- self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosRefundDownpayment', login="accountman")
- self.assertEqual(len(sale_order.order_line), 3)
- self.assertEqual(sale_order.order_line[1].qty_invoiced, 1)
- self.assertEqual(sale_order.order_line[2].qty_invoiced, -1)
- def test_settle_order_with_multistep_delivery(self):
- """This test create an order and settle it in the PoS. It also uses multistep delivery
- and we need to make sure that all the picking are cancelled if the order is fully delivered.
- """
- #get the warehouse
- warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1)
- warehouse.delivery_steps = 'pick_pack_ship'
- product_a = self.env['product.product'].create({
- 'name': 'Product A',
- 'available_in_pos': True,
- 'type': 'product',
- 'lst_price': 10.0,
- })
- #create a sale order with 2 lines
- sale_order = self.env['sale.order'].create({
- 'partner_id': self.env.ref('base.res_partner_2').id,
- 'order_line': [(0, 0, {
- 'product_id': product_a.id,
- 'name': product_a.name,
- 'product_uom_qty': 1,
- 'product_uom': product_a.uom_id.id,
- 'price_unit': product_a.lst_price,
- })],
- })
- sale_order.action_confirm()
- self.assertEqual(sale_order.order_line[0].qty_delivered, 0)
- self.main_pos_config.open_ui()
- self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrder3', login="accountman")
- self.assertEqual(sale_order.order_line[0].qty_delivered, 1)
- self.assertEqual(sale_order.picking_ids.mapped('state'), ['cancel', 'cancel', 'cancel'])
- def test_pos_not_groupable_product(self):
- #Create a UoM Category that is not pos_groupable
- uom_category = self.env['uom.category'].create({
- 'name': 'Test',
- 'is_pos_groupable': False,
- })
- uom = self.env['uom.uom'].create({
- 'name': 'Test',
- 'category_id': uom_category.id,
- 'uom_type': 'reference',
- })
- product_a = self.env['product.product'].create({
- 'name': 'Product A',
- 'available_in_pos': True,
- 'type': 'product',
- 'lst_price': 10.0,
- 'uom_id': uom.id,
- 'uom_po_id': uom.id,
- })
- #create a sale order with product_a
- self.env['sale.order'].create({
- 'partner_id': self.env.ref('base.res_partner_2').id,
- 'order_line': [(0, 0, {
- 'product_id': product_a.id,
- 'name': product_a.name,
- 'product_uom_qty': 3,
- 'product_uom': product_a.uom_id.id,
- 'price_unit': product_a.lst_price,
- })],
- })
- self.main_pos_config.open_ui()
- self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrderNotGroupable', login="accountman")
|