diff --git a/addons/event_booth_sale/models/product.py b/addons/event_booth_sale/models/product.py
index 28b1db54415..d626d98efc9 100644
--- a/addons/event_booth_sale/models/product.py
+++ b/addons/event_booth_sale/models/product.py
@@ -9,7 +9,7 @@ class ProductTemplate(models.Model):
detailed_type = fields.Selection(selection_add=[
('event_booth', 'Event Booth'),
- ], ondelete={'event_booth': 'set default'})
+ ], ondelete={'event_booth': 'set service'})
@api.onchange('detailed_type')
def _onchange_type_event_booth(self):
diff --git a/addons/event_booth_sale/views/event_booth_category_views.xml b/addons/event_booth_sale/views/event_booth_category_views.xml
index ea7a1a2d8a7..3332f18495f 100644
--- a/addons/event_booth_sale/views/event_booth_category_views.xml
+++ b/addons/event_booth_sale/views/event_booth_category_views.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/addons/event_sale/models/product.py b/addons/event_sale/models/product.py
index 7574c088747..2b72c1b8a7d 100644
--- a/addons/event_sale/models/product.py
+++ b/addons/event_sale/models/product.py
@@ -8,7 +8,7 @@ class ProductTemplate(models.Model):
detailed_type = fields.Selection(selection_add=[
('event', 'Event Ticket'),
- ], ondelete={'event': 'set default'})
+ ], ondelete={'event': 'set service'})
@api.onchange('detailed_type')
def _onchange_type_event(self):
diff --git a/addons/gift_card/models/product.py b/addons/gift_card/models/product.py
index 156b6eaeedf..636891e41e1 100644
--- a/addons/gift_card/models/product.py
+++ b/addons/gift_card/models/product.py
@@ -10,7 +10,7 @@ class ProductTemplate(models.Model):
detailed_type = fields.Selection(selection_add=[
('gift', 'Gift Card'),
- ], ondelete={'gift': 'set default'})
+ ], ondelete={'gift': 'set service'})
def _detailed_type_mapping(self):
type_mapping = super()._detailed_type_mapping()
diff --git a/addons/hr_expense/views/hr_expense_views.xml b/addons/hr_expense/views/hr_expense_views.xml
index 6c764088293..2fbb5aca157 100644
--- a/addons/hr_expense/views/hr_expense_views.xml
+++ b/addons/hr_expense/views/hr_expense_views.xml
@@ -552,7 +552,7 @@
product.product
kanban,tree,form
-
{"default_can_be_expensed": 1, 'default_type': 'service'}
+
{"default_can_be_expensed": 1, 'default_detailed_type': 'service'}
[('can_be_expensed', '=', True)]
diff --git a/addons/membership/views/product_views.xml b/addons/membership/views/product_views.xml
index ceb0e0d1b5f..58626c0bc40 100644
--- a/addons/membership/views/product_views.xml
+++ b/addons/membership/views/product_views.xml
@@ -113,7 +113,7 @@
Membership Products
product.template
[('membership','=',True), ('type', '=', 'service')]
- {'membership':True, 'type':'service', 'default_membership': True, 'default_type': 'service'}
+ {'membership':True, 'type':'service', 'default_membership': True, 'default_detailed_type': 'service'}
diff --git a/addons/mrp/tests/test_stock.py b/addons/mrp/tests/test_stock.py
index 4da19ce09ab..c0f55da240e 100644
--- a/addons/mrp/tests/test_stock.py
+++ b/addons/mrp/tests/test_stock.py
@@ -179,7 +179,7 @@ class TestKitPicking(common.TestMrpCommon):
def create_product(name):
p = Form(self.env['product.product'])
p.name = name
- p.type = 'product'
+ p.detailed_type = 'product'
return p.save()
# Create a kit 'kit_parent' :
diff --git a/addons/mrp/views/mrp_bom_views.xml b/addons/mrp/views/mrp_bom_views.xml
index d8df9e68052..67226f38c60 100644
--- a/addons/mrp/views/mrp_bom_views.xml
+++ b/addons/mrp/views/mrp_bom_views.xml
@@ -51,9 +51,9 @@
-
+
-
+
@@ -83,7 +83,7 @@
-
+
-
+
diff --git a/addons/mrp/views/mrp_production_views.xml b/addons/mrp/views/mrp_production_views.xml
index af30468d437..c0f0ad5b19e 100644
--- a/addons/mrp/views/mrp_production_views.xml
+++ b/addons/mrp/views/mrp_production_views.xml
@@ -169,7 +169,7 @@
-
+
@@ -252,7 +252,7 @@
context="{'default_date': date_planned_start, 'default_date_deadline': date_deadline, 'default_location_id': location_src_id, 'default_location_dest_id': production_location_id, 'default_state': 'draft', 'default_raw_material_production_id': id, 'default_picking_type_id': picking_type_id, 'default_company_id': company_id}"
attrs="{'readonly': ['|', ('state', '=', 'cancel'), '&', ('state', '=', 'done'), ('is_locked', '=', True)]}" options="{'delete': [('state', '=', 'draft')]}">
-
+
@@ -331,7 +331,7 @@
-
+
diff --git a/addons/mrp/views/product_views.xml b/addons/mrp/views/product_views.xml
index 487348230a0..644ed616540 100644
--- a/addons/mrp/views/product_views.xml
+++ b/addons/mrp/views/product_views.xml
@@ -52,7 +52,7 @@
product.template
kanban,tree,form
- {"search_default_consumable": 1, 'default_type': 'product'}
+ {"search_default_consumable": 1, 'default_detailed_type': 'product'}
No product found. Let's create one!
diff --git a/addons/pos_sale/views/pos_config_views.xml b/addons/pos_sale/views/pos_config_views.xml
index 86fbc27062c..a3e46d32ad9 100644
--- a/addons/pos_sale/views/pos_config_views.xml
+++ b/addons/pos_sale/views/pos_config_views.xml
@@ -27,7 +27,7 @@
diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py
index 88cfb214baf..b47df281432 100644
--- a/addons/product/models/product_template.py
+++ b/addons/product/models/product_template.py
@@ -55,7 +55,6 @@ class ProductTemplate(models.Model):
('consu', 'Consumable'),
('service', 'Service')
],
- default='consu',
compute='_compute_type',
store=True,
readonly=False,
@@ -417,12 +416,12 @@ class ProductTemplate(models.Model):
for record in self:
record.type = type_mapping.get(record.detailed_type, record.detailed_type)
- # @api.constrains('type', 'detailed_type')
- # def _constrains_detailed_type(self):
- # type_mapping = self._detailed_type_mapping()
- # for record in self:
- # if record.type != type_mapping.get(record.detailed_type, record.detailed_type):
- # raise ValidationError(_("The Type of this product doesn't match the Detailed Type"))
+ @api.constrains('type', 'detailed_type')
+ def _constrains_detailed_type(self):
+ type_mapping = self._detailed_type_mapping()
+ for record in self:
+ if record.type != type_mapping.get(record.detailed_type, record.detailed_type):
+ raise ValidationError(_("The Type of this product doesn't match the Detailed Type"))
@api.constrains('uom_id', 'uom_po_id')
def _check_uom(self):
@@ -445,6 +444,12 @@ class ProductTemplate(models.Model):
return {}
def _sanitize_vals(self, vals):
+ """Sanitize vales for writing/creating product templates and variants.
+
+ Values need to be sanitized to keep values synchronized, and to be able to preprocess the
+ vals in extensions of create/write.
+ :param vals: create/write values dictionary
+ """
if 'type' in vals and 'detailed_type' not in vals:
if vals['type'] not in self.mapped('type'):
vals['detailed_type'] = vals['type']
diff --git a/addons/purchase_mrp/tests/test_purchase_mrp_flow.py b/addons/purchase_mrp/tests/test_purchase_mrp_flow.py
index 7e643519dcb..7731be9a53b 100644
--- a/addons/purchase_mrp/tests/test_purchase_mrp_flow.py
+++ b/addons/purchase_mrp/tests/test_purchase_mrp_flow.py
@@ -147,7 +147,7 @@ class TestSaleMrpFlow(TransactionCase):
def _create_product(self, name, uom_id, routes=()):
p = Form(self.env['product.product'])
p.name = name
- p.type = 'product'
+ p.detailed_type = 'product'
p.uom_id = uom_id
p.uom_po_id = uom_id
p.route_ids.clear()
diff --git a/addons/sale/views/res_config_settings_views.xml b/addons/sale/views/res_config_settings_views.xml
index 03541845e48..1c647c292aa 100644
--- a/addons/sale/views/res_config_settings_views.xml
+++ b/addons/sale/views/res_config_settings_views.xml
@@ -419,7 +419,7 @@
Product used for down payments
No product found. Let's create one!
diff --git a/addons/stock/views/stock_move_views.xml b/addons/stock/views/stock_move_views.xml
index e249cc1f0a7..018f7c8bfc1 100644
--- a/addons/stock/views/stock_move_views.xml
+++ b/addons/stock/views/stock_move_views.xml
@@ -251,7 +251,7 @@
1000
-
+
diff --git a/addons/stock/views/stock_picking_views.xml b/addons/stock/views/stock_picking_views.xml
index e84fbc67860..d1e87597ead 100644
--- a/addons/stock/views/stock_picking_views.xml
+++ b/addons/stock/views/stock_picking_views.xml
@@ -375,7 +375,7 @@
-
+
diff --git a/addons/stock/views/stock_production_lot_views.xml b/addons/stock/views/stock_production_lot_views.xml
index 7de7089082b..5023491431e 100644
--- a/addons/stock/views/stock_production_lot_views.xml
+++ b/addons/stock/views/stock_production_lot_views.xml
@@ -31,7 +31,7 @@
-
+
diff --git a/addons/stock/views/stock_scrap_views.xml b/addons/stock/views/stock_scrap_views.xml
index 98a2499da5c..26c6bf2cc84 100644
--- a/addons/stock/views/stock_scrap_views.xml
+++ b/addons/stock/views/stock_scrap_views.xml
@@ -46,7 +46,7 @@
-
+
diff --git a/addons/stock_account/tests/test_stockvaluationlayer.py b/addons/stock_account/tests/test_stockvaluationlayer.py
index 174bfd16e5b..d4d21b1d486 100644
--- a/addons/stock_account/tests/test_stockvaluationlayer.py
+++ b/addons/stock_account/tests/test_stockvaluationlayer.py
@@ -847,9 +847,9 @@ class TestStockValuationChangeValuation(TestStockValuationCommon):
'property_stock_journal': self.stock_journal.id,
})
- # Try to change the product category with a `default_type` key in the context and
+ # Try to change the product category with a `default_detailed_type` key in the context and
# check it doesn't break the account move generation.
- self.product1.with_context(default_type='product').categ_id = cat2
+ self.product1.with_context(default_detailed_type='product').categ_id = cat2
self.assertEqual(self.product1.categ_id, cat2)
self.assertEqual(self.product1.value_svl, 100)
@@ -898,4 +898,3 @@ class TestStockValuationChangeValuation(TestStockValuationCommon):
# An accounting entry should only be created for the emptying now that the category is manual.
self.assertEqual(len(self.product1.stock_valuation_layer_ids.mapped('account_move_id')), 2)
self.assertEqual(len(self.product1.stock_valuation_layer_ids), 3)
-
diff --git a/addons/stock_dropshipping/tests/test_crossdock.py b/addons/stock_dropshipping/tests/test_crossdock.py
index 2d13a7c735c..b7fa78a94ed 100644
--- a/addons/stock_dropshipping/tests/test_crossdock.py
+++ b/addons/stock_dropshipping/tests/test_crossdock.py
@@ -26,7 +26,7 @@ class TestCrossdock(common.TransactionCase):
p_f = Form(self.env['product.template'])
p_f.name = 'PCE'
- p_f.type = 'product'
+ p_f.detailed_type = 'product'
p_f.categ_id = self.env.ref('product.product_category_1')
p_f.list_price = 100.0
with p_f.seller_ids.new() as seller:
diff --git a/addons/stock_landed_costs/views/stock_landed_cost_views.xml b/addons/stock_landed_costs/views/stock_landed_cost_views.xml
index a86da51a2c8..c14e20dc602 100644
--- a/addons/stock_landed_costs/views/stock_landed_cost_views.xml
+++ b/addons/stock_landed_costs/views/stock_landed_cost_views.xml
@@ -65,7 +65,7 @@
+ context="{'default_landed_cost_ok': True, 'default_detailed_type': 'service'}"/>
diff --git a/addons/stock_picking_batch/views/stock_picking_batch_views.xml b/addons/stock_picking_batch/views/stock_picking_batch_views.xml
index ba694510fd2..5bf7debedbb 100644
--- a/addons/stock_picking_batch/views/stock_picking_batch_views.xml
+++ b/addons/stock_picking_batch/views/stock_picking_batch_views.xml
@@ -60,7 +60,7 @@
-
+
diff --git a/addons/website_event_sale/models/product_pricelist.py b/addons/website_event_sale/models/product_pricelist.py
index b6fcbb48fdc..fa7d141d38b 100644
--- a/addons/website_event_sale/models/product_pricelist.py
+++ b/addons/website_event_sale/models/product_pricelist.py
@@ -11,8 +11,8 @@ class PricelistItem(models.Model):
msg = ''
if self.applied_on == '3_global' or self.applied_on == '2_product_category':
msg = _("A pricelist item with a positive min. quantity will not be applied to the event tickets products.")
- elif ((self.applied_on == '1_product' and self.product_tmpl_id.type == 'event') or
- (self.applied_on == '0_product_variant' and self.product_id.type == 'event')):
+ elif ((self.applied_on == '1_product' and self.product_tmpl_id.detailed_type == 'event') or
+ (self.applied_on == '0_product_variant' and self.product_id.detailed_type == 'event')):
msg = _("A pricelist item with a positive min. quantity cannot be applied to this event tickets product.")
if msg:
return {'warning':
diff --git a/addons/website_event_sale/models/website.py b/addons/website_event_sale/models/website.py
index 5250d6d0ed3..f1afdabaae8 100644
--- a/addons/website_event_sale/models/website.py
+++ b/addons/website_event_sale/models/website.py
@@ -8,4 +8,4 @@ class Website(models.Model):
def sale_product_domain(self):
# remove product event from the website content grid and list view (not removed in detail view)
- return ['&'] + super(Website, self).sale_product_domain() + [('type', '!=', 'event')]
+ return ['&'] + super(Website, self).sale_product_domain() + [('detailed_type', '!=', 'event')]
diff --git a/addons/website_sale_slides/views/slide_channel_views.xml b/addons/website_sale_slides/views/slide_channel_views.xml
index cffeeabbed6..7d72c53ce26 100644
--- a/addons/website_sale_slides/views/slide_channel_views.xml
+++ b/addons/website_sale_slides/views/slide_channel_views.xml
@@ -8,7 +8,7 @@
+ context="{'default_detailed_type': 'service', 'default_invoice_policy': 'order', 'default_purchase_ok': False, 'default_sale_ok': True, 'default_website_published': True}"/>
-
- Address
+
+ Address