Example #1
0
class Collection(TimeStampedModel):
    """A collection of metadata belonging to a Stewardship Organisation"""
    objects = CollectionQuerySet.as_manager()
    # objects = CollectionManager()

    stewardship_organisation = models.ForeignKey(
        'aristotle_mdr.StewardOrganisation',
        to_field="uuid",
        null=False,
        on_delete=models.CASCADE)
    name = ShortTextField(help_text=_("The name of the group."))
    description = MDR.RichTextField(_('description'), blank=True)

    metadata = ConceptManyToManyField('aristotle_mdr._concept', blank=True)
    parent_collection = models.ForeignKey('self',
                                          blank=True,
                                          null=True,
                                          on_delete=models.CASCADE)
    publication_details = GenericRelation(
        'aristotle_mdr_publishing.PublicationRecord')

    def get_absolute_url(self):
        return reverse("aristotle_mdr:stewards:group:collection_detail_view",
                       args=[self.stewardship_organisation.slug, self.pk])

    def __str__(self):
        return self.name
class DistributionDataElementPath(aristotle.models.aristotleComponent):
    class Meta:
        ordering = ['order']

    @property
    def parentItem(self):
        return self.distribution

    distribution = models.ForeignKey(
        Distribution,
        blank=True,
        null=True,
        help_text=_('A relation to the DCAT Distribution Record.'),
    )
    data_element = ConceptForeignKey(
        aristotle.models.DataElement,
        blank=True,
        null=True,
        help_text=_('An entity responsible for making the dataset available.'),
    )
    logical_path = models.CharField(
        max_length=256,
        help_text=
        _("A text expression that specifies how to identify which series of data in the distribution maps to this data element"
          ))
    order = models.PositiveSmallIntegerField(
        "Position",
        null=True,
        blank=True,
        help_text=_("Column position within a dataset."))
    specialisation_classes = ConceptManyToManyField(
        aristotle.models.ObjectClass, help_text=_(""), blank=True)
Example #3
0
class DistributionDataElementPath(aristotle.models.aristotleComponent):
    class Meta:
        ordering = ['order']

    parent_field_name = 'distribution'

    # TODO: Set this to NOT NULL
    distribution = models.ForeignKey(
        Distribution,
        blank=True,
        null=True,
        on_delete=models.CASCADE,
        help_text=_('A relation to the DCAT Distribution Record.'),
    )
    data_element = ConceptForeignKey(
        aristotle.models.DataElement,
        blank=True,
        null=True,
        help_text=_('An entity responsible for making the dataset available.'),
        verbose_name='Data Element',
        on_delete=models.SET_NULL,
    )
    logical_path = models.CharField(
        max_length=256,
        help_text=
        _("A text expression that specifies how to identify which series of data in the distribution maps to this data element"
          ))
    order = models.PositiveSmallIntegerField(
        "Position",
        null=True,
        blank=True,
        help_text=_("Column position within a dataset."))
    specialisation_classes = ConceptManyToManyField(
        aristotle.models.ObjectClass, help_text=_(""), blank=True)
class Framework(aristotle.models.concept):
    template = "comet/framework.html"
    parentFramework = ConceptForeignKey('Framework',
                                        blank=True,
                                        null=True,
                                        related_name="childFrameworks")
    indicators = ConceptManyToManyField(Indicator,
                                        related_name="frameworks",
                                        blank=True)
class IndicatorSet(aristotle.models.concept):
    template = "comet/indicatorset.html"
    indicators = ConceptManyToManyField(Indicator,
                                        related_name="indicatorSets",
                                        blank=True,
                                        null=True)
    indicatorSetType = models.ForeignKey(IndicatorSetType,
                                         blank=True,
                                         null=True)
class DSSDEInclusion(DSSInclusion):
    data_element = ConceptForeignKey(aristotle.models.DataElement,
                                     related_name="dssInclusions")
    specialisation_classes = ConceptManyToManyField(
        aristotle.models.ObjectClass, help_text=_(""))

    class Meta(DSSInclusion.Meta):
        verbose_name = "DSS Data Element Inclusion"

    @property
    def include(self):
        return self.data_element
