@@ -29,12 +29,12 @@ def portal_my_calendar(self, **kw):
2929 Display customer's scheduled services in a calendar view.
3030 """
3131 partner = request .env .user .partner_id
32-
32+
3333 values = {
3434 'page_name' : 'calendar' ,
3535 'partner' : partner ,
3636 }
37-
37+
3838 return request .render ("records_management.portal_calendar_view" , values )
3939
4040 @http .route (['/my/calendar/events' ], type = 'json' , auth = 'user' )
@@ -56,18 +56,18 @@ def portal_calendar_events(self, start=None, end=None, **kw):
5656 """
5757 partner = request .env .user .partner_id
5858 events = []
59-
59+
6060 # Parse date range (FullCalendar sends ISO strings)
6161 if start :
6262 start_date = datetime .fromisoformat (start .replace ('Z' , '+00:00' ))
6363 else :
6464 start_date = datetime .now () - timedelta (days = 30 )
65-
65+
6666 if end :
6767 end_date = datetime .fromisoformat (end .replace ('Z' , '+00:00' ))
6868 else :
6969 end_date = datetime .now () + timedelta (days = 90 )
70-
70+
7171 # ============================================================================
7272 # 1. SHREDDING SERVICES (Recurring bin services)
7373 # ============================================================================
@@ -77,7 +77,7 @@ def portal_calendar_events(self, start=None, end=None, **kw):
7777 ('active' , '=' , True ),
7878 ('service_frequency' , '!=' , False )
7979 ])
80-
80+
8181 for bin in shred_bins :
8282 # Generate recurring service dates based on frequency
8383 service_dates = self ._generate_recurring_dates (
@@ -86,7 +86,7 @@ def portal_calendar_events(self, start=None, end=None, **kw):
8686 start_date ,
8787 end_date
8888 )
89-
89+
9090 for service_date in service_dates :
9191 events .append ({
9292 'id' : f'shred_{ bin .id } _{ service_date .strftime ("%Y%m%d" )} ' ,
@@ -101,31 +101,31 @@ def portal_calendar_events(self, start=None, end=None, **kw):
101101 'location' : bin .location_description or 'On-site' ,
102102 }
103103 })
104-
104+
105105 # ============================================================================
106106 # 2. FIELD SERVICE TASKS (Pickups, Retrievals, Deliveries)
107107 # ============================================================================
108108 Task = request .env ['project.task' ].sudo ()
109-
109+
110110 # Search for FSM tasks related to this customer
111111 task_domain = [
112112 ('partner_id' , '=' , partner .commercial_partner_id .id ),
113113 '|' ,
114114 ('scheduled_start_time' , '>=' , start_date ),
115115 ('date_deadline' , '>=' , start_date .date ()),
116116 ]
117-
117+
118118 tasks = Task .search (task_domain )
119-
119+
120120 for task in tasks :
121121 # Determine event date (prefer scheduled_start_time, fallback to date_deadline)
122122 event_start = task .scheduled_start_time or datetime .combine (
123123 task .date_deadline or datetime .now ().date (),
124124 datetime .min .time ()
125125 )
126-
126+
127127 event_end = task .scheduled_end_time or (event_start + timedelta (hours = 2 ))
128-
128+
129129 # Color code by work order type
130130 color_map = {
131131 'pickup' : '#007bff' , # Blue
@@ -134,13 +134,13 @@ def portal_calendar_events(self, start=None, end=None, **kw):
134134 'delivery' : '#ffc107' , # Yellow
135135 'internal' : '#6c757d' , # Gray
136136 }
137-
137+
138138 task_type = task .work_order_type or 'other'
139139 color = color_map .get (task_type , '#17a2b8' ) # Teal default
140-
140+
141141 # Build detail URL
142142 detail_url = f'/my/tasks/{ task .id } ' if task .portal_show else None
143-
143+
144144 events .append ({
145145 'id' : f'task_{ task .id } ' ,
146146 'title' : task .name ,
@@ -156,26 +156,26 @@ def portal_calendar_events(self, start=None, end=None, **kw):
156156 'stage' : task .stage_id .name if task .stage_id else 'Scheduled' ,
157157 }
158158 })
159-
159+
160160 # ============================================================================
161161 # 3. PORTAL REQUESTS (Pending pickups, destructions)
162162 # ============================================================================
163163 PortalRequest = request .env ['portal.request' ].sudo ()
164-
164+
165165 portal_requests = PortalRequest .search ([
166166 ('partner_id' , '=' , partner .commercial_partner_id .id ),
167167 ('state' , 'in' , ['draft' , 'submitted' , 'approved' ]),
168168 ('requested_date' , '!=' , False ),
169169 ('requested_date' , '>=' , start_date .date ()),
170170 ('requested_date' , '<=' , end_date .date ()),
171171 ])
172-
172+
173173 for req in portal_requests :
174174 req_date = datetime .combine (req .requested_date , datetime .min .time ())
175-
175+
176176 # Color by request type
177177 req_color = '#6610f2' if req .request_type == 'destruction' else '#fd7e14' # Purple or Orange
178-
178+
179179 events .append ({
180180 'id' : f'request_{ req .id } ' ,
181181 'title' : _ ('%s Request' ) % req .request_type .capitalize (),
@@ -190,19 +190,19 @@ def portal_calendar_events(self, start=None, end=None, **kw):
190190 'state' : req .state ,
191191 }
192192 })
193-
193+
194194 # ============================================================================
195195 # 4. CONTAINER RETRIEVALS (Scheduled document access)
196196 # ============================================================================
197197 RetrievalOrder = request .env ['records.retrieval.order' ].sudo ()
198-
198+
199199 retrievals = RetrievalOrder .search ([
200200 ('partner_id' , '=' , partner .commercial_partner_id .id ),
201201 ('state' , 'not in' , ['cancelled' , 'delivered' ]),
202202 ('scheduled_date' , '>=' , start_date ),
203203 ('scheduled_date' , '<=' , end_date ),
204204 ])
205-
205+
206206 for retrieval in retrievals :
207207 events .append ({
208208 'id' : f'retrieval_{ retrieval .id } ' ,
@@ -217,7 +217,7 @@ def portal_calendar_events(self, start=None, end=None, **kw):
217217 'state' : retrieval .state ,
218218 }
219219 })
220-
220+
221221 return events
222222
223223 def _generate_recurring_dates (self , start_date , frequency , range_start , range_end ):
@@ -235,28 +235,28 @@ def _generate_recurring_dates(self, start_date, frequency, range_start, range_en
235235 """
236236 if not start_date or not frequency :
237237 return []
238-
238+
239239 dates = []
240240 current = start_date
241-
241+
242242 # Frequency intervals
243243 intervals = {
244244 'weekly' : timedelta (days = 7 ),
245245 'biweekly' : timedelta (days = 14 ),
246246 'monthly' : timedelta (days = 30 ), # Approximate
247247 'quarterly' : timedelta (days = 90 ),
248248 }
249-
249+
250250 interval = intervals .get (frequency , timedelta (days = 7 ))
251-
251+
252252 # Generate dates within range
253253 while current <= range_end :
254254 if current >= range_start :
255255 dates .append (current )
256256 current += interval
257-
257+
258258 # Safety limit: max 100 occurrences
259259 if len (dates ) > 100 :
260260 break
261-
261+
262262 return dates
0 commit comments