def get_context_data(self, *args, **kwargs): context = super(WorkflowDetailView, self).get_context_data(**kwargs) # stats self.object.n_tasks = self.object.tasks.count() self.object.n_done = self.object.tasks.closed().count() self.object.pct_done = self.object.n_done / (self.object.n_tasks or 1) * 100.0 context['form'] = self.form tasks = self.form.filter_queryset(self.object.tasks) \ .select_related('document__language', 'document__language__language')\ .defer('document__document_xml', 'document__search_text', 'document__search_vector')\ .all() context['tasks'] = tasks context['has_tasks'] = self.object.n_tasks > 0 context['task_groups'] = Task.task_columns( ['open', 'pending_review', 'assigned'], tasks) context['possible_tasks'] = self.place.tasks\ .unclosed()\ .exclude(workflows=self.object) \ .select_related('document__language', 'document__language__language') \ .defer('document__document_xml', 'document__search_text', 'document__search_vector')\ .all() Task.decorate_potential_assignees(tasks, self.country) context[ 'may_close'] = not self.object.closed and self.object.n_tasks == self.object.n_done context['may_reopen'] = self.object.closed stream = any_stream(self.object) context['activity_stream'] = self.coalesce_entries(stream) return context
class TaskTestCase(TestCase): fixtures = ['countries', 'user', 'work', 'drafts'] def setUp(self): self.task = Task(title='foo', description='bar') def test_discard_bad_work_country(self): na = Country.objects.get(country__pk='NA') self.task.country = na self.task.work = Work.objects.get(frbr_uri='/za/act/2014/10') self.task.clean() self.assertEqual(self.task.country, na) self.assertIsNone(self.task.work) def test_discard_bad_work_locality(self): za = Country.objects.get(country__pk='ZA') loc = za.localities.all()[0] self.task.country = za self.task.locality = loc self.task.work = Work.objects.get(frbr_uri='/za/act/2014/10') self.task.clean() self.assertEqual(self.task.country, za) self.assertEqual(self.task.locality, loc) self.assertIsNone(self.task.work)
def get_context_data(self, **kwargs): context = super(TaskDetailView, self).get_context_data(**kwargs) task = self.object if self.request.user.has_perm('indigo_api.change_task'): context['change_task_permission'] = True if has_transition_perm(task.submit, self): context['submit_task_permission'] = True if has_transition_perm(task.reopen, self): context['reopen_task_permission'] = True if has_transition_perm(task.unsubmit, self): context['unsubmit_task_permission'] = True if has_transition_perm(task.close, self): context['close_task_permission'] = True context['possible_workflows'] = Workflow.objects.unclosed().filter( country=task.country, locality=task.locality).all() Task.decorate_potential_assignees([task], self.country) return context
def get_context_data(self, **kwargs): context = super(WorkTasksView, self).get_context_data(**kwargs) context['tasks'] = context['work'].tasks.all() context['task_groups'] = Task.task_columns( ['open', 'assigned', 'pending_review', 'done', 'cancelled'], context['tasks']) Task.decorate_potential_assignees(context['tasks'], self.country) return context
def get_context_data(self, **kwargs): context = super(TaskListView, self).get_context_data(**kwargs) context['task_labels'] = TaskLabel.objects.all() context['form'] = self.form context['frbr_uri'] = self.request.GET.get('frbr_uri') context['task_groups'] = Task.task_columns( self.form.cleaned_data['state'], context['tasks']) Task.decorate_potential_assignees(context['tasks'], self.country) return context
def pub_doc_task(self, work, user): task_title = 'Link publication document' try: Task.objects.get(title=task_title, work=work, state__in=Task.OPEN_STATES + ('cancelled', )) except Task.DoesNotExist: task = Task() self.stdout.write( self.style.NOTICE( "Creating 'Link publication document' task for {}".format( work))) task.title = task_title task.description = '''This work's publication document could not be linked automatically. There may be more than one candidate, or it may be unavailable. First check under 'Edit work' for multiple candidates. If there are, choose the correct one. Otherwise, find it and upload it manually.''' task.country = work.country task.locality = work.locality task.work = work task.created_by_user = user if not self.dry_run: task.save() workflow_review_title = 'Link publication documents' try: workflow = work.place.workflows.get( title=workflow_review_title, closed=False) except Workflow.DoesNotExist: self.stdout.write( self.style.NOTICE("Creating workflow for {}".format(work))) workflow = Workflow() workflow.title = workflow_review_title workflow.description = 'These works\' publication documents could not be automatically linked.' workflow.country = task.country workflow.locality = task.locality workflow.created_by_user = user if not self.dry_run: workflow.save() if not self.dry_run: workflow.tasks.add(task) workflow.updated_by_user = user workflow.save()
def get_context_data(self, **kwargs): context = super(TaskDetailView, self).get_context_data(**kwargs) task = self.object # merge actions and comments actions = task.action_object_actions.all() task_content_type = ContentType.objects.get_for_model(self.model) comments = Comment.objects\ .filter(content_type=task_content_type, object_pk=task.id)\ .select_related('user') context['task_timeline'] = sorted( chain(comments, actions), key=lambda x: x.submit_date if hasattr(x, 'comment') else x.timestamp) context['possible_workflows'] = Workflow.objects.unclosed().filter( country=task.country, locality=task.locality).all() Task.decorate_potential_assignees([task], self.country) Task.decorate_permissions([task], self) return context
def get_context_data(self, **kwargs): context = super(TaskListView, self).get_context_data(**kwargs) context['task_labels'] = TaskLabel.objects.all() context['form'] = self.form context['frbr_uri'] = self.request.GET.get('frbr_uri') context['task_groups'] = Task.task_columns(self.form.cleaned_data['state'], context['tasks']) # warn when submitting task on behalf of another user Task.decorate_submission_message(context['tasks'], self) Task.decorate_potential_assignees(context['tasks'], self.country) Task.decorate_permissions(context['tasks'], self) return context
def get_context_data(self, **kwargs): context = super(WorkTasksView, self).get_context_data(**kwargs) context['tasks'] = context['work'].tasks.all() context['task_groups'] = Task.task_columns( ['open', 'assigned', 'pending_review', 'done', 'cancelled'], context['tasks']) # warn when submitting task on behalf of another user Task.decorate_submission_message(context['tasks'], self) Task.decorate_potential_assignees(context['tasks'], self.country) Task.decorate_permissions(context['tasks'], self) return context
def get_context_data(self, **kwargs): context = super(TaskDetailView, self).get_context_data(**kwargs) task = self.object # merge actions and comments actions = task.action_object_actions.all() task_content_type = ContentType.objects.get_for_model(self.model) comments = list(Comment.objects\ .filter(content_type=task_content_type, object_pk=task.id)\ .select_related('user')) # get the annotation for the particular task try: task_annotation = task.annotation except Annotation.DoesNotExist: task_annotation = None # for the annotation that is linked to the task, get all the replies if task_annotation: # get the replies to the annotation annotation_replies = Annotation.objects.filter(in_reply_to=task_annotation)\ .select_related('created_by_user') comments.extend([ Comment(user=a.created_by_user, comment=a.text, submit_date=a.created_at) for a in annotation_replies ]) context['task_timeline'] = sorted( chain(comments, actions), key=lambda x: x.submit_date if hasattr(x, 'comment') else x.timestamp) context['possible_workflows'] = Workflow.objects.unclosed().filter( country=task.country, locality=task.locality).all() # warn when submitting task on behalf of another user Task.decorate_submission_message([task], self) Task.decorate_potential_assignees([task], self.country) Task.decorate_permissions([task], self) # add work to context if task.work: context['work'] = task.work context['work_json'] = json.dumps( WorkSerializer(instance=task.work, context={ 'request': self.request }).data) return context
def get_context_data(self, *args, **kwargs): context = super(WorkflowDetailView, self).get_context_data(**kwargs) tasks = self.object.tasks.all() context['has_tasks'] = bool(tasks) context['task_groups'] = Task.task_columns( ['open', 'pending_review', 'assigned'], tasks) context['possible_tasks'] = self.place.tasks.unclosed().exclude( pk__in=[t.id for t in self.object.tasks.all()]).all() # stats self.object.n_tasks = self.object.tasks.count() self.object.n_done = self.object.tasks.closed().count() self.object.pct_done = self.object.n_done / (self.object.n_tasks or 1) * 100.0 context[ 'may_close'] = not self.object.closed and self.object.n_tasks == self.object.n_done context['may_reopen'] = self.object.closed stream = any_stream(self.object) context['activity_stream'] = self.coalesce_entries(stream) return context
def get_context_data(self, *args, **kwargs): context = super(WorkflowDetailView, self).get_context_data(**kwargs) # stats self.object.n_tasks = self.object.tasks.count() self.object.n_done = self.object.tasks.closed().count() self.object.pct_done = self.object.n_done / (self.object.n_tasks or 1) * 100.0 context['form'] = self.form tasks = self.form.filter_queryset(Task.objects.filter(workflows=self.object)) \ .select_related('document__language', 'document__language__language')\ .defer('document__document_xml')\ .all() context['tasks'] = tasks context['has_tasks'] = self.object.n_tasks > 0 context['task_groups'] = Task.task_columns( ['open', 'pending_review', 'assigned'], tasks) context['possible_tasks'] = Task.objects.filter(country=self.country, locality=self.locality)\ .unclosed()\ .exclude(workflows=self.object) \ .select_related('document__language', 'document__language__language') \ .defer('document__document_xml')\ .all() # warn when submitting task on behalf of another user Task.decorate_submission_message(tasks, self) Task.decorate_potential_assignees(tasks, self.country) Task.decorate_permissions(tasks, self) context[ 'may_close'] = not self.object.closed and self.object.n_tasks == self.object.n_done context['may_reopen'] = self.object.closed stream = any_stream(self.object) context['activity_stream'] = self.coalesce_entries(stream) return context
def get_form_kwargs(self): kwargs = super(TaskCreateView, self).get_form_kwargs() task = Task() task.country = self.country task.locality = self.locality task.created_by_user = self.request.user if self.request.GET.get('frbr_uri'): # pre-load a work try: work = Work.objects.get(frbr_uri=self.request.GET['frbr_uri']) if task.country == work.country and task.locality == work.locality: task.work = work except Work.DoesNotExist: pass kwargs['instance'] = task return kwargs
def create_task(self, work, info, task_type): task = Task() if task_type == 'link-publication-document': task.title = 'Link gazette' task.description = '''This work's gazette (original publication document) could not be linked automatically – see row {}. Find it and upload it manually.'''.format(info['row']) elif task_type == 'import': task.title = 'Import content' task.description = '''Import a point in time for this work; either the initial publication or a later consolidation. Make sure the document's expression date is correct.''' elif task_type == 'link-commencement': task.title = 'Link commencement' task.description = '''On the spreadsheet, it says that this work is commenced by '{}' – see row {}. The commencement work could not be linked automatically. Possible reasons: – a typo in the spreadsheet – more than one work by that name exists on the system – the commencing work doesn't exist on the system. Check the spreadsheet for reference and link it manually.'''.format(info['commenced_by'], info['row']) elif task_type == 'link-amendment': task.title = 'Link amendment(s)' amended_title = info['amends'] if len(amended_title) > 256: amended_title = "".join(amended_title[:256] + ', etc') task.description = '''On the spreadsheet, it says that this work amends '{}' – see row {}. The amendment could not be linked automatically. Possible reasons: – a typo in the spreadsheet – no date for the amendment – more than one amended work listed – the amended work doesn't exist on the system. Check the spreadsheet for reference and link it/them manually, or add the 'Pending commencement' label to this task if it doesn't have a date yet.'''.format(amended_title, info['row']) elif task_type == 'link-repeal': task.title = 'Link repeal' task.description = '''On the spreadsheet, it says that this work was repealed by '{}' – see row {}. The repeal could not be linked automatically. Possible reasons: – a typo in the spreadsheet – no date for the repeal – more than one work by that name exists on the system – the repealing work doesn't exist on the system. Check the spreadsheet for reference and link it manually, or add the 'Pending commencement' label to this task if it doesn't have a date yet.'''.format(info['repealed_by'], info['row']) elif task_type == 'link-primary-work': task.title = 'Link primary work' task.description = '''On the spreadsheet, it says that this work's primary work is '{}' – see row {}. The primary work could not be linked automatically. Possible reasons: – a typo in the spreadsheet – more than one work by that name exists on the system – the primary work doesn't exist on the system. Check the spreadsheet for reference and link it manually.'''.format(info['primary_work'], info['row']) task.country = self.country task.locality = self.locality task.work = work task.code = task_type task.created_by_user = self.user # need to save before assigning workflow because of M2M relation task.save() if self.workflow: task.workflows = [self.workflow] task.save() return task
class TaskTestCase(TestCase): fixtures = ['countries', 'user', 'work', 'drafts'] def setUp(self): self.user = User.objects.get(pk=1) self.task = Task( title='foo', description='bar', created_by_user=self.user) def test_discard_bad_work_country(self): na = Country.objects.get(country__pk='NA') self.task.country = na self.task.work = Work.objects.get(frbr_uri='/za/act/2014/10') self.task.clean() self.assertEqual(self.task.country, na) self.assertIsNone(self.task.work) def test_discard_bad_work_locality(self): za = Country.objects.get(country__pk='ZA') loc = za.localities.all()[0] self.task.country = za self.task.locality = loc self.task.work = Work.objects.get(frbr_uri='/za/act/2014/10') self.task.clean() self.assertEqual(self.task.country, za) self.assertEqual(self.task.locality, loc) self.assertIsNone(self.task.work) def test_cancel(self): za = Country.objects.get(country__pk='ZA') self.task.country = za self.task.cancel(self.user) self.task.save() self.task.refresh_from_db() self.assertEqual(Task.CANCELLED, self.task.state) self.assertIsNotNone(self.task.closed_at) self.assertIsNone(self.task.reviewed_by_user) def test_reopen(self): za = Country.objects.get(country__pk='ZA') self.task.country = za self.task.cancel(self.user) self.task.save() self.task.refresh_from_db() self.task.reopen(self.user) self.assertEqual(Task.OPEN, self.task.state) self.assertIsNone(self.task.closed_at) self.assertIsNone(self.task.reviewed_by_user) def test_close(self): za = Country.objects.get(country__pk='ZA') self.task.state = Task.PENDING_REVIEW self.task.country = za self.task.close(self.user) self.task.save() self.task.refresh_from_db() self.assertEqual(Task.DONE, self.task.state) self.assertIsNotNone(self.task.closed_at) self.assertEqual(self.user, self.task.reviewed_by_user)
def make_task(chosen_task): task = Task() task.country = self.country task.locality = self.locality task.work = info.get('work') task.created_by_user = self.request.user task.code = chosen_task for possible_task in form.possible_tasks: if chosen_task == possible_task['key']: task.title = possible_task['label'] task.description = possible_task['description'] # need to save before assigning workflow because of M2M relation task.save() task.workflows = [form.cleaned_data.get('workflow')] task.save()
def create_task(self, info, form, task_type): task = Task() if task_type == 'link-publication-document': task.title = 'Link publication document' task.description = '''This work's publication document could not be linked automatically – see row {}. Find it and upload it manually.'''.format(info['row']) elif task_type == 'link-commencement': task.title = 'Link commencement' task.description = '''On the spreadsheet, it says that this work is commenced by '{}' – see row {}. The commencement work could not be linked automatically. Possible reasons: – a typo in the spreadsheet – the commencing work hasn't been imported. Check the spreadsheet for reference and link it manually.'''.format( info['commenced_by'], info['row']) elif task_type == 'link-amendment': task.title = 'Link amendment(s)' amended_title = info['amends'] if len(amended_title) > 256: amended_title = "".join(amended_title[:256] + ', etc') task.description = '''On the spreadsheet, it says that this work amends '{}' – see row {}. The amendment could not be linked automatically. Possible reasons: – more than one amended work listed – a typo in the spreadsheet – no date for the amendment – the amended work hasn't been imported. Check the spreadsheet for reference and link it/them manually, or add the 'Pending commencement' label to this task if it doesn't have a date yet.'''.format( amended_title, info['row']) elif task_type == 'link-repeal': task.title = 'Link repeal' task.description = '''On the spreadsheet, it says that this work was repealed by '{}' – see row {}. The repeal could not be linked automatically. Possible reasons: – a typo in the spreadsheet – no date for the repeal – the repealing work hasn't been imported. Check the spreadsheet for reference and link it manually, or add the 'Pending commencement' label to this task if it doesn't have a date yet.'''.format( info['repealed_by'], info['row']) elif task_type == 'link-primary-work': task.title = 'Link primary work' task.description = '''On the spreadsheet, it says that this work's primary work is '{}' – see row {}. The primary work could not be linked automatically. Possible reasons: – a typo in the spreadsheet – the primary work hasn't been imported. Check the spreadsheet for reference and link it manually.'''.format( info['primary_work'], info['row']) task.country = self.country task.locality = self.locality task.work = info['work'] task.code = task_type task.created_by_user = self.request.user # need to save before assigning workflow because of M2M relation task.save() task.workflows = [form.cleaned_data.get('workflow')] task.save()
def create_task(self, info, form, task_type): task = Task() if task_type == 'commencement': task.title = 'Link commencement' task.description = '''This work's commencement work could not be linked automatically. There may have been a typo in the spreadsheet, or the work may not exist yet. Check the spreadsheet for reference and link it manually.''' elif task_type == 'amendment': task.title = 'Link amendment(s)' task.description = '''This work's amended work(s) could not be linked automatically. There may be more than one amended work listed, there may have been a typo in the spreadsheet, \ there may not be a date for the amendment, or the amended work may not exist yet. Check the spreadsheet for reference and link it/them manually, or add the 'Pending commencement' label to this task.''' elif task_type == 'repeal': task.title = 'Link repeal' task.description = '''According to the spreadsheet this work was repealed by the '{}', \ but the repeal could not be linked automatically. There may have been a typo in the spreadsheet, or the work may not exist yet. Otherwise, the 'with effect from' date could be in the wrong format, or the repealing work might not have commenced yet. Check the spreadsheet for reference and link it manually, or add the 'Pending commencement' label to this task.'''.format(info.get('repealed_by')) elif task_type == 'parent_work': task.title = 'Link parent work' task.description = '''This work's parent work could not be linked automatically. There may have been a typo in the spreadsheet, or the work may not exist yet. Check the spreadsheet for reference and link it manually.''' task.country = info['work'].country task.locality = info['work'].locality task.work = info['work'] task.created_by_user = self.request.user task.save() task.workflows = form.cleaned_data.get('workflows').all() task.save()
def setUp(self): self.task = Task(title='foo', description='bar')
def pub_doc_task(self, work, form, task_type): task = Task() if task_type == 'link': task.title = 'Link publication document' task.description = '''This work's publication document could not be linked automatically. There may be more than one candidate, or it may be unavailable. First check under 'Edit work' for multiple candidates. If there are, choose the correct one. Otherwise, find it and upload it manually.''' elif task_type == 'check': task.title = 'Check publication document' task.description = '''This work's publication document was linked automatically. Double-check that it's the right one.''' task.state = 'pending_review' task.country = work.country task.locality = work.locality task.work = work task.created_by_user = self.request.user task.save() task.workflows = form.cleaned_data.get('workflows').all() task.save()
def create_review_task(self, document, user, filename): task = Task() task.title = 'Review batch-imported document' task.description = ''' This document was imported as part of a batch from the file '{}'. - Double-check that the content is on the right work and at the right point in time. - Clean up any import errors as with a normal import. '''.format(filename) task.country = document.work.country task.locality = document.work.locality task.work = document.work task.document = document task.created_by_user = user task.save()
def create_task(self, work, info, task_type, repealing_work=None, amended_work=None, amendment=None): task = Task() if task_type == 'link-publication-document': task.title = 'Link gazette' task.description = f'''This work's gazette (original publication document) couldn't be linked automatically. Find it and upload it manually.''' elif task_type == 'import': task.title = 'Import content' task.description = '''Import the content for this work – either the initial publication (usually a PDF of the Gazette) or a later consolidation (usually a .docx file).''' elif task_type == 'link-commencement': task.title = 'Link commencement' task.description = f'''It looks like this work was commenced by "{info['commenced_by']}" (see row {info['row']} of the spreadsheet), but it couldn't be linked automatically. Possible reasons: – a typo in the spreadsheet – the commencing work doesn't exist on the system. Please link the commencing work manually.''' elif task_type == 'link-amendment': task.title = 'Link amendment' amended_work = info['amends'] if len(amended_work) > 256: amended_work = "".join(amended_work[:256] + ', etc') task.description = f'''It looks like this work amends "{amended_work}" (see row {info['row']} of the spreadsheet), but it couldn't be linked automatically. Possible reasons: – a typo in the spreadsheet – more than one amended work was listed (it only works if there's one) – the amended work doesn't exist on the system. Please link the amendment manually.''' elif task_type == 'link-amendment-pending-commencement': task.title = 'Link amendment' task.description = f'''It looks like this work amends {amended_work.title} ({amended_work.numbered_title()}), but it couldn't be linked automatically because this work hasn't commenced yet (so there's no date for the amendment). Please link the amendment manually (and apply it) when this work comes into force.''' elif task_type == 'apply-amendment': task.title = 'Apply amendment' task.description = f'''Apply the amendments made by {amendment.amending_work.title} ({amendment.amending_work.numbered_title()}) on {amendment.date}. The amendment has already been linked, so start at Step 3 of https://docs.laws.africa/managing-works/amending-works.''' elif task_type == 'no-repeal-match': task.title = 'Link repeal' task.description = f'''It looks like this work was repealed by "{info['repealed_by']}" (see row {info['row']} of the spreadsheet), but it couldn't be linked automatically. Possible reasons: – a typo in the spreadsheet – the repealing work doesn't exist on the system. Please link the repeal manually.''' elif task_type == 'check-update-repeal': task.title = 'Update repeal information?' task.description = f'''On the spreadsheet (see row {info['row']}), it says that this work was repealed by {repealing_work.title} ({repealing_work.numbered_title()}). But this work is already listed as having been repealed by {work.repealed_by} ({work.repealed_by.numbered_title()}), so the repeal information wasn't updated automatically. If the old / existing repeal information was wrong, update it manually. Otherwise (if the spreadsheet was wrong), cancel this task. ''' elif task_type == 'link-repeal-pending-commencement': repealed_work = info['work'] task.title = 'Link repeal' task.description = f'''It looks like this work repeals {repealed_work.title} ({repealed_work.numbered_title()}), but it couldn't be linked automatically because this work hasn't commenced yet (so there's no date for the repeal). Please link the repeal manually when this work comes into force.''' elif task_type == 'link-repeal': task.title = 'Link repeal' task.description = f'''It looks like this work was repealed by {repealing_work.title} ({repealing_work.numbered_title()}), but it couldn't be linked automatically. Please link it manually.''' elif task_type == 'link-primary-work': task.title = 'Link primary work' task.description = f'''It looks like this work's primary work is "{info['primary_work']}" (see row {info['row']} of the spreadsheet), but it couldn't be linked automatically. Possible reasons: – a typo in the spreadsheet – the primary work doesn't exist on the system. Please link the primary work manually.''' elif task_type == 'link-taxonomy': task.title = 'Link taxonomy' task.description = f'''It looks like this work has the following taxonomy: "{info['unlinked_topics']}" (see row {info['row']} of the spreadsheet), but it couldn't be linked automatically. Possible reasons: – a typo in the spreadsheet – the taxonomy doesn't exist on the system.''' task.country = self.country task.locality = self.locality task.work = work task.code = task_type task.created_by_user = self.user # need to save before assigning workflow because of M2M relation task.save() if self.workflow: task.workflows.set([self.workflow]) task.save() if 'pending-commencement' in task_type: # add the `pending commencement` label, if it exists pending_commencement_label = TaskLabel.objects.filter( slug='pending-commencement').first() if pending_commencement_label: task.labels.add(pending_commencement_label) task.save() return task
def setUp(self): self.user = User.objects.get(pk=1) self.task = Task( title='foo', description='bar', created_by_user=self.user)