diff --git a/fieldservice_calendar/models/calendar.py b/fieldservice_calendar/models/calendar.py index ec7d2866d9..1862ab7a69 100644 --- a/fieldservice_calendar/models/calendar.py +++ b/fieldservice_calendar/models/calendar.py @@ -1,7 +1,7 @@ # Copyright (C) 2021 Raphaël Reverdy # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models +from odoo import fields, models, tools class Meeting(models.Model): @@ -15,38 +15,38 @@ class Meeting(models.Model): def _update_fsm_order_date(self): self.ensure_one() - if self._context.get("recurse_order_calendar"): - # avoid recursion - return to_apply = {} to_apply["scheduled_date_start"] = self.start to_apply["scheduled_duration"] = self.duration - self.fsm_order_id.with_context(recurse_order_calendar=True).write(to_apply) + self.fsm_order_id.write(to_apply) def _update_fsm_assigned(self): # update back fsm_order when an attenndee is member of a team self.ensure_one() - if self._context.get("recurse_order_calendar"): - # avoid recursion - return - person_id = None - for partner in self.partner_ids: - if partner.fsm_person: - person_id = ( - self.env["fsm.person"] - .search([["partner_id", "=", partner.id]], limit=1) - .id - ) - break - self.fsm_order_id.with_context(recurse_order_calendar=True).write( - {"person_id": person_id} - ) + for partner in self.partner_ids.filtered("fsm_person"): + self.fsm_order_id.person_id = self.env["fsm.person"].search( + [("partner_id", "=", partner.id)], limit=1 + ) + break + + def _update_fsm_order_description(self): + self.fsm_order_id.description = tools.html2plaintext(self.description or "") def write(self, values): res = super().write(values) - if self.fsm_order_id: - if "start" in values or "duration" in values: - self._update_fsm_order_date() - if "partner_ids" in values: - self._update_fsm_assigned() + if values.keys() & { + "start", + "duration", + "partner_ids", + "description", + } and not self.env.context.get("recurse_order_calendar"): + for event in self.filtered("fsm_order_id").with_context( + recurse_order_calendar=True + ): + if "start" in values or "duration" in values: + event._update_fsm_order_date() + if "partner_ids" in values: + event._update_fsm_assigned() + if "description" in values: + event._update_fsm_order_description() return res diff --git a/fieldservice_calendar/models/fsm_order.py b/fieldservice_calendar/models/fsm_order.py index d374099a78..4e1c05e00b 100644 --- a/fieldservice_calendar/models/fsm_order.py +++ b/fieldservice_calendar/models/fsm_order.py @@ -1,7 +1,7 @@ # Copyright (C) 2021 Raphaël Reverdy # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +from odoo import api, fields, models, tools class FSMOrder(models.Model): @@ -37,7 +37,7 @@ def _prepare_calendar_event(self): model_id = self.env.ref("fieldservice.model_fsm_order").id vals = { "name": self.name, - "description": self.description, + "description": tools.plaintext2html(self.description or ""), "start": self.scheduled_date_start, "stop": self.scheduled_date_end, "allday": False, @@ -53,18 +53,22 @@ def _prepare_calendar_event(self): return vals def write(self, vals): - old_persons = {} - for rec in self: - old_persons[rec.id] = rec.person_id + if "person_id" in vals and not self.env.context.get("recurse_order_calendar"): + old_persons = {order: order.person_id for order in self} res = super().write(vals) to_update = self.create_or_delete_calendar() - with_calendar = to_update.filtered("calendar_event_id") - if "scheduled_date_start" in vals or "scheduled_date_end" in vals: - with_calendar.update_calendar_date(vals) - if "location_id" in vals: - with_calendar.update_calendar_location() - if "person_id" in vals: - with_calendar.update_calendar_person(old_persons) + if not self.env.context.get("recurse_order_calendar"): + with_calendar = to_update.filtered("calendar_event_id").with_context( + recurse_order_calendar=True + ) + if "scheduled_date_start" in vals or "scheduled_date_end" in vals: + with_calendar.update_calendar_date(vals) + if "description" in vals: + with_calendar.update_calendar_description() + if "location_id" in vals: + with_calendar.update_calendar_location() + if "person_id" in vals: + with_calendar.update_calendar_person(old_persons) return res def unlink(self): @@ -84,16 +88,16 @@ def _rm_calendar_event(self): self.calendar_event_id.unlink() def update_calendar_date(self, vals): - if self._context.get("recurse_order_calendar"): - # avoid recursion - return to_apply = {} to_apply["start"] = self.scheduled_date_start to_apply["stop"] = self.scheduled_date_end # always write start and stop in order to calc duration - self.mapped("calendar_event_id").with_context( - recurse_order_calendar=True - ).write(to_apply) + self.calendar_event_id.write(to_apply) + + def update_calendar_description(self): + for order in self: + html_description = tools.plaintext2html(order.description or "") + order.calendar_event_id.description = html_description def update_calendar_location(self): for rec in self: @@ -104,14 +108,9 @@ def _serialize_location(self): return f"{partner_id.name} {partner_id._display_address()}" def update_calendar_person(self, old_persons): - if self._context.get("recurse_order_calendar"): - # avoid recursion - return - for rec in self: - with_ctx = rec.calendar_event_id.with_context(recurse_order_calendar=True) - if old_persons.get(rec.id): - # remove buddy - with_ctx.partner_ids = [(3, old_persons[rec.id].partner_id.id, False)] - if rec.person_id: - # add the new one - with_ctx.partner_ids = [(4, rec.person_id.partner_id.id, False)] + for order in self: + event = order.calendar_event_id + if person := old_persons.get(order): + event.partner_ids -= person.partner_id # remove buddy + if person := order.person_id: + event.partner_ids += person.partner_id # add new one diff --git a/fieldservice_calendar/readme/CONTRIBUTORS.rst b/fieldservice_calendar/readme/CONTRIBUTORS.rst index 0238b67df8..b9ffec1410 100644 --- a/fieldservice_calendar/readme/CONTRIBUTORS.rst +++ b/fieldservice_calendar/readme/CONTRIBUTORS.rst @@ -1,2 +1,5 @@ * Raphaël Reverdy * Freni Patel +* `XCG Consulting `_: + + * Houzéfa Abbasbhay diff --git a/fieldservice_calendar/tests/test_fsm_calendar.py b/fieldservice_calendar/tests/test_fsm_calendar.py index 40cbeef62f..be6c4c30cc 100644 --- a/fieldservice_calendar/tests/test_fsm_calendar.py +++ b/fieldservice_calendar/tests/test_fsm_calendar.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import fields -from odoo.tests.common import TransactionCase +from odoo.tests.common import Form, TransactionCase class TestFSMOrder(TransactionCase): @@ -18,25 +18,15 @@ def setUpClass(cls): cls.person_id3 = cls.env.ref("fieldservice.person_3") def test_fsm_order_no_duration(self): - new = self.Order.create( - { - "location_id": self.test_location.id, - # no duration = no calendar - } - ) + # not scheduled (no duration) = no calendar + new = self._create_fsm_order(schedule=False) evt = new.calendar_event_id self.assertFalse(evt.exists()) def test_fsm_order_no_calendar_user(self): self.team.calendar_user_id = False # no calendar user_id = no calendar event - new = self.Order.create( - { - "location_id": self.test_location.id, - "scheduled_date_start": fields.Datetime.today(), - "scheduled_duration": 2, - } - ) + new = self._create_fsm_order(schedule=True) evt = new.calendar_event_id self.assertFalse(evt.exists()) self.team.calendar_user_id = self.env.ref("base.partner_root").id @@ -53,14 +43,7 @@ def test_fsm_order_no_calendar_user(self): self.assertFalse(evt.exists()) def test_fsm_order_unlink(self): - # Create an Orders - new = self.Order.create( - { - "location_id": self.test_location.id, - "scheduled_date_start": fields.Datetime.today(), - "scheduled_duration": 2, - } - ) + new = self._create_fsm_order(schedule=True) evt = new.calendar_event_id self.assertTrue(evt.exists()) @@ -72,14 +55,7 @@ def test_fsm_order_unlink(self): self.assertFalse(evt.exists()) def test_fsm_order_ensure_attendee(self): - # Create an Orders - new = self.Order.create( - { - "location_id": self.test_location.id, - "scheduled_date_start": fields.Datetime.today(), - "scheduled_duration": 2, - } - ) + new = self._create_fsm_order(schedule=True) evt = new.calendar_event_id self.assertTrue( len(evt.partner_ids) == 1, @@ -94,3 +70,22 @@ def test_fsm_order_ensure_attendee(self): self.assertTrue( len(evt.partner_ids) == 2, "Not workers should be removed from attendees" ) + + def test_description_sync(self): + fsm_order = self._create_fsm_order(schedule=True) + event = fsm_order.calendar_event_id + self.assertEqual(event.description, "

") + with Form(fsm_order) as form: + form.description = "line 1\nline 2" + self.assertEqual(event.description, "

line 1
line 2

") + with Form(event) as form: + form.description = "

line 1
line 2
line 3

" + self.assertEqual(fsm_order.description, "line 1\nline 2\nline 3") + + def _create_fsm_order(self, schedule=False): + form = Form(self.Order) + form.location_id = self.test_location + if schedule: + form.scheduled_date_start = fields.Datetime.today() + form.scheduled_duration = 2 + return form.save()