statistics: add time between two statuses for cards (#72454) #8

Merged
vdeniaud merged 1 commits from wip/72454-Pouvoir-calculer-la-duree-entre- into main 2023-01-16 09:43:17 +01:00
3 changed files with 73 additions and 3 deletions

View File

@ -27,6 +27,7 @@ def pub():
Category.wipe()
FormDef.wipe()
Workflow.wipe()
CardDef.wipe()
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
pub.set_app_dir(req)
@ -272,6 +273,19 @@ def test_statistics_index_resolution_time(pub):
assert form_filter['options'] == [{'id': 'test-1', 'label': 'test 1'}]
def test_statistics_index_resolution_time_cards(pub):
carddef = CardDef()
carddef.name = 'test 1'
carddef.fields = []
carddef.store()
carddef.data_class().wipe()
resp = get_app(pub).get(sign_uri('/api/statistics/'))
resolution_time_stat = [x for x in resp.json['data'] if x['id'] == 'resolution_time_cards'][0]
card_filter = [x for x in resolution_time_stat['filters'] if x['id'] == 'form'][0]
assert card_filter['options'] == [{'id': 'test-1', 'label': 'test 1'}]
def test_statistics_forms_count(pub):
category_a = Category(name='Category A')
category_a.store()
@ -1089,3 +1103,33 @@ def test_statistics_resolution_time_start_end_filter(pub, freezer):
'4 day(s) and 0 hour(s)', # mean
'4 day(s) and 0 hour(s)', # median
]
def test_statistics_resolution_time_cards(pub, freezer):
workflow = Workflow(name='Workflow One')
new_status = workflow.add_status(name='New status')
workflow.add_status(name='End status')
jump = new_status.add_action('jump', id='_jump')
jump.status = '2'
workflow.store()
carddef = CardDef()
carddef.name = 'test'
carddef.workflow_id = workflow.id
carddef.store()
for i in range(1, 10):
carddata = carddef.data_class()()
freezer.move_to(datetime.date(2021, 1, i))
carddata.just_created()
freezer.move_to(datetime.date(2021, 1, i * 2))
carddata.jump_status('2')
carddata.store()
resp = get_app(pub).get(sign_uri('/api/statistics/resolution-time-cards/?form=test'))
assert get_humanized_duration_serie(resp.json) == [
'1 day(s) and 0 hour(s)',
'9 day(s) and 0 hour(s)',
'5 day(s) and 0 hour(s)',
'5 day(s) and 0 hour(s)',
]

View File

@ -157,7 +157,7 @@ class IndexView(RestrictedView):
],
},
{
'name': _('Time between two statuses'),
'name': _('Time between two statuses (forms)'),
'url': request.build_absolute_uri(reverse('api-statistics-resolution-time')),
'id': 'resolution_time',
'data_type': 'seconds',
@ -171,6 +171,21 @@ class IndexView(RestrictedView):
},
],
},
{
'name': _('Time between two statuses (cards)'),
'url': request.build_absolute_uri(reverse('api-statistics-resolution-time-cards')),
'id': 'resolution_time_cards',
'data_type': 'seconds',
'filters': [
{
'id': 'form',
'label': _('Card'),
'options': self.get_form_options(CardDef, include_all_option=False),
'required': True,
'has_subfilters': True,
},
],
},
]
}
)
@ -546,12 +561,13 @@ class CardsCountView(FormsCountView):
class ResolutionTimeView(RestrictedView):
label = _('Time between two statuses')
formdef_class = FormDef
label = _('Time between two statuses (forms)')
def get(self, request, *args, **kwargs):
formdef_slug = request.GET.get('form', '_nothing')
try:
formdef = FormDef.get_by_urlname(formdef_slug, ignore_migration=True)
formdef = self.formdef_class.get_by_urlname(formdef_slug, ignore_migration=True)
except KeyError:
return HttpResponseBadRequest('invalid form')
@ -653,3 +669,8 @@ class ResolutionTimeView(RestrictedView):
(_('Mean'), mean),
(_('Median'), median),
]
class CardsResolutionTimeView(ResolutionTimeView):
label = _('Time between two statuses (cards)')
formdef_class = CardDef

View File

@ -66,6 +66,11 @@ urlpatterns = [
statistics_views.ResolutionTimeView.as_view(),
name='api-statistics-resolution-time',
),
path(
'api/statistics/resolution-time-cards/',
statistics_views.CardsResolutionTimeView.as_view(),
name='api-statistics-resolution-time-cards',
),
# provide django.contrib.auth view names for compatibility with
# templates created for classic django applications.
path('login/', compat.quixote, name='auth_login'),