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 20:33 +0000

1import datetime 

2from datetime import timedelta 

3 

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 

9 

10 

11class CalendarEvent(models.Model): 

12 _inherit = "calendar.event" 

13 

14 request_id = fields.Many2one("helpdesk.ticket.upgrade.request") 

15 

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. 

20 

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. 

24 

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 

31 

32 appointment_type = upgrade_type.appointment_type_id 

33 

34 duration = ticket._get_estimated_production_upgrade_duration() 

35 

36 partner_ids = [(4, ticket.partner_id.id)] if ticket.partner_id else [] 

37 

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 ) 

61 

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 ) 

71 

72 return event 

73 

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 

101 

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 

105 

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" 

112 

113 def _create_request_from_appointment(self) -> BaseModel: 

114 """ 

115 Create a request from the appointment and link it to the event 

116 

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