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 patch_batch(request, bat_id): batch = get_object_or_404(Batch, id=int(bat_id)) # check permission on accession object perms = get_permissions_for(request.user, batch.accession.content_type.app_label, batch.accession.content_type.model, batch.accession.pk) if 'accession.change_accession' not in perms: raise PermissionDenied( _('Invalid permission to modify this accession')) entity_status = request.data.get("entity_status") descriptors = request.data.get("descriptors") result = {'id': batch.id} try: with transaction.atomic(): if entity_status is not None and batch.entity_status != entity_status: batch.set_status(entity_status) result['entity_status'] = entity_status batch.update_field('entity_status') if descriptors is not None: # update descriptors descriptors_builder = DescriptorsBuilder(batch) descriptors_builder.check_and_update(batch.layout, descriptors) batch.descriptors = descriptors_builder.descriptors result['descriptors'] = batch.descriptors descriptors_builder.update_associations() batch.update_descriptors( descriptors_builder.changed_descriptors()) batch.update_field('descriptors') batch.save() except IntegrityError as e: logger.error(repr(e)) raise SuspiciousOperation(_("Unable to update the batch")) 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_batch(request): """ This is the deprecated way of creating a batch. Creation of a batch must be supervised by an action of creation. This method still because of its interest during development process. """ # name = request.data['name'] naming_options = request.data['naming_options'] accession_id = int_arg(request.data['accession']) layout_id = int_arg(request.data['layout']) descriptors = request.data['descriptors'] # batch selection selection = request.data['selection']['select'] related_entity = request.data['selection']['from'] search = request.data['selection']['search'] filters = request.data['selection']['filters'] # naming accession = get_object_or_404(Accession, id=accession_id) naming_variables = { 'ACCESSION_NAME': accession.name, 'ACCESSION_CODE': accession.code } name = NameBuilderManager.get(NameBuilderManager.GLOBAL_BATCH).pick( naming_variables, naming_options) # check uniqueness of the name if Batch.objects.filter(name=name).exists(): raise SuspiciousOperation(_("The name of the batch is already used")) content_type = get_object_or_404(ContentType, app_label="accession", model="batch") layout = get_object_or_404(Layout, id=layout_id, target=content_type) from main.cursor import CursorQuery cq = CursorQuery(Batch) if search: cq.filter(search) if filters: cq.filter(filters) 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(): # common properties batch = Batch() batch.name = name batch.layout = layout # parent accession accession = get_object_or_404(Accession, id=accession_id) batch.accession = accession # descriptors descriptors_builder = DescriptorsBuilder(batch) descriptors_builder.check_and_update(layout, descriptors) batch.descriptors = descriptors_builder.descriptors batch.save() # parent batches if isinstance(selection, bool): if selection is True: batch.batches.add(*cq) elif selection['op'] == 'in': batch.batches.add(*cq.filter(id__in=selection['value'])) elif selection['op'] == 'notin': batch.batches.add(*cq.filter(id__notin=selection['value'])) # update owner on external descriptors descriptors_builder.update_associations() except IntegrityError as e: logger.error(repr(e)) raise SuspiciousOperation(_("Unable to create the batch")) response = { 'id': batch.pk, 'name': batch.name, 'layout': layout.id, 'accession': accession.id, 'descriptors': descriptors } return HttpResponseRest(request, response)
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_classification_entry(cls, name, rank_id, parent, language, layout=None, descriptors=None): """ Create a new classification entry with a unique name. The level must be greater than its parent level. :param name: Unique classification entry name. :param rank_id: Classification rank with a greater level than its parent rank. :param parent: None or valid Classification entry instance. :param language: Language code of the primary synonym created with name. :param layout: Layout instance or None. :param descriptors: Descriptors values or None if no layout. :return: None or new Classification entry instance. """ if ClassificationEntry.objects.filter(name=name).exists(): raise SuspiciousOperation( _("A classification entry with this name already exists")) try: classification_rank = ClassificationRank.objects.get(id=rank_id) except ClassificationRank.DoesNotExist: raise SuspiciousOperation( _("The given classification rank does not exists")) if parent: if parent.rank.classification_id != classification_rank.classification_id: raise SuspiciousOperation( _("The parent and the children classification rank must be of the same nature" )) if parent.rank.level >= classification_rank.level: raise SuspiciousOperation( _("The rank level of the parent must be lesser than the rank level of the new classification entry" )) classification_entry = ClassificationEntry() classification_entry.name = name classification_entry.rank = classification_rank classification_entry.parent = parent classification_entry.parent_list = [] classification_entry.layout = layout if parent: try: ClassificationEntryManager.update_parents( classification_entry, parent) except ClassificationEntry.DoesNotExist: return None # descriptors if layout is not None: descriptors_builder = DescriptorsBuilder(classification_entry) descriptors_builder.check_and_update(layout, descriptors) classification_entry.descriptors = descriptors_builder.descriptors classification_entry.save() # first name a primary synonym primary_synonym = ClassificationEntrySynonym( entity_id=classification_entry.id, name=name, synonym_type_id=localsettings. synonym_type_classification_entry_name, language=language) primary_synonym.save() return classification_entry
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(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)