Skip to content

Commit

Permalink
[MIG] resource_booking: Migration to 14.0
Browse files Browse the repository at this point in the history
- Standard procedure
- No more virtual ids
- Adapt tests
- FIX: Proper show_as meeting generation
- IMP: Add name to tree view

TT32344
  • Loading branch information
pedrobaeza committed Oct 24, 2022
1 parent f4b61d3 commit 1f27de7
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 162 deletions.
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
# generated from manifests external_dependencies
cssselect
freezegun
9 changes: 4 additions & 5 deletions resource_booking/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
# Copyright 2021 Tecnativa - Jairo Llopis
# Copyright 2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Resource booking",
"summary": "Manage appointments and resource booking",
"version": "13.0.2.6.5",
"development_status": "Beta",
"version": "14.0.1.0.0",
"development_status": "Production/Stable",
"category": "Appointments",
"website": "https://github.com/OCA/calendar",
"author": "Tecnativa, Odoo Community Association (OCA)",
"maintainers": ["Yajo"],
"maintainers": ["pedrobaeza"],
"license": "AGPL-3",
"application": True,
"installable": True,
"external_dependencies": {
"python": [
# Used implicitly
"cssselect",
# Only for tests
"freezegun",
],
},
"depends": [
Expand Down
5 changes: 2 additions & 3 deletions resource_booking/controllers/portal.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2021 Tecnativa - Jairo Llopis
# Copyright 2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from datetime import datetime
Expand Down Expand Up @@ -125,9 +126,7 @@ def portal_booking_cancel(self, booking_id, access_token=None, **kwargs):
)
def portal_booking_confirm(self, booking_id, access_token, when, **kwargs):
"""Confirm a booking in a given datetime."""
booking_sudo = self._get_booking_sudo(booking_id, access_token).with_context(
autoconfirm_booking_requester=True
)
booking_sudo = self._get_booking_sudo(booking_id, access_token)
when_tz_aware = isoparse(when)
when_naive = datetime.utcfromtimestamp(when_tz_aware.timestamp())
try:
Expand Down
17 changes: 0 additions & 17 deletions resource_booking/migrations/13.0.1.0.0/noupdate_changes.xml

This file was deleted.

11 changes: 0 additions & 11 deletions resource_booking/migrations/13.0.1.0.0/post-migrate.py

This file was deleted.

55 changes: 0 additions & 55 deletions resource_booking/migrations/13.0.2.0.0/pre-migrate.py

This file was deleted.

92 changes: 51 additions & 41 deletions resource_booking/models/calendar_event.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Copyright 2021 Tecnativa - Jairo Llopis
# Copyright 2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError


class CalendarEvent(models.Model):
_name = "calendar.event"
_inherit = "calendar.event"

# One2one field, actually
Expand Down Expand Up @@ -36,10 +36,10 @@ def _validate_booking_modifications(self):
% "\n- ".join(frozen.mapped("display_name"))
)

def unlink(self, can_be_deleted=True):
def unlink(self):
"""Check you're allowed to unschedule it."""
self._validate_booking_modifications()
return super().unlink(can_be_deleted=can_be_deleted)
return super().unlink()

def write(self, vals):
"""Check you're allowed to reschedule it."""
Expand All @@ -52,44 +52,26 @@ def write(self, vals):
rescheduled._validate_booking_modifications()
return result

def create_attendees(self):
"""Autoconfirm resource attendees if preselected."""
old_attendees = self.attendee_ids
result = super(
# This context avoids sending invitations to new attendees
CalendarEvent,
self.with_context(detaching=True),
).create_attendees()
new_attendees = (self.attendee_ids - old_attendees).with_context(
self.env.context
)
for attendee in new_attendees:
# No need to change state if it's already done
if attendee.state in {"accepted", "declined"}:
continue
rb = attendee.event_id.resource_booking_ids
# Confirm requester attendee always if requested
if (
self.env.context.get("autoconfirm_booking_requester")
and attendee.partner_id == rb.partner_id
):
attendee.state = "accepted"
continue
# Auto-confirm if attendee comes from a handpicked combination
if rb.combination_auto_assign:
continue
if attendee.partner_id in rb.combination_id.resource_ids.user_id.partner_id:
attendee.state = "accepted"
# Don't send notifications if you're a public user
if self.env.user._is_public():
return result
# Send invitations like upstream would have done
to_notify = new_attendees.filtered(lambda a: a.email != self.env.user.email)
if to_notify and not self.env.context.get("detaching"):
to_notify._send_mail_to_attendees(
"calendar.calendar_template_meeting_invitation"
)
return result
@api.model_create_multi
def create(self, vals_list):
"""Transfer resource booking to _attendees_values by context.
We need to serialize the creation in that case.
"""
vals_list2 = []
records = self.env["calendar.event"]
for vals in vals_list:
if "resource_booking_ids" in vals:
records += super(
CalendarEvent,
self.with_context(
resource_booking_ids=vals["resource_booking_ids"]
),
).create(vals)
else:
vals_list2.append(vals)
records += super().create(vals_list2)
return records