class DSSDEInclusion(DSSInclusion):
    data_element = ConceptForeignKey(aristotle.models.DataElement,
                                     related_name="dssInclusions",
                                     on_delete=models.CASCADE)
    group = models.ForeignKey(DSSGrouping,
                              blank=True,
                              null=True,
                              on_delete=models.SET_NULL)
    specialisation_classes = ConceptManyToManyField(
        aristotle.models.ObjectClass,
        help_text=_(""),
        blank=True,
    )

    inline_field_layout = 'list'
    inline_field_order = [
        "order", "dss", "data_element", "reference", "inclusion",
        "maximum_occurrences", "conditional_inclusion", "specific_information",
        "group", "specialisation_classes"
    ]

    class Meta(DSSInclusion.Meta):
        verbose_name = "DSS Data Element"

    @property
    def include(self):
        return self.data_element

    @property
    def inline_editor_description(self):
        if self.group:
            msg = [
                "Data element: '{de}' in group '{group}'".format(
                    de=self.data_element.name, group=self.group.name)
            ]
        else:
            msg = ['Data element: {de}'.format(de=self.data_element.name)]
        return msg

    def __str__(self):
        has_reference = self.reference is not None and self.reference != ''
        if has_reference:
            return 'Data element {} at position {} with reference: {}.'.format(
                self.data_element_id, self.order, self.reference)
        return 'Data element {} at position {}'.format(self.data_element_id,
                                                       self.order)

    def get_absolute_url(self):
        pass
class Indicator(aristotle.models.concept):
    """
    An indicator is a single measure that is reported on regularly
    and that provides relevant and actionable information about population or system performance.
    """
    template = "comet/indicator.html"
    dataElementConcept = ConceptForeignKey(aristotle.models.DataElementConcept,
                                           verbose_name="Data Element Concept",
                                           blank=True,
                                           null=True)
    valueDomain = ConceptForeignKey(aristotle.models.ValueDomain,
                                    verbose_name="Value Domain",
                                    blank=True,
                                    null=True)
    outcome_areas = ConceptManyToManyField('OutcomeArea',
                                           related_name="indicators",
                                           blank=True)

    indicatorType = ConceptForeignKey(IndicatorType, blank=True, null=True)
    numerators = ConceptManyToManyField(aristotle.models.DataElement,
                                        related_name="as_numerator",
                                        blank=True)
    denominators = ConceptManyToManyField(aristotle.models.DataElement,
                                          related_name="as_denominator",
                                          blank=True)
    disaggregators = ConceptManyToManyField(aristotle.models.DataElement,
                                            related_name="as_disaggregator",
                                            blank=True)

    numerator_description = models.TextField(blank=True)
    numerator_computation = models.TextField(blank=True)
    denominator_description = models.TextField(blank=True)
    denominator_computation = models.TextField(blank=True)
    computationDescription = RichTextField(blank=True)
    rationale = RichTextField(blank=True)
    disaggregation_description = RichTextField(blank=True)
