-
@@ -888,11 +889,6 @@
options="{'no_open': True}"
widget="many2many_avatar_user"
domain="[('share', '=', False)]"/>
-
@@ -911,7 +907,7 @@
-
+
@@ -989,6 +985,7 @@
+
@@ -1207,8 +1204,10 @@
project.task
-
+
diff --git a/addons/resource/models/resource.py b/addons/resource/models/resource.py
index d1dd783c4a0..e1050d4a5a2 100644
--- a/addons/resource/models/resource.py
+++ b/addons/resource/models/resource.py
@@ -636,6 +636,18 @@ class ResourceCalendar(models.Model):
)
return interval_dt(work_intervals[0]) if work_intervals else None
+ def _get_unusual_days(self, start_dt, end_dt):
+ if not self:
+ return {}
+ self.ensure_one()
+ if not start_dt.tzinfo:
+ start_dt = start_dt.replace(tzinfo=utc)
+ if not end_dt.tzinfo:
+ end_dt = end_dt.replace(tzinfo=utc)
+
+ works = {d[0].date() for d in self._work_intervals_batch(start_dt, end_dt)[False]}
+ return {fields.Date.to_string(day.date()): (day.date() not in works) for day in rrule(DAILY, start_dt, until=end_dt)}
+
# --------------------------------------------------
# External API
# --------------------------------------------------
diff --git a/addons/sale_project/models/project.py b/addons/sale_project/models/project.py
index 25f9eb8c61c..bb952a0ff50 100644
--- a/addons/sale_project/models/project.py
+++ b/addons/sale_project/models/project.py
@@ -169,11 +169,6 @@ class ProjectTask(models.Model):
product_id=task.sale_line_id.product_id.display_name,
))
- @api.ondelete(at_uninstall=False)
- def _unlink_except_linked_so(self):
- if any(task.sale_line_id for task in self):
- raise ValidationError(_('You have to unlink the task from the sale order item in order to delete it.'))
-
# ---------------------------------------------------
# Actions
# ---------------------------------------------------
diff --git a/addons/sale_purchase/models/product_template.py b/addons/sale_purchase/models/product_template.py
index f1b730a563b..9b92440333a 100644
--- a/addons/sale_purchase/models/product_template.py
+++ b/addons/sale_purchase/models/product_template.py
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
+from odoo.exceptions import ValidationError
class ProductTemplate(models.Model):
@@ -13,6 +14,11 @@ class ProductTemplate(models.Model):
('service_to_purchase', "CHECK((type != 'service' AND service_to_purchase != true) or (type = 'service'))", 'Product that is not a service can not create RFQ.'),
]
+ @api.constrains('service_to_purchase', 'seller_ids')
+ def validate_service_to_purchase(self):
+ if self.service_to_purchase and not self.seller_ids:
+ raise ValidationError("Please define the vendor from whom you would like to purchase this service automatically.")
+
@api.onchange('type')
def _onchange_type(self):
res = super(ProductTemplate, self)._onchange_type()
diff --git a/addons/sale_purchase/tests/common.py b/addons/sale_purchase/tests/common.py
index 44365e8ee86..008bbe0c94a 100644
--- a/addons/sale_purchase/tests/common.py
+++ b/addons/sale_purchase/tests/common.py
@@ -2,7 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.sale.tests.common import TestSaleCommon
-
+from odoo import Command
class TestCommonSalePurchaseNoChart(TestSaleCommon):
@@ -24,6 +24,19 @@ class TestCommonSalePurchaseNoChart(TestSaleCommon):
'email': 'supplier.serv@supercompany.com',
})
+ cls.supplierinfo1 = cls.env['product.supplierinfo'].create({
+ 'partner_id': cls.partner_vendor_service.id,
+ 'price': 100,
+ 'delay': 1,
+ })
+ cls.supplierinfo2 = cls.env['product.supplierinfo'].create({
+ 'partner_id': cls.partner_vendor_service.id,
+ 'price': 10,
+ 'delay': 5,
+ })
+
+ # Create product
+ # When service_to_purser is True add the supplier i.e 'saller_ids' on the product to void the Validation error at product creation time
cls.service_purchase_1 = cls.env['product.product'].create({
'name': "Out-sourced Service 1",
'standard_price': 200.0,
@@ -38,6 +51,7 @@ class TestCommonSalePurchaseNoChart(TestSaleCommon):
'taxes_id': False,
'categ_id': cls.product_category_purchase.id,
'service_to_purchase': True,
+ 'seller_ids': [Command.set(cls.supplierinfo1.ids)],
})
cls.service_purchase_2 = cls.env['product.product'].create({
'name': "Out-sourced Service 2",
@@ -53,17 +67,8 @@ class TestCommonSalePurchaseNoChart(TestSaleCommon):
'taxes_id': False,
'categ_id': cls.product_category_purchase.id,
'service_to_purchase': True,
+ 'seller_ids': [Command.set(cls.supplierinfo2.ids)],
})
- cls.supplierinfo1 = cls.env['product.supplierinfo'].create({
- 'partner_id': cls.partner_vendor_service.id,
- 'price': 100,
- 'product_tmpl_id': cls.service_purchase_1.product_tmpl_id.id,
- 'delay': 1,
- })
- cls.supplierinfo2 = cls.env['product.supplierinfo'].create({
- 'partner_id': cls.partner_vendor_service.id,
- 'price': 10,
- 'product_tmpl_id': cls.service_purchase_2.product_tmpl_id.id,
- 'delay': 5,
- })
+ cls.supplierinfo1.product_tmpl_id = cls.service_purchase_1.product_tmpl_id.id
+ cls.supplierinfo2.product_tmpl_id = cls.service_purchase_2.product_tmpl_id.id
diff --git a/addons/sale_timesheet/tests/test_sale_service.py b/addons/sale_timesheet/tests/test_sale_service.py
index f3c85bcacb4..7b2765aa15a 100644
--- a/addons/sale_timesheet/tests/test_sale_service.py
+++ b/addons/sale_timesheet/tests/test_sale_service.py
@@ -92,9 +92,9 @@ class TestSaleService(TestCommonSaleTimesheet):
# delete timesheets before deleting the task, so as to trigger the error
# about linked sales order lines and not the one about linked timesheets
task.timesheet_ids.unlink()
- # not possible to delete a task linked to a SOL
- with self.assertRaises(ValidationError):
- task.unlink()
+ # unlink automatically task from the SOL when deleting the task
+ task.unlink()
+ self.assertFalse(sale_order_line.task_id, "Deleting the task its should automatically unlink the task from SOL.")
def test_timesheet_uom(self):
""" Test timesheet invoicing and uom conversion """
diff --git a/addons/sale_timesheet/views/project_task_views.xml b/addons/sale_timesheet/views/project_task_views.xml
index 15e3bfd69c3..b9f29741aa0 100644
--- a/addons/sale_timesheet/views/project_task_views.xml
+++ b/addons/sale_timesheet/views/project_task_views.xml
@@ -134,6 +134,17 @@
+
+ project.task.tree.inherited
+ project.task
+
+
+
+
+
+
+
+
project.task.form.inherit.timesheet
project.task