def create_classification_entry(request): """ Create a new classification entry with a primary synonym in the current language. """ parameters = request.data parent = None if parameters.get('parent'): parent_id = int_arg(parameters['parent']) parent = get_object_or_404(ClassificationEntry, id=parent_id) rank_id = int_arg(parameters['rank']) language = parameters['language'] layout = request.data.get('layout') descriptors = request.data.get('descriptors') if not Language.objects.filter(code=language).exists(): raise SuspiciousOperation(_("The language is not supported")) if layout is not None and descriptors is not None: layout_id = int_arg(layout) content_type = get_object_or_404(ContentType, app_label="classification", model="classificationentry") layout = get_object_or_404(Layout, id=layout_id, target=content_type) else: # @todo do we allow that ? layout = None classification_entry = None try: with transaction.atomic(): classification_entry = ClassificationEntryManager.create_classification_entry( parameters['name'], rank_id, parent, language, layout, descriptors) except IntegrityError as e: Descriptor.integrity_except(ClassificationEntry, e) response = { 'id': classification_entry.id, 'name': classification_entry.name, 'rank': classification_entry.rank_id, 'parent': classification_entry.parent_id if parent else None, 'parent_list': classification_entry.parent_list, 'synonyms': [], 'layout': classification_entry.layout_id if layout else None, 'descriptors': classification_entry.descriptors } for s in classification_entry.synonyms.all(): response['synonyms'].append({ 'id': s.id, 'name': s.name, 'synonym_type': s.synonym_type_id, 'language': s.language }) return HttpResponseRest(request, response)
def patch_accession(request, acc_id): accession = get_object_or_404(Accession, id=int(acc_id)) entity_status = request.data.get("entity_status") descriptors = request.data.get("descriptors") result = {'id': accession.id} try: with transaction.atomic(): if 'primary_classification_entry' in request.data: primary_classification_entry_id = int( request.data['primary_classification_entry']) primary_classification_entry = get_object_or_404( ClassificationEntry, id=primary_classification_entry_id) # update FK accession.primary_classification_entry = primary_classification_entry result[ 'primary_classification_entry'] = primary_classification_entry.id # and replace from classification entry M2M previous primary accession_classification_entry = get_object_or_404( AccessionClassificationEntry, accession=accession, primary=True) accession_classification_entry.classification_entry = primary_classification_entry accession_classification_entry.save() accession.update_field('primary_classification_entry') if entity_status is not None and accession.entity_status != entity_status: accession.set_status(entity_status) result['entity_status'] = entity_status accession.update_field('entity_status') if descriptors is not None: # update descriptors descriptors_builder = DescriptorsBuilder(accession) descriptors_builder.check_and_update(accession.layout, descriptors) accession.descriptors = descriptors_builder.descriptors result['descriptors'] = accession.descriptors descriptors_builder.update_associations() accession.update_descriptors( descriptors_builder.changed_descriptors()) accession.update_field('descriptors') accession.save() except IntegrityError as e: Descriptor.integrity_except(Accession, e) return HttpResponseRest(request, result)
def patch_organisation(request, org_id): organisation = get_object_or_404(Organisation, id=int(org_id)) organisation_name = request.data.get("name") organisation_type = request.data.get("type") entity_status = request.data.get("entity_status") descriptors = request.data.get("descriptors") result = {'id': organisation.id} try: with transaction.atomic(): if organisation_name is not None: organisation.name = organisation_name result['name'] = organisation_name organisation.update_field('name') if organisation_type is not None: organisation.type = organisation_type result['type'] = organisation_type organisation.update_field('type') if entity_status is not None and organisation.entity_status != entity_status: organisation.set_status(entity_status) result['entity_status'] = entity_status if descriptors is not None: # update descriptors descriptors_builder = DescriptorsBuilder(organisation) descriptors_builder.check_and_update(organisation.layout, descriptors) organisation.descriptors = descriptors_builder.descriptors result['descriptors'] = organisation.descriptors descriptors_builder.update_associations() organisation.update_descriptors( descriptors_builder.changed_descriptors()) organisation.update_field('descriptors') organisation.save() except IntegrityError as e: Descriptor.integrity_except(Organisation, e) return HttpResponseRest(request, result)
def create_establishment(request): """ Create a new establishment. """ name = request.data['name'] descriptors = request.data['descriptors'] org_id = request.data['organisation'] # check existence of the organisation organisation = get_object_or_404(Organisation, id=int(org_id)) # check uniqueness of the name if Establishment.objects.filter(name=name).exists(): raise SuspiciousOperation(_("The name of the establishment is already used")) content_type = get_object_or_404(ContentType, app_label="organisation", model="establishment") layout = get_object_or_404(Layout, name="establishment", target=content_type) try: with transaction.atomic(): # common properties establishment = Establishment() establishment.name = request.data['name'] establishment.layout = layout establishment.organisation = organisation # descriptors descriptors_builder = DescriptorsBuilder(organisation) descriptors_builder.check_and_update(layout, descriptors) establishment.descriptors = descriptors_builder.descriptors establishment.save() # update owner on external descriptors descriptors_builder.update_associations() except IntegrityError as e: Descriptor.integrity_except(Organisation, e) response = { 'id': establishment.id, 'name': establishment.name, 'organisation': organisation.id, 'layout': layout.id, 'descriptors': establishment.descriptors } return HttpResponseRest(request, response)
def patch_establishment(request, est_id): establishment = get_object_or_404(Establishment, id=int(est_id)) organisation_name = request.data.get("name") entity_status = request.data.get("entity_status") descriptors = request.data.get("descriptors") result = { 'id': establishment.id } try: with transaction.atomic(): if organisation_name is not None: establishment.name = organisation_name result['name'] = organisation_name establishment.update_field('name') if entity_status is not None and establishment.entity_status != entity_status: establishment.set_status(entity_status) result['entity_status'] = entity_status if descriptors is not None: # update descriptors descriptors_builder = DescriptorsBuilder(establishment) descriptors_builder.check_and_update(establishment.layout, descriptors) establishment.descriptors = descriptors_builder.descriptors result['descriptors'] = establishment.descriptors descriptors_builder.update_associations() establishment.update_descriptors(descriptors_builder.changed_descriptors()) establishment.update_field('descriptors') establishment.save() except IntegrityError as e: Descriptor.integrity_except(Organisation, e) return HttpResponseRest(request, result)
def patch_classification_entry(request, cls_id): classification_entry = get_object_or_404(ClassificationEntry, id=int(cls_id)) result = {} if 'parent' in request.data: if request.data['parent'] is None: classification_entry.parent = None classification_entry.parent_list = [] result['parent'] = None result['parent_list'] = [] result['parent_details'] = [] else: pcls_id = int(request.data['parent']) parent = get_object_or_404(ClassificationEntry, id=pcls_id) classification_entry.parent = parent # @todo rank level if parent.rank_id >= classification_entry.rank_id: raise SuspiciousOperation( _("The rank of the parent must be lowest than the classification entry itself" )) # make parent list ClassificationEntryManager.update_parents(classification_entry, parent) # query for parents parents = [] parents_cls = ClassificationEntry.objects.filter( id__in=classification_entry.parent_list) for parent in parents_cls: parents.insert( 0, { 'id': parent.id, 'name': parent.name, 'rank': parent.rank_id, 'parent': parent.parent_id }) result['parent'] = parent.id result['parent_list'] = parents result['parent_details'] = parents classification_entry.update_field(['parent', 'parent_list']) try: with transaction.atomic(): # update layout of descriptors and descriptors if 'layout' in request.data: layout_id = request.data["layout"] # changing of layout erase all previous descriptors values if layout_id is None and classification_entry.layout is not None: # clean previous descriptors and owns descriptors_builder = DescriptorsBuilder( classification_entry) descriptors_builder.clear(classification_entry.layout) classification_entry.layout = None classification_entry.descriptors = {} descriptors_builder.update_associations() result['layout'] = None result['descriptors'] = {} elif layout_id is not None: # existing descriptors and new layout is different : first clean previous descriptors if (classification_entry.layout is not None and classification_entry.layout.pk != layout_id): # clean previous descriptors and owns descriptors_builder = DescriptorsBuilder( classification_entry) descriptors_builder.clear(classification_entry.layout) classification_entry.layout = None classification_entry.descriptors = {} descriptors_builder.update_associations() # and set the new one content_type = get_object_or_404( ContentType, app_label="classification", model="classificationentry") layout = get_object_or_404(Layout, id=layout_id, target=content_type) classification_entry.layout = layout classification_entry.descriptors = {} result['layout'] = layout.id result['descriptors'] = {} classification_entry.update_field( ['layout', 'descriptors']) # update descriptors if 'descriptors' in request.data: descriptors = request.data["descriptors"] descriptors_builder = DescriptorsBuilder(classification_entry) descriptors_builder.check_and_update( classification_entry.layout, descriptors) classification_entry.descriptors = descriptors_builder.descriptors descriptors_builder.update_associations() result['descriptors'] = classification_entry.descriptors classification_entry.update_descriptors( descriptors_builder.changed_descriptors()) classification_entry.update_field('descriptors') classification_entry.save() except IntegrityError as e: Descriptor.integrity_except(ClassificationEntry, e) return HttpResponseRest(request, result)
def create_organisation(request): """ Create a new organisation. """ name = request.data['name'] organisation_type = request.data['type'] descriptors = request.data['descriptors'] # check uniqueness of the name if Organisation.objects.filter(name=name).exists(): raise SuspiciousOperation( _("The name of the organisation is already used")) # check that type is in the values of descriptor if not Organisation.is_type(organisation_type): raise SuspiciousOperation(_("Unsupported type of organisation")) content_type = get_object_or_404(ContentType, app_label="organisation", model="organisation") layout = get_object_or_404(Layout, name="organisation", target=content_type) try: with transaction.atomic(): # common properties organisation = Organisation() organisation.name = request.data['name'] organisation.type = organisation_type organisation.layout = layout # descriptors descriptors_builder = DescriptorsBuilder(organisation) descriptors_builder.check_and_update(layout, descriptors) organisation.descriptors = descriptors_builder.descriptors organisation.save() # update owner on external descriptors descriptors_builder.update_associations() # add to GRC as partner if request.data['grc'] is True: grc = GRC.objects.get_unique_grc() grc.organisations.add(organisation) except IntegrityError as e: Descriptor.integrity_except(Organisation, e) response = { 'id': organisation.id, 'name': organisation.name, 'type': organisation.type, 'grc': request.data['grc'], 'layout': layout.id, 'descriptors': organisation.descriptors } return HttpResponseRest(request, response)
def create_accession(request): name = request.data['name'] naming_options = request.data['naming_options'] # code = request.data['code'] layout_id = int_arg(request.data['layout']) primary_classification_entry_id = int_arg( request.data['primary_classification_entry']) descriptors = request.data['descriptors'] language = request.data['language'] if not Language.objects.filter(code=language).exists(): raise SuspiciousOperation(_("The language is not supported")) naming_variables = {} code = NameBuilderManager.get(NameBuilderManager.GLOBAL_ACCESSION).pick( naming_variables, naming_options) # check uniqueness of the code for any type of synonym if AccessionSynonym.objects.filter(name=code).exists(): raise SuspiciousOperation( _("The code of the accession is already used as a synonym name")) # check uniqueness of the code if Accession.objects.filter(code=code).exists(): raise SuspiciousOperation( _("The code of the accession is already used")) if name == code: raise SuspiciousOperation( _("The code and the name of the accession must be different")) content_type = get_object_or_404(ContentType, app_label="accession", model="accession") layout = get_object_or_404(Layout, id=layout_id, target=content_type) try: with transaction.atomic(): # common properties accession = Accession() accession.name = name accession.code = code accession.layout = layout # primary classification entry primary_classification_entry = get_object_or_404( ClassificationEntry, id=primary_classification_entry_id) accession.primary_classification_entry = primary_classification_entry # descriptors descriptors_builder = DescriptorsBuilder(accession) descriptors_builder.check_and_update(layout, descriptors) accession.descriptors = descriptors_builder.descriptors accession.save() # update owner on external descriptors descriptors_builder.update_associations() # primary classifications in M2M AccessionClassificationEntry.objects.create( accession=accession, classification_entry=primary_classification_entry, primary=True) # initial synonym GRC code grc_code = AccessionSynonym( entity=accession, name=code, synonym_type_id=localsettings.synonym_type_accession_code, language='en') grc_code.save() # primary synonym if defined primary_name = AccessionSynonym( entity=accession, name=name, synonym_type_id=localsettings.synonym_type_accession_name, language=language) primary_name.save() accession.synonyms.add(grc_code) accession.synonyms.add(primary_name) # add related classification entries classification_entry_bulk = [] for classification_entry in primary_classification_entry.related.all( ): ace = AccessionClassificationEntry( primary=False, accession=accession, classification_entry=classification_entry) classification_entry_bulk.append(ace) AccessionClassificationEntry.objects.bulk_create( classification_entry_bulk) except IntegrityError as e: Descriptor.integrity_except(Accession, e) response = { 'id': accession.pk, 'name': accession.name, 'code': accession.code, 'layout': layout.id, 'primary_classification_entry': primary_classification_entry.id, 'descriptors': accession.descriptors, 'synonyms': [{ 'id': grc_code.id, 'name': grc_code.name, 'synonym_type': grc_code.synonym_type_id, 'language': grc_code.language }, { 'id': primary_name.id, 'name': primary_name.name, 'synonym_type': primary_name.synonym_type_id, 'language': primary_name.language }] } return HttpResponseRest(request, response)
def modify_panel_accessions(request, panel_id): action = request.data['action'] selection = request.data['selection']['select'] acc_panel = AccessionPanel.objects.get(id=int_arg(panel_id)) from main.cursor import CursorQuery cq = CursorQuery(Accession) if request.data['selection'].get('search'): search = json.loads(request.GET['search']) cq.filter(request.data['selection'].get('search')) if request.data['selection'].get('filters'): filters = json.loads(request.GET['filters']) cq.filter(request.data['selection'].get('filters')) cq.m2m_to_array_field(relationship=AccessionPanel.accessions, selected_field='accessionpanel_id', from_related_field='id', to_related_field='accession_id', alias='panels') cq.m2m_to_array_field(relationship=Accession.classifications_entries, selected_field='classification_entry_id', from_related_field='id', to_related_field='accession_id', alias='classifications') cq.set_synonym_model(AccessionSynonym) if request.data['selection'].get('from'): related_entity = request.data['selection']['from'] label, model = related_entity['content_type'].split('.') content_type = get_object_or_404(ContentType, app_label=label, model=model) model_class = content_type.model_class() cq.inner_join(model_class, **{model: int_arg(related_entity['id'])}) if action == 'remove': try: with transaction.atomic(): if isinstance(selection, bool): if selection is True: acc_panel.accessions.remove(*cq) elif selection['op'] == 'in': acc_panel.accessions.remove(*cq.filter( id__in=selection['value'])) elif selection['op'] == 'notin': acc_panel.accessions.remove(*cq.filter( id__notin=selection['value'])) acc_panel.save() except IntegrityError as e: Descriptor.integrity_except(AccessionPanel, e) elif action == 'add': try: with transaction.atomic(): if isinstance(selection, bool): if selection is True: acc_panel.accessions.add(*cq) elif selection['op'] == 'in': acc_panel.accessions.add(*cq.filter( id__in=selection['value'])) elif selection['op'] == 'notin': acc_panel.accessions.add(*cq.filter( id__notin=selection['value'])) acc_panel.save() except IntegrityError as e: Descriptor.integrity_except(AccessionPanel, e) else: raise SuspiciousOperation('Invalid action') return HttpResponseRest(request, {})
def modify_panel(request, panel_id): acc_panel = get_object_or_404(AccessionPanel, id=int(panel_id)) # entity_status = request.data.get("entity_status") descriptors = request.data.get("descriptors") result = {'id': acc_panel.id} try: with transaction.atomic(): # if entity_status is not None and panel.entity_status != entity_status: # panel.set_status(entity_status) # result['entity_status'] = entity_status if 'name' in request.data: name = request.data['name'] if AccessionPanel.objects.filter(name=name).exists(): raise SuspiciousOperation( _("The name of the panel is already used")) acc_panel.name = name result['name'] = name if 'layout' in request.data: layout_id = request.data["layout"] # changing of layout erase all previous descriptors values if layout_id is None and acc_panel.layout is not None: # clean previous descriptors and owns descriptors_builder = DescriptorsBuilder(acc_panel) descriptors_builder.clear(acc_panel.layout) acc_panel.layout = None acc_panel.descriptors = {} descriptors_builder.update_associations() result['layout'] = None result['descriptors'] = {} elif layout_id is not None: # existing descriptors and new layout is different : first clean previous descriptors if acc_panel.layout is not None and acc_panel.layout.pk != layout_id: # clean previous descriptors and owns descriptors_builder = DescriptorsBuilder(acc_panel) descriptors_builder.clear(acc_panel.layout) acc_panel.layout = None acc_panel.descriptors = {} descriptors_builder.update_associations() # and set the new one content_type = get_object_or_404(ContentType, app_label="accession", model="accessionpanel") layout = get_object_or_404(Layout, id=layout_id, target=content_type) acc_panel.layout = layout acc_panel.descriptors = {} result['layout'] = layout.id result['descriptors'] = {} acc_panel.update_field(['layout', 'descriptors']) if descriptors is not None: # update descriptors descriptors_builder = DescriptorsBuilder(acc_panel) descriptors_builder.check_and_update(acc_panel.layout, descriptors) acc_panel.descriptors = descriptors_builder.descriptors result['descriptors'] = acc_panel.descriptors descriptors_builder.update_associations() acc_panel.update_descriptors( descriptors_builder.changed_descriptors()) acc_panel.update_field('descriptors') acc_panel.save() except IntegrityError as e: Descriptor.integrity_except(Accession, e) return HttpResponseRest(request, result)
def create_panel(request): name = request.data['name'] selection = request.data['selection']['select'] related_entity = request.data['selection']['from'] search = request.data['selection']['search'] filters = request.data['selection']['filters'] layout_id = request.data['layout'] descriptors = request.data['descriptors'] layout = None # check uniqueness of the name if AccessionPanel.objects.filter(name=name).exists(): raise SuspiciousOperation(_("The name of the panel is already used")) if layout_id is not None: content_type = get_object_or_404(ContentType, app_label="accession", model="accessionpanel") layout = get_object_or_404(Layout, id=int_arg(layout_id), target=content_type) from main.cursor import CursorQuery cq = CursorQuery(Accession) if search: cq.filter(search) if filters: cq.filter(filters) cq.m2m_to_array_field(relationship=AccessionPanel.accessions, selected_field='accessionpanel_id', from_related_field='id', to_related_field='accession_id', alias='panels') cq.m2m_to_array_field(relationship=Accession.classifications_entries, selected_field='classification_entry_id', from_related_field='id', to_related_field='accession_id', alias='classifications') cq.set_synonym_model(AccessionSynonym) if related_entity: label, model = related_entity['content_type'].split('.') content_type = get_object_or_404(ContentType, app_label=label, model=model) model_class = content_type.model_class() cq.inner_join(model_class, **{model: int_arg(related_entity['id'])}) try: with transaction.atomic(): acc_panel = AccessionPanel(name=name) acc_panel.layout = layout acc_panel.count = 0 # descriptors descriptors_builder = DescriptorsBuilder(acc_panel) if layout: descriptors_builder.check_and_update(layout, descriptors) acc_panel.descriptors = descriptors_builder.descriptors acc_panel.save() # update owner on external descriptors descriptors_builder.update_associations() if isinstance(selection, bool): if selection is True: acc_panel.accessions.add(*cq) acc_panel.count = cq.count() elif selection['op'] == 'in': acc_panel.accessions.add(*cq.filter(id__in=selection['value'])) acc_panel.count = cq.filter(id__in=selection['value']).count() elif selection['op'] == 'notin': acc_panel.accessions.add(*cq.filter( id__notin=selection['value'])) acc_panel.count = cq.filter( id__notin=selection['value']).count() except IntegrityError as e: Descriptor.integrity_except(AccessionPanel, e) response = { 'id': acc_panel.pk, 'name': acc_panel.name, 'layout': acc_panel.layout.pk if acc_panel.layout else None, 'descriptors': acc_panel.descriptors, 'accessions_amount': acc_panel.count } return HttpResponseRest(request, response)
def modify_panel_batches(request, panel_id): action = request.data['action'] selection = request.data['selection']['select'] panel = BatchPanel.objects.get(id=int_arg(panel_id)) from main.cursor import CursorQuery cq = CursorQuery(Batch) if request.data['selection'].get('filters'): cq.filter(request.data['selection'].get('filters')) if request.data['selection'].get('search'): cq.filter(request.data['selection'].get('search')) if request.data['selection'].get('from'): related_entity = request.data['selection']['from'] label, model = related_entity['content_type'].split('.') content_type = get_object_or_404(ContentType, app_label=label, model=model) model_class = content_type.model_class() cq.inner_join(model_class, **{model: int_arg(related_entity['id'])}) if action == 'remove': try: with transaction.atomic(): if isinstance(selection, bool): if selection is True: panel.batches.remove(*cq) elif selection['op'] == 'in': panel.batches.remove(*cq.filter(id__in=selection['value'])) elif selection['op'] == 'notin': panel.batches.remove(*cq.filter( id__notin=selection['value'])) panel.save() except IntegrityError as e: Descriptor.integrity_except(BatchPanel, e) elif action == 'add': try: with transaction.atomic(): if isinstance(selection, bool): if selection is True: panel.batches.add(*cq) elif selection['op'] == 'in': panel.batches.add(*cq.filter(id__in=selection['value'])) elif selection['op'] == 'notin': panel.batches.add(*cq.filter(id__notin=selection['value'])) panel.save() except IntegrityError as e: Descriptor.integrity_except(BatchPanel, e) else: raise SuspiciousOperation('Invalid action') return HttpResponseRest(request, {})