class DataSetSpecification(aristotle.models.concept):
    """
    A collection of :model:`aristotle_mdr.DataElement`\s
    specifying the order and fields required for a standardised
    :model:`aristotle_dse.DataSource`.
    """
    edit_page_excludes = ['clusters', 'data_elements']
    serialize_weak_entities = [
        ('clusters', 'dssclusterinclusion_set'),
        ('data_elements', 'dssdeinclusion_set'),
    ]

    template = "aristotle_dse/concepts/dataSetSpecification.html"
    ordered = models.BooleanField(
        default=False,
        help_text=
        _("Indicates if the ordering for a dataset is must match exactly the order laid out in the specification."
          ))
    statistical_unit = ConceptForeignKey(
        aristotle.models._concept,
        related_name='statistical_unit_of',
        blank=True,
        null=True,
        help_text=
        _("Indiciates if the ordering for a dataset is must match exactly the order laid out in the specification."
          ))
    data_elements = ConceptManyToManyField(aristotle.models.DataElement,
                                           blank=True,
                                           through='DSSDEInclusion')
    clusters = ConceptManyToManyField('self',
                                      through='DSSClusterInclusion',
                                      blank=True,
                                      null=True,
                                      symmetrical=False)
    collection_method = aristotle.models.RichTextField(blank=True,
                                                       help_text=_(''))
    implementation_start_date = models.DateField(blank=True,
                                                 null=True,
                                                 help_text=_(''))
    implementation_end_date = models.DateField(blank=True,
                                               null=True,
                                               help_text=_(''))

    def addDataElement(self, data_element, **kwargs):
        inc = DSSDEInclusion.objects.get_or_create(data_element=data_element,
                                                   dss=self,
                                                   defaults=kwargs)

    def addCluster(self, child, **kwargs):
        inc = DSSClusterInclusion.objects.get_or_create(child=child,
                                                        dss=self,
                                                        defaults=kwargs)

    @property
    def registry_cascade_items(self):
        return list(self.clusters.all()) + list(self.data_elements.all())

    def get_download_items(self):
        return [
            (DataSetSpecification, self.clusters.all()),
            (aristotle.models.DataElement, self.data_elements.all()),
            (aristotle.models.ObjectClass,
             aristotle.models.ObjectClass.objects.filter(
                 dataelementconcept__dataelement__datasetspecification=self)),
            (aristotle.models.Property,
             aristotle.models.Property.objects.filter(
                 dataelementconcept__dataelement__datasetspecification=self)),
            (aristotle.models.ValueDomain,
             aristotle.models.ValueDomain.objects.filter(
                 dataelement__datasetspecification=self)),
        ]
class Indicator(MDR.concept):
    """
    An indicator is a single measure that is reported on regularly
    and that provides relevant and actionable information about population or system performance.
    """
    # Subclassing from DataElement causes indicators to present as DataElements, which isn't quite right.
    backwards_compatible_fields = ['representation_class']

    template = "comet/indicator.html"
    outcome_areas = ConceptManyToManyField('OutcomeArea',
                                           related_name="indicators",
                                           blank=True)

    computation_description = MDR.RichTextField(blank=True)
    computation = MDR.RichTextField(blank=True)

    numerator_description = MDR.RichTextField(blank=True)
    denominator_description = MDR.RichTextField(blank=True)
    disaggregation_description = MDR.RichTextField(blank=True)

    quality_statement = ConceptForeignKey(
        "QualityStatement",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        help_text=
        _("A statement of multiple quality dimensions for the purpose of assessing the quality of the data for reporting against this Indicator."
          ))
    rationale = MDR.RichTextField(blank=True)
    benchmark = MDR.RichTextField(blank=True)
    reporting_information = MDR.RichTextField(blank=True)
    dimensions = ConceptManyToManyField("FrameworkDimension",
                                        related_name="indicators",
                                        blank=True)

    serialize_weak_entities = [
        ('numerators', 'indicatornumeratordefinition_set'),
        ('denominators', 'indicatordenominatordefinition_set'),
        ('disaggregators', 'indicatordisaggregationdefinition_set'),
    ]
    clone_fields = [
        'indicatornumeratordefinition', 'indicatordenominatordefinition',
        'indicatordisaggregationdefinition'
    ]

    def add_component(self, model_class, **kwargs):
        kwargs.pop('indicator', None)
        from django.db.models import Max
        max_order = list(
            model_class.objects.filter(indicator=self).annotate(
                latest=Max('order')).values_list('order', flat=True))
        if not max_order:
            order = 1
        else:
            order = max_order[0] + 1
        return model_class.objects.create(indicator=self,
                                          order=order,
                                          **kwargs)

    @property
    def numerators(self):
        return MDR.DataElement.objects.filter(
            indicatornumeratordefinition__indicator=self)

    def add_numerator(self, **kwargs):
        self.add_component(model_class=IndicatorNumeratorDefinition, **kwargs)

    @property
    def denominators(self):
        return MDR.DataElement.objects.filter(
            indicatordenominatordefinition__indicator=self)

    def add_denominator(self, **kwargs):
        self.add_component(model_class=IndicatorDenominatorDefinition,
                           **kwargs)

    @property
    def disaggregators(self):
        return MDR.DataElement.objects.filter(
            indicatordisaggregationdefinition__indicator=self)

    def add_disaggregator(self, **kwargs):
        self.add_component(model_class=IndicatorDisaggregationDefinition,
                           **kwargs)
class Indicator(MDR.concept):
    """
    An indicator is a single measure that is reported on regularly
    and that provides relevant and actionable information about population or system performance.
    """
    # Subclassing from DataElement causes indicators to present as DataElements, which isn't quite right.
    backwards_compatible_fields = ['representation_class']

    template = "comet/indicator.html"
    outcome_areas = ConceptManyToManyField('OutcomeArea',
                                           related_name="indicators",
                                           blank=True)
    quality_statement = ConceptForeignKey(
        "QualityStatement",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        help_text=
        _("A statement of multiple quality dimensions for the purpose of assessing the quality of the data for reporting against this Indicator."
          ))
    dimensions = ConceptManyToManyField("FrameworkDimension",
                                        related_name="indicators",
                                        blank=True)

    computation_description = MDR.RichTextField(blank=True)
    computation = MDR.RichTextField(blank=True)

    numerator_description = MDR.RichTextField(blank=True)
    denominator_description = MDR.RichTextField(blank=True)
    disaggregation_description = MDR.RichTextField(blank=True)

    rationale = MDR.RichTextField(blank=True)
    benchmark = MDR.RichTextField(blank=True)
    reporting_information = MDR.RichTextField(blank=True)

    serialize_weak_entities = [
        ('numerators', 'indicatornumeratordefinition_set'),
        ('denominators', 'indicatordenominatordefinition_set'),
        ('disaggregators', 'indicatordisaggregationdefinition_set'),
    ]
    clone_fields = [
        'indicatornumeratordefinition', 'indicatordenominatordefinition',
        'indicatordisaggregationdefinition'
    ]

    @property
    def relational_attributes(self):
        rels = {
            "indicator_sets": {
                "all":
                _("Indicator Sets that include this Indicator"),
                "qs":
                IndicatorSet.objects.filter(indicatorinclusion__indicator=self)
            },
        }

        if "aristotle_dse" in fetch_aristotle_settings().get(
                'CONTENT_EXTENSIONS'):
            from aristotle_dse.models import DataSetSpecification, Dataset

            numdefn_datasets = IndicatorNumeratorDefinition.objects.filter(
                indicator_id=self.id).values('data_set_id')
            dendefn_datasets = IndicatorDenominatorDefinition.objects.filter(
                indicator_id=self.id).values('data_set_id')
            dissagedefn_datasets = IndicatorDisaggregationDefinition.objects.filter(
                indicator_id=self.id).values('data_set_id')
            datasets = Dataset.objects.filter(id__in=Subquery(
                numdefn_datasets.union(dendefn_datasets).union(
                    dissagedefn_datasets)))

            rels.update({
                "data_sources": {
                    "all": _("Data Sets that are used in this Indicator"),
                    "qs": datasets
                },
            })
        return rels

    def add_component(self, model_class, **kwargs):
        kwargs.pop('indicator', None)
        from django.db.models import Max
        max_order = list(
            model_class.objects.filter(indicator=self).annotate(
                latest=Max('order')).values_list('order', flat=True))
        if not max_order:
            order = 1
        else:
            order = max_order[0] + 1
        return model_class.objects.create(indicator=self,
                                          order=order,
                                          **kwargs)

    @property
    def numerators(self):
        return MDR.DataElement.objects.filter(
            indicatornumeratordefinition__indicator=self)

    def add_numerator(self, **kwargs):
        self.add_component(model_class=IndicatorNumeratorDefinition, **kwargs)

    @property
    def denominators(self):
        return MDR.DataElement.objects.filter(
            indicatordenominatordefinition__indicator=self)

    def add_denominator(self, **kwargs):
        self.add_component(model_class=IndicatorDenominatorDefinition,
                           **kwargs)

    @property
    def disaggregators(self):
        return MDR.DataElement.objects.filter(
            indicatordisaggregationdefinition__indicator=self)

    def add_disaggregator(self, **kwargs):
        self.add_component(model_class=IndicatorDisaggregationDefinition,
                           **kwargs)