Coverage for ingadhoc-odoo-saas-adhoc / saas_provider_upgrade / models / calendar_event.py: 69%
64 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-09 19:24 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-09 19:24 +0000
1import datetime
2from datetime import timedelta
4import dateutil
5from markupsafe import Markup
6from odoo import SUPERUSER_ID, Command, _, api, fields, models
7from odoo.exceptions import UserError
8from odoo.models import BaseModel
11class CalendarEvent(models.Model):
12 _inherit = "calendar.event"
14 request_id = fields.Many2one("helpdesk.ticket.upgrade.request")
16 @api.model
17 def create_from_ticket_upgrade(self, ticket: BaseModel, date_start) -> BaseModel:
18 """
19 Create a calendar event for a production upgrade request.
21 This method creates events bypassing availability validations since wizard-created
22 production requests are administrative and should not be subject to resource
23 availability restrictions.
25 :param ticket: The helpdesk ticket record
26 :param date_start: Scheduled datetime for the upgrade
27 :return: The created calendar event
28 :raises UserError: If no appointment type is configured
29 """
30 upgrade_type = ticket.upgrade_type_id
32 appointment_type = upgrade_type.appointment_type_id
34 duration = ticket._get_estimated_production_upgrade_duration()
36 partner_ids = [(4, ticket.partner_id.id)] if ticket.partner_id else []
38 event_vals = {
39 "name": _("Upgrade to %s - %s", upgrade_type.target, ticket.name),
40 "start": date_start,
41 "stop": date_start + timedelta(hours=duration),
42 "allday": False,
43 "duration": duration,
44 "appointment_type_id": appointment_type.id,
45 "partner_ids": partner_ids,
46 "description": _("Production upgrade scheduled"),
47 "active": True,
48 }
49 event = (
50 self.env["calendar.event"]
51 .with_context(
52 upgrade_ticket_id=ticket.id,
53 confirm_now=True,
54 )
55 .create(event_vals)
56 )
57 available_resources = self.env["appointment.resource"].search(
58 [("appointment_type_ids", "in", appointment_type.id)],
59 limit=1,
60 )
62 if available_resources:
63 self.env["appointment.booking.line"].sudo().create(
64 {
65 "calendar_event_id": event.id,
66 "appointment_resource_id": available_resources[0].id,
67 "capacity_reserved": 1,
68 "capacity_used": 0,
69 }
70 )
72 return event
74 @api.model_create_multi
75 def create(self, vals_list: list) -> BaseModel:
76 events = super().create(vals_list)
77 upgrade_events = events.filtered(lambda e: e.appointment_type_id.upgrade_create).sudo()
78 if not upgrade_events:
79 return events
80 upgrade_events._create_request_from_appointment()
81 upgrade_ticket_id = self.env.context.get("upgrade_ticket_id")
82 ticket = self.env["helpdesk.ticket"].browse(upgrade_ticket_id)
83 if ticket.user_id: 83 ↛ 85line 83 didn't jump to line 85 because the condition on line 83 was always true
84 upgrade_events.write({"user_id": ticket.user_id.id})
85 request_field = self.env["ir.model.fields"]._get("calendar.event", "request_id")
86 for migration_event in upgrade_events.filtered("request_id"):
87 migration_event._message_log(
88 body=Markup("<p>%s</p>")
89 % _("Linked to Request Migration %s", migration_event.request_id._get_html_link()),
90 tracking_value_ids=[
91 Command.create(
92 {
93 "field_id": request_field.id,
94 "old_value_char": False,
95 "new_value_char": migration_event.request_id.id,
96 }
97 )
98 ],
99 )
100 return events
102 def action_cancel_meeting(self, partner_ids: BaseModel):
103 """
104 Override of the method to cancel the linked request if the event is cancelled
106 :param partner_ids: List of partner ids to notify
107 """
108 self.ensure_one()
109 super().action_cancel_meeting(partner_ids)
110 if self.request_id and self.request_id.state != "cancel": 110 ↛ 111line 110 didn't jump to line 111 because the condition on line 110 was never true
111 self.request_id.state = "cancel"
113 def _create_request_from_appointment(self) -> BaseModel:
114 """
115 Create a request from the appointment and link it to the event
117 :return: The new production request, or None if creation failed
118 """
119 upgrade_ticket_id = self.env.context.get("upgrade_ticket_id")
120 confirm_now = self.env.context.get("confirm_now", False)
121 ticket = self.env["helpdesk.ticket"].browse(upgrade_ticket_id)
122 if not ticket: 122 ↛ 123line 122 didn't jump to line 123 because the condition on line 122 was never true
123 raise UserError(_("Error. Please contact support."))
124 if ticket.last_production_request_line_id: 124 ↛ 125line 124 didn't jump to line 125 because the condition on line 124 was never true
125 raise UserError(_("You already have a production request created. You cannot create another one."))
126 request = self.env["helpdesk.ticket.upgrade.request"]._create_request(
127 upgrade_ticket_id,
128 "production",
129 date_start=self.start,
130 event_upgrade_id=self.id,
131 automatic=True,
132 )
133 if not request: 133 ↛ 134line 133 didn't jump to line 134 because the condition on line 133 was never true
134 return None
135 self.write(
136 {
137 "res_model_id": self.env["ir.model"]._get(request._name).id,
138 "res_id": request.id,
139 "request_id": request.id,
140 }
141 )
142 if confirm_now: 142 ↛ 143line 142 didn't jump to line 143 because the condition on line 142 was never true
143 request.ticket_id.sudo().action_confirm_production()
144 else:
145 partners_to_notify = (
146 request.ticket_id.user_id.partner_id | request.ticket_id.assigned_technician_id.partner_id
147 )
148 request.ticket_id.message_post(
149 body=_("The customer has requested an upgrade date, please remember to confirm"),
150 partner_ids=partners_to_notify.ids,
151 )
152 if not request.ticket_id.request_line_ids.filtered( 152 ↛ 162line 152 didn't jump to line 162 because the condition on line 152 was always true
153 lambda x: x.aim == "test"
154 and x.create_date >= datetime.datetime.now() - dateutil.relativedelta.relativedelta(days=7)
155 ):
156 try:
157 self.env["helpdesk.ticket.upgrade.request"].with_user(SUPERUSER_ID)._create_request(
158 request.ticket_id.id, "test", automatic=True, hide_from_portal=True, bypass=True
159 )
160 except Exception:
161 pass # We don't want to fail the event creation if the test request fails
162 return request