def get_interval(self, interval, tz=None):
"""Autofix tz from related resource booking.
Expand All @@ -100,3 +82,31 @@ def get_interval(self, interval, tz=None):
"""
tz = self.resource_booking_ids.type_id.resource_calendar_id.tz or tz
return super().get_interval(interval=interval, tz=tz)

def _attendees_values(self, partner_commands):
"""Autoconfirm resource attendees if preselected and hand-picked on RB.
NOTE: There's no support for changing `resource_booking_ids` once the meeting
is created nor having more than one Rb attached to the same meeting, but that's
not a real case for now.
"""
attendee_commands = super()._attendees_values(partner_commands)
ctx_partner_id = False
for cmd in self.env.context.get("resource_booking_ids", []):
if cmd[0] == 0 and not cmd[2].get("combination_auto_assign", True):
ctx_partner_id = cmd[2]["partner_id"]
elif cmd[0] == 6:
rb = self.env["resource.booking"].browse(cmd[2])
if rb.combination_auto_assign:
continue # only auto-confirm if handpicked combination
ctx_partner_id = rb.combination_id.resource_ids.user_id.partner_id.id
for command in attendee_commands:
if command[0] != 0:
continue
att_partner_id = ctx_partner_id
if not att_partner_id:
rb = self.resource_booking_ids
att_partner_id = rb.combination_id.resource_ids.user_id.partner_id.id
if command[2]["partner_id"] == att_partner_id:
command[2]["state"] = "accepted"
return attendee_commands
11 changes: 2 additions & 9 deletions resource_booking/models/resource_booking.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2021 Tecnativa - Jairo Llopis
# Copyright 2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

import calendar
Expand Down Expand Up @@ -119,14 +120,12 @@ class ResourceBooking(models.Model):
index=True,
readonly=False,
store=True,
track_sequence=200,
tracking=True,
)
duration = fields.Float(
compute="_compute_duration",
readonly=False,
store=True,
track_sequence=220,
tracking=True,
help="Amount of time that the resources will be booked and unavailable for others.",
)
Expand All @@ -135,7 +134,6 @@ class ResourceBooking(models.Model):
copy=False,
index=True,
store=True,
track_sequence=210,
tracking=True,
)
type_id = fields.Many2one(
Expand Down Expand Up @@ -304,12 +302,7 @@ def _sync_meeting(self):
start=one.start,
stop=one.stop,
user_id=one.user_id.id,
# If you're not booked, you're free
show_as=(
"busy"
if self.env.user.partner_id in resource_partners
else "free"
),
show_as="busy",
# These 2 avoid creating event as activity
res_model_id=False,
res_id=False,
Expand Down
9 changes: 3 additions & 6 deletions resource_booking/models/resource_calendar.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Copyright 2021 Tecnativa - Jairo Llopis
# Copyright 2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from pytz import UTC

from odoo import api, fields, models

from odoo.addons.calendar.models.calendar import calendar_id2real_id
from odoo.addons.resource.models.resource import Intervals


Expand Down Expand Up @@ -63,15 +63,12 @@ def _calendar_event_busy_intervals(
self.env["calendar.event"].with_context(active_test=True).search(domain)
)
for event in all_events:
real_event = self.env["calendar.event"].browse(
calendar_id2real_id(event.id)
)
# Is the event the same one we're currently checking?
if real_event.resource_booking_ids.id == analyzed_booking_id:
if event.resource_booking_ids.id == analyzed_booking_id:
continue
try:
# Is the event not booking our resource?
if resource & real_event.mapped(
if resource & event.mapped(
"resource_booking_ids.combination_id.resource_ids"
):
raise Busy
Expand Down
Loading

0 comments on commit 1f27de7

Please sign in to comment.