@@ -263,42 +263,53 @@ def _get_partitioned_data_from(self):
263
263
@api .model
264
264
def _get_filled_data_query (self ):
265
265
"""Fill empty values in rows with previous value."""
266
- # Second part ot the idea coming from
267
- # https://stackoverflow.com/a/19012333/11534960
268
- return """select
269
- message_id as id,
270
- task_id,
271
- message_id,
272
- date,
273
- case when new_name <> old_name -- Change counts as old value
274
- then old_name
275
- else first_value(new_name)
276
- over (partition by task_id, count_new_name order by message_id)
277
- end "name",
278
- case when new_user_id <> old_user_id
279
- then old_user_id
280
- else first_value(new_user_id)
281
- over (partition by task_id, count_new_user_id order by message_id)
282
- end user_id,
283
- case when new_stage_id <> old_stage_id
284
- then old_stage_id
285
- else first_value(new_stage_id)
286
- over (partition by task_id, count_new_stage_id order by message_id)
287
- end stage_id,
288
- case when new_kanban_state <> old_kanban_state
289
- then old_kanban_state
290
- else first_value(new_kanban_state)
291
- over (partition by task_id, count_new_kanban_state order by message_id)
292
- end kanban_state,
293
- lag(date) over (partition by task_id order by date) as prev_update,
294
- extract(epoch from
295
- (date - lag(date)
296
- over (partition by task_id order by date)))/ 3600 as duration
266
+ return """
267
+ {select_clause}
297
268
from ({partitioned_data}) partitioned_data
298
269
""" .format (
270
+ select_clause = self ._get_filled_data_select (),
299
271
partitioned_data = self ._get_partitioned_data_query (),
300
272
)
301
273
274
+ def _get_filled_data_select (self ):
275
+ """
276
+ Select duration of changes using partitions.
277
+
278
+ For each tracked field, use a partition over the task id
279
+ to record the time passed
280
+ from the last change of any other tracked field.
281
+ Ordering of partitions is the date of the change.
282
+ Some other fields useful for the context
283
+ like message_id and task_id are selected.
284
+ `message_id` is used as this table's id.
285
+ """
286
+ # Second part ot the idea coming from
287
+ # https://stackoverflow.com/a/19012333/11534960
288
+ select_clause = ["""select
289
+ message_id as id,
290
+ task_id,
291
+ message_id,
292
+ date,
293
+ lag(date) over (partition by task_id order by date) as prev_update,
294
+ extract(epoch
295
+ from (date - lag(date)
296
+ over (partition by task_id order by date)))
297
+ / 3600
298
+ as duration
299
+ """ ]
300
+ for field_name in TRACKED_TASK_FIELDS :
301
+ field_select = """
302
+ case when new_{field_name} <> old_{field_name} -- Change counts as old value
303
+ then old_{field_name}
304
+ else first_value(new_{field_name})
305
+ over (partition by task_id, count_new_{field_name} order by message_id)
306
+ end
307
+ "{field_name}"
308
+ """ .format (field_name = field_name )
309
+ select_clause .append (field_select )
310
+ select_clause = ', ' .join (select_clause )
311
+ return select_clause
312
+
302
313
@api .model
303
314
def _get_cleaned_data_query (self ):
304
315
"""Clan data that are not interesting.
0 commit comments