diff --git a/addons/stock_dropshipping/tests/test_crossdock.py b/addons/stock_dropshipping/tests/test_crossdock.py index a1a8225661d..3902ffcb9d7 100644 --- a/addons/stock_dropshipping/tests/test_crossdock.py +++ b/addons/stock_dropshipping/tests/test_crossdock.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.tests import common +from odoo.tests import common, Form class TestCrossdock(common.TransactionCase): @@ -12,12 +12,12 @@ class TestCrossdock(common.TransactionCase): supplier_crossdock = self.env['res.partner'].create({'name': "Crossdocking supplier"}) # I first create a warehouse with pick-pack-ship and reception in 2 steps - wh_pps = self.env['stock.warehouse'].create({ - 'name': 'WareHouse PickPackShip', - 'code': 'whpps', - 'reception_steps': 'two_steps', - 'delivery_steps': 'pick_pack_ship' - }) + wh_f = Form(self.env['stock.warehouse']) + wh_f.name = 'WareHouse PickPackShip' + wh_f.code = 'whpps' + wh_f.reception_steps = 'two_steps' + wh_f.delivery_steps = 'pick_pack_ship' + wh_pps = wh_f.save() # Check that cross-dock route is active self.assertTrue(wh_pps.crossdock_route_id.active, @@ -38,17 +38,13 @@ class TestCrossdock(common.TransactionCase): }) # Create a sales order with a line of 100 PCE incoming shipment with route_id crossdock shipping - sale_order_crossdock = self.env['sale.order'].create({ - 'partner_id': self.env.ref('base.res_partner_4').id, - 'warehouse_id': wh_pps.id, - 'note': 'Create Sales Order', - 'order_line': [(0, 0, { - 'product_id': cross_shop_product.id, - 'product_uom_qty': 100.0, - 'product_uom': self.env.ref('product.product_uom_unit').id, - 'route_id': wh_pps.crossdock_route_id.id, - })] - }) + so_form = Form(self.env['sale.order']) + so_form.partner_id = self.env.ref('base.res_partner_4') + so_form.warehouse_id = wh_pps + with so_form.order_line.new() as line: + line.product_id = cross_shop_product + line.product_uom_qty = 100.0 + sale_order_crossdock = so_form.save() # Confirm sales order sale_order_crossdock.action_confirm() diff --git a/addons/stock_dropshipping/tests/test_dropship.py b/addons/stock_dropshipping/tests/test_dropship.py index 4ab4726f8cb..5faacdb78a3 100644 --- a/addons/stock_dropshipping/tests/test_dropship.py +++ b/addons/stock_dropshipping/tests/test_dropship.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.tests import common +from odoo.tests import common, Form class TestDropship(common.TransactionCase): @@ -16,7 +16,7 @@ class TestDropship(common.TransactionCase): 'name': "Pen drive", 'type': "product", 'categ_id': self.env.ref('product.product_category_1').id, - 'list_price': 100.0, + 'lst_price': 100.0, 'standard_price': 0.0, 'uom_id': self.env.ref('product.product_uom_unit').id, 'uom_po_id': self.env.ref('product.product_uom_unit').id, @@ -28,17 +28,15 @@ class TestDropship(common.TransactionCase): }) # Create a sales order with a line of 200 PCE incoming shipment, with route_id drop shipping - sale_order_drp_shpng = self.env['sale.order'].create({ - 'partner_id': self.env.ref('base.res_partner_2').id, - 'note': 'Create sale order for drop shipping', - 'payment_term_id': self.env.ref('account.account_payment_term').id, - 'order_line': [(0, 0, { - 'product_id': drop_shop_product.id, - 'product_uom_qty': 200, - 'price_unit': 1.00, - 'route_id': self.env.ref('stock_dropshipping.route_drop_shipping').id, - })] - }) + so_form = Form(self.env['sale.order']) + so_form.partner_id = self.env.ref('base.res_partner_2') + so_form.payment_term_id = self.env.ref('account.account_payment_term') + with so_form.order_line.new() as line: + line.product_id = drop_shop_product + line.product_uom_qty = 200 + line.price_unit = 1.00 + line.route_id = self.env.ref('stock_dropshipping.route_drop_shipping') + sale_order_drp_shpng = so_form.save() # Confirm sales order sale_order_drp_shpng.action_confirm() diff --git a/addons/stock_dropshipping/tests/test_lifo_price.py b/addons/stock_dropshipping/tests/test_lifo_price.py index 7c39c95a3fa..b2d419aa2c4 100644 --- a/addons/stock_dropshipping/tests/test_lifo_price.py +++ b/addons/stock_dropshipping/tests/test_lifo_price.py @@ -3,9 +3,11 @@ import time +from datetime import date + from odoo import tools from odoo.modules.module import get_module_resource -from odoo.tests import common +from odoo.tests import common, Form class TestLifoPrice(common.TransactionCase): @@ -26,49 +28,46 @@ class TestLifoPrice(common.TransactionCase): product_category_001 = self.env['product.category'].create({ 'name': 'Lifo Category', 'removal_strategy_id': self.env.ref('stock.removal_lifo').id, + 'property_valuation': 'real_time', + 'property_cost_method': 'fifo', }) # Set a product as using lifo price - product_lifo_icecream = self.env['product.product'].create({ - 'default_code': 'LIFO', - 'name': 'LIFO Ice Cream', - 'type': 'product', - 'categ_id': product_category_001.id, - 'list_price': 100.0, - 'standard_price': 70.0, - 'uom_id': self.env.ref('product.product_uom_kgm').id, - 'uom_po_id': self.env.ref('product.product_uom_kgm').id, - 'valuation': 'real_time', - 'cost_method': 'fifo', - 'property_stock_account_input': self.env.ref('stock_dropshipping.o_expense').id, - 'property_stock_account_output': self.env.ref('stock_dropshipping.o_income').id, - }) + product_form = Form(self.env['product.product']) + product_form.default_code = 'LIFO' + product_form.name = 'LIFO Ice Cream' + product_form.type = 'product' + product_form.categ_id = product_category_001 + product_form.lst_price = 100.0 + product_form.standard_price = 70.0 + product_form.uom_id = self.env.ref('product.product_uom_kgm') + product_form.uom_po_id = self.env.ref('product.product_uom_kgm') + # these are not available (visible) in either product or variant + # for views, apparently from the UI you can only set the product + # category (or hand-assign the property_* version which seems...) + # product_form.valuation = 'real_time' + # product_form.cost_method = 'fifo' + product_form.property_stock_account_input = self.env.ref('stock_dropshipping.o_expense') + product_form.property_stock_account_output = self.env.ref('stock_dropshipping.o_income') + product_lifo_icecream = product_form.save() # I create a draft Purchase Order for first in move for 10 pieces at 60 euro - purchase_order_lifo1 = self.env['purchase.order'].create({ - 'partner_id': self.env.ref('base.res_partner_3').id, - 'order_line': [(0, 0, { - 'product_id': product_lifo_icecream.id, - 'product_qty': 10.0, - 'product_uom': self.env.ref('product.product_uom_kgm').id, - 'price_unit': 60.0, - 'name': 'LIFO Ice Cream', - 'date_planned': time.strftime('%Y-%m-%d'), - })] - }) + order_form = Form(self.env['purchase.order']) + order_form.partner_id = self.env.ref('base.res_partner_3') + with order_form.order_line.new() as line: + line.product_id = product_lifo_icecream + line.product_qty = 10.0 + line.price_unit = 60.0 + purchase_order_lifo1 = order_form.save() # I create a draft Purchase Order for second shipment for 30 pieces at 80 euro - purchase_order_lifo2 = self.env['purchase.order'].create({ - 'partner_id': self.env.ref('base.res_partner_3').id, - 'order_line': [(0, 0, { - 'product_id': product_lifo_icecream.id, - 'product_qty': 30.0, - 'product_uom': self.env.ref('product.product_uom_kgm').id, - 'price_unit': 80.0, - 'name': 'LIFO Ice Cream', - 'date_planned': time.strftime('%Y-%m-%d'), - })] - }) + order2_form = Form(self.env['purchase.order']) + order2_form.partner_id = self.env.ref('base.res_partner_3') + with order2_form.order_line.new() as line: + line.product_id = product_lifo_icecream + line.product_qty = 30.0 + line.price_unit = 80.0 + purchase_order_lifo2 = order2_form.save() # I confirm the first purchase order purchase_order_lifo1.button_confirm() @@ -88,28 +87,16 @@ class TestLifoPrice(common.TransactionCase): purchase_order_lifo2.picking_ids[0].button_validate() # Let us send some goods - outgoing_lifo_shipment = self.env['stock.picking'].new({ - 'picking_type_id': self.env.ref('stock.picking_type_out').id, - }) - outgoing_lifo_shipment.onchange_picking_type() - vals = outgoing_lifo_shipment._convert_to_write(outgoing_lifo_shipment._cache) - outgoing_lifo_shipment = self.env['stock.picking'].create(vals) - - # Picking needs movement from stock, outgoing_shipment_lifo_icecream - self.env['stock.move'].create({ - 'name': product_lifo_icecream.name, - 'product_id': product_lifo_icecream.id, - 'picking_id': outgoing_lifo_shipment.id, - 'product_uom': self.env.ref('product.product_uom_kgm').id, - 'location_id': self.env.ref('stock.stock_location_stock').id, - 'location_dest_id': self.env.ref('stock.stock_location_customers').id, - 'product_uom_qty': 20.0, - 'picking_type_id': self.env.ref('stock.picking_type_out').id, - }) + out_form = Form(self.env['stock.picking']) + out_form.picking_type_id = self.env.ref('stock.picking_type_out') + out_form.scheduled_date = date.today().strftime('%Y-%m-%d') + with out_form.move_lines.new() as move: + move.product_id = product_lifo_icecream + move.quantity_done = 20.0 + outgoing_lifo_shipment = out_form.save() # I assign this outgoing shipment outgoing_lifo_shipment.action_assign() - outgoing_lifo_shipment.move_lines.quantity_done = outgoing_lifo_shipment.move_lines.product_qty # Process the delivery of the outgoing shipment outgoing_lifo_shipment.button_validate() diff --git a/addons/stock_dropshipping/tests/test_procurement_exception.py b/addons/stock_dropshipping/tests/test_procurement_exception.py index a14539818c2..3e9921a6e8c 100644 --- a/addons/stock_dropshipping/tests/test_procurement_exception.py +++ b/addons/stock_dropshipping/tests/test_procurement_exception.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.tests import common +from odoo.tests import common, Form class TestProcurementException(common.TransactionCase): @@ -9,39 +9,35 @@ class TestProcurementException(common.TransactionCase): def test_00_procurement_exception(self): # I create a product with no supplier define for it. - product_with_no_seller = self.env['product.product'].create({ - "name": 'product with no seller', - 'list_price': 20.00, - 'standard_price': 15.00, - 'categ_id': self.env.ref('product.product_category_1').id, - }) + product_form = Form(self.env['product.product']) + product_form.name = 'product with no seller' + product_form.lst_price = 20.00 + product_form.standard_price = 15.00 + product_form.categ_id = self.env.ref('product.product_category_1') + product_with_no_seller = product_form.save() # I create a sales order with this product with route dropship. - sale_order_route_dropship01 = self.env['sale.order'].create({ - 'partner_id': self.env.ref('base.res_partner_2').id, - 'partner_invoice_id': self.env.ref('base.res_partner_address_3').id, - 'partner_shipping_id': self.env.ref('base.res_partner_address_3').id, - 'note': 'crossdock route', - 'payment_term_id': self.env.ref('account.account_payment_term').id, - 'order_line': [(0, 0, { - 'product_id': product_with_no_seller.id, - 'product_uom_qty': 1, - 'route_id': self.env.ref('stock_dropshipping.route_drop_shipping').id, - })] - }) + so_form = Form(self.env['sale.order']) + so_form.partner_id = self.env.ref('base.res_partner_2') + so_form.partner_invoice_id = self.env.ref('base.res_partner_address_3') + so_form.partner_shipping_id = self.env.ref('base.res_partner_address_3') + so_form.payment_term_id = self.env.ref('account.account_payment_term') + with so_form.order_line.new() as line: + line.product_id = product_with_no_seller + line.product_uom_qty = 1 + line.route_id = self.env.ref('stock_dropshipping.route_drop_shipping') + sale_order_route_dropship01 = so_form.save() # I confirm the sales order, but it will raise an error with self.assertRaises(Exception): sale_order_route_dropship01.action_confirm() # I set the at least one supplier on the product. - product_with_no_seller.write({ - 'seller_ids': [(0, 0, { - 'delay': 1, - 'name': self.env.ref('base.res_partner_2').id, - 'min_qty': 2.0 - })] - }) + with Form(product_with_no_seller) as f: + with f.seller_ids.new() as seller: + seller.delay = 1 + seller.name = self.env.ref('base.res_partner_2') + seller.min_qty = 2.0 # I confirm the sales order, no error this time sale_order_route_dropship01.action_confirm() diff --git a/odoo/tests/common.py b/odoo/tests/common.py index 53c30b8db5f..c7a48c5eddd 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -19,14 +19,15 @@ import threading import time import unittest from contextlib import contextmanager -from datetime import datetime, timedelta +from datetime import datetime, timedelta, date from pprint import pformat import requests from lxml import etree, html from odoo.models import BaseModel -from odoo.tools import pycompat, safe_eval +from odoo.tools import pycompat +from odoo.tools.safe_eval import safe_eval try: from itertools import zip_longest as izip_longest @@ -579,6 +580,13 @@ class Form(object): else: self._init_from_defaults(self._model) + def __str__(self): + return "<%s %s(%s)>" % ( + type(self).__name__, + self._model._name, + self._values.get('id', False), + ) + def _process_fvg(self, model, fvg): """ Post-processes to augment the fields_view_get with: @@ -687,7 +695,23 @@ class Form(object): if not c: return {} - return safe_eval(c, self._values) + # see _getEvalContext + # the context for a field's evals (of domain/context) is the composition of: + # * the parent's values + # * ??? element.context ??? + # * the environment's context (?) + # * a few magic values + record_id = self._values.get('id') or False + ctx = dict(self._values) + ctx.update(self._env.context) + ctx.update( + id=record_id, + active_id=record_id, + active_ids=[record_id] if record_id else [], + active_model=self._model._name, + current_date=date.today().strftime("%Y-%m-%d"), + ) + return safe_eval(c, ctx, {'context': ctx}) def __setattr__(self, field, value): descr = self._view['fields'].get(field) @@ -712,8 +736,9 @@ class Form(object): # q: how to get recordset? def __enter__(self): return self - def __exit__(self, *_): - self.save() + def __exit__(self, etype, _evalue, _etb): + if not etype: + self.save() def save(self): id_ = self._values.get('id') @@ -852,8 +877,10 @@ class O2MForm(Form): def _onchange_values(self): values = super(O2MForm, self)._onchange_values() - values[self._proxy._descr['relation_field']] = \ - self._proxy._parent._values + # computed o2m may not have a relation_field(?) + descr = self._proxy._descr + if 'relation_field' in descr: + values[descr['relation_field']] = self._proxy._parent._values return values def save(self):