Exemple #1
0
    def guess_number(self, model_name, number_string):
        # first strip non numeric values, except for -.,
        decimal_string = re.sub(r'[^\d.,-]+', '', number_string)

        try:
            return Decimal(decimal_string)
        except ValueError:
            raise FieldValidationError(model_name, "value",
                                       "Must be decimal or integer string")
        except InvalidOperation:
            raise FieldValidationError(model_name, "value",
                                       "Must be decimal or integer string")
Exemple #2
0
    def iati_activities__iati_activity__location__gazetteer_entry(
            self, element):
        gazetteer_ref_code = element.attrib.get('gazetteer-ref')
        gazetteer_ref = self.gazetteer_agency_mapping.get(gazetteer_ref_code)
        code = element.text

        if not gazetteer_ref_code:
            raise RequiredFieldError(
                "location/gazetteer-entry",
                "gazetteer-ref",
                "required attribute missing")

        if not gazetteer_ref:
            raise FieldValidationError(
                "location/gazetteer-entry",
                "gazetteer-ref",
                "not found on the accompanying code list")

        if not code:
            raise RequiredFieldError(
                "location/gazetteer-entry",
                "text",
                "required element empty")

        location_id = E('location-id', code=code, vocabulary=gazetteer_ref)
        super(
            Parse, self
        ).iati_activities__iati_activity__location__location_id(
            location_id
        )

        return element
    def iati_organisations__iati_organisation__recipient_region_budget__value(
            self, element):
        """atributes:
        currency:USD
        value-date:2014-01-01

        tag:value"""
        model = self.get_model('RecipientRegionBudget')
        model.currency = self.get_or_none(codelist_models.Currency,
                                          code=self._get_currency_or_raise(
                                              'recipient-region-budget/value',
                                              element.attrib.get('currency')))
        value_date = element.attrib.get('value-date')
        if value_date is None:
            raise RequiredFieldError("RecipientRegionBudget", "value-date",
                                     "required field missing.")
        value_date = self.validate_date(value_date)
        if not value_date:
            raise FieldValidationError(
                "RecipientRegionBudget",
                "value-date",
                "not in the correct range.",
                None,
                None,
            )
        model.value = element.text
        model.value_date = value_date
        # store element
        return element
    def iati_organisations__iati_organisation__total_expenditure__expense_line__value(  # NOQA: E501
            self, element):
        """
        """
        model = self.get_model('TotalExpenditureBudgetLine',
                               self.total_expenditure_line_current_index)

        currency = element.attrib.get("currency")
        if not currency:
            currency = getattr(self.get_model("Organisation"),
                               "default_currency")
            if not currency:
                raise RequiredFieldError(
                    "TotalExpenditureLine", "currency",
                    "must specify default-currency on iati-activity or as "
                    "currency on the element itself.")

        else:
            currency = self.get_or_none(codelist_models.Currency,
                                        code=currency)
            if currency is None:
                raise FieldValidationError(
                    "TotalExpenditureLine",
                    "currency",
                    "not found on the accompanying codelist.",
                    None,
                    None,
                )
        model.value_date = self.validate_date(element.attrib.get('value-date'))
        model.currency = currency
        model.value = element.text
        return element
Exemple #5
0
def document_link_recipient_country(
    document_link,
    recipient_country_code,
):
    warnings = []
    errors = []

    recipient_country = get_or_none(models.Country,
                                    code=recipient_country_code)

    if not recipient_country_code:
        errors.append(
            RequiredFieldError(
                "organisation/document-link/recipient_country",
                "code",
                apiField="recipient_country.code",
            ))
    elif not recipient_country:
        errors.append(
            FieldValidationError(
                "organisation/document-link/recipient_country",
                "code",
                "recipient_country not found for code {}".format(
                    recipient_country_code),
                apiField="recipient_country.code",
            ))

    return {
        "warnings": warnings,
        "errors": errors,
        "validated_data": {
            "document_link": document_link,
            "recipient_country": recipient_country,
        },
    }
Exemple #6
0
def document_link_language(
    document_link,
    language_code,
):
    warnings = []
    errors = []

    language = get_or_none(models.Language, code=language_code)

    if not language_code:
        errors.append(
            RequiredFieldError(
                "organisation/document-link/language",
                "code",
                apiField="language.code",
            ))
    elif not language:
        errors.append(
            FieldValidationError(
                "organisation/document-link/language",
                "code",
                "language not found for code {}".format(language_code),
                apiField="language.code",
            ))

    return {
        "warnings": warnings,
        "errors": errors,
        "validated_data": {
            "document_link": document_link,
            "language": language,
        },
    }
Exemple #7
0
def document_link_category(
    document_link,
    category_code,
):
    warnings = []
    errors = []

    category = get_or_none(models.DocumentCategory, code=category_code)

    if not category_code:
        errors.append(
            RequiredFieldError(
                "organisation/document-link/category",
                "code",
                apiField="category.code",
            ))
    elif not category:
        errors.append(
            FieldValidationError(
                "organisation/document-link/category",
                "code",
                "category not found for code {}".format(category_code),
                apiField="category.code",
            ))

    return {
        "warnings": warnings,
        "errors": errors,
        "validated_data": {
            "document_link": document_link,
            "category": category,
        },
    }
Exemple #8
0
    def iati_organisations__iati_organisation__document_link__document_date(
            self, element):
        """attributes:
        format:application/vnd.oasis.opendocument.text
        url:http:www.example.org/docs/report_en.odt

        tag:document-link"""
        iso_date = element.attrib.get('iso-date')

        if not iso_date:
            raise RequiredFieldError("document-link/document-date", "iso-date",
                                     "required attribute missing")

        iso_date = self.validate_date(iso_date)

        if not iso_date:
            raise FieldValidationError("document-link/document-date",
                                       "iso-date",
                                       "iso-date not of type xsd:date")

        document_link = self.get_model(
            'OrganisationDocumentLink',
            self.organisation_document_link_current_index)

        document_link.iso_date = iso_date
        return element
Exemple #9
0
def organisation(
    organisation_identifier,
    default_lang,
    default_currency,
    name={},
    iati_standard_version="2.02",
    published=False,
):

    warnings = []
    errors = []

    default_currency = get_or_none(models.Currency, pk=default_currency)
    iati_standard_version = get_or_none(models.Version,
                                        pk=iati_standard_version)
    default_lang = get_or_none(models.Language, pk=default_lang)

    if not default_lang:
        warnings.append(
            RequiredFieldError(
                "organisation",
                "default-lang",
                apiField="default_lang",
            ))

    if not validate_organisation_identifier(organisation_identifier):
        errors.append(
            FieldValidationError(
                "organisation",
                "organisation-identifier",
                apiField="organisation_identifier",
            ))

    name_narratives = name.get('narratives', [])

    name_narratives = narratives_validate(name_narratives, default_lang, None,
                                          warnings, errors, "name")
    errors = errors + name_narratives['errors']
    warnings = warnings + name_narratives['warnings']

    return {
        "warnings": warnings,
        "errors": errors,
        "validated_data": {
            "organisation_identifier": organisation_identifier,
            "normalized_organisation_identifier": organisation_identifier,
            "default_lang": default_lang,
            "default_currency": default_currency,
            "iati_standard_version": iati_standard_version,
            "published": published,
            "name": {},
            "name_narratives": name_narratives['validated_data'],
        },
    }
Exemple #10
0
    def iati_organisations__iati_organisation__reporting_org(self, element):
        # Although OrganisationReportingOrganisation and Organisation has
        # One-to-One relation on the database level, we check here whether
        # element 'reporting-org' occurs only once in the parent element
        # 'organisation'.
        organisation = self.get_model('Organisation')
        if 'OrganisationReportingOrganisation' in self.model_store:
            for reporting_org in self.model_store[
                    'OrganisationReportingOrganisation']:

                if reporting_org.organisation == organisation:
                    raise ParserError("Organisation",
                                      "OrganisationReportingOrganisation",
                                      "must occur no more than once.")
        # narrative is parsed in different method but as it is required
        # sub-element in 'name' element so we check it here.
        narrative = element.xpath("narrative")
        if len(narrative) < 1:
            raise RequiredFieldError("OrganisationName", "narrative",
                                     "must occur at least once.")
        reporting_org_identifier = element.attrib.get("ref")
        if reporting_org_identifier is None:
            raise RequiredFieldError("OrganisationReportingOrganisation",
                                     "ref", "required field missing.")
        org_type = element.attrib.get("type")
        if org_type is None:
            raise RequiredFieldError("OrganisationReportingOrganisation",
                                     "type", "required field missing.")
        # here org_type is OrganisationType object.
        org_type = self.get_or_none(codelist_models.OrganisationType,
                                    code=org_type)
        if org_type is None:
            raise FieldValidationError(
                "OrganisationReportingOrganisation",
                "type",
                "not found on the accompanying codelist.",
                None,
                None,
            )
        secondary_reporter = self.makeBool(
            element.attrib.get("secondary-reporter"))

        reporting_org = OrganisationReportingOrganisation()
        reporting_org.organisation = organisation
        reporting_org.org_type = org_type
        reporting_org.secondary_reporter = secondary_reporter
        reporting_org.reporting_org_identifier = reporting_org_identifier

        self.register_model("OrganisationReportingOrganisation", reporting_org)
        return element
Exemple #11
0
    def iati_organisations__iati_organisation__name(self, element):
        name_list = self.get_model_list('OrganisationName')

        if name_list and len(name_list) > 0:
            raise FieldValidationError("name",
                                       "Duplicate names are not allowed")

        organisation = self.get_model('Organisation')

        name = OrganisationName()
        name.organisation = organisation

        self.register_model('OrganisationName', name)

        return element
Exemple #12
0
    def iati_organisations__iati_organisation__total_expenditure__value(
            self, element):
        """
        """
        model = self.get_model('TotalExpenditure',
                               self.total_expenditure_current_index)
        code = element.attrib.get('currency')
        currency = self.get_or_none(codelist_models.Currency, code=code)

        if not code:
            raise RequiredFieldError("total-expenditure/value/currency",
                                     "code", "required element empty")

        if not currency:
            raise FieldValidationError(
                "total-expenditure/value/currency", "code",
                "not found on the accompanying code list")

        model.value_date = self.validate_date(element.attrib.get('value-date'))
        model.currency = currency
        model.value = element.text
        return element
Exemple #13
0
    def iati_activities__iati_activity__other_identifier(self, element):
        """atributes:
    ref:ABC123-XYZ
    owner-name:A1
    tag:other-identifier"""
        identifier = element.text
        owner_ref = element.attrib.get('owner-ref')
        owner_name = element.attrib.get('owner-name')

        if not identifier:
            raise RequiredFieldError("other-identifier", "text",
                                     "required element empty")

        if identifier and len(identifier) > 200:
            raise FieldValidationError(
                "other-identifier", "text",
                "identifier is longer than 200 characters (unlikely and is \
                most often a data bug)")

        if not (owner_ref or owner_name):
            raise RequiredFieldError(
                "other-identifier", "owner-ref/owner-name",
                "either owner_ref or owner_name must be set")

        activity = self.get_model('Activity')

        other_identifier = models.OtherIdentifier()
        other_identifier.activity = activity
        other_identifier.identifier = identifier
        other_identifier.owner_ref = owner_ref

        # TODO: refactor this to not create an lxml element
        self.register_model('OtherIdentifier', other_identifier)

        if element.text:
            self.add_narrative(E('elem', owner_name), other_identifier)

        return element
Exemple #14
0
    def iati_activities__iati_activity__participating_org(self, element):
        """atributes:
        ref:BB-BBB-123456789
        role:Funding
        type:40

        tag:participating-org"""

        role_name = element.attrib.get('role')
        role = self.get_or_none(codelist_models.OrganisationRole,
                                name=role_name)

        if not role_name:
            raise RequiredFieldError("participating-org", "role",
                                     "required attribute missing")

        if not role:
            raise FieldValidationError(
                "participating-org", "role",
                "not found on the accompanying code list")

        element.attrib['role'] = role.code

        super(Parse,
              self).iati_activities__iati_activity__participating_org(element)

        participating_organisation = self.get_model(
            'ActivityParticipatingOrganisation')

        if element.text:
            self.add_narrative(element, participating_organisation)
            # workaround for IATI ref uniqueness limitation
            participating_organisation.primary_name = self.get_primary_name(
                element, participating_organisation.primary_name)

        return element
Exemple #15
0
def organisation_total_expenditure(
    organisation,
    period_start_raw,
    period_end_raw,
    value,
    currency_code,
    value_date_raw,
):
    warnings = []
    errors = []

    currency = get_or_none(models.Currency, code=currency_code)

    if not period_start_raw:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "period-start",
                apiField="period_start",
            ))
        period_start = None
    else:
        try:
            period_start = validate_date(period_start_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "recipient-org-budget",
                    "period-start",
                    "iso-date not of type xsd:date",
                    apiField="period_start",
                ))
            period_start = None

    if not period_end_raw:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "period-end",
                apiField="period_end",
            ))
        period_end = None
    else:
        try:
            period_end = validate_date(period_end_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "recipient-org-budget",
                    "period-end",
                    "iso-date not of type xsd:date",
                    apiField="period_end",
                ))
            period_end = None

    if not value:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "value",
                apiField="value",
            ))

    if not value_date_raw:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "value-date",
                apiField="value_date",
            ))
        value_date = None
    else:
        try:
            value_date = validate_date(value_date_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "recipient-org-budget",
                    "value-date",
                    "iso-date not of type xsd:date",
                    apiField="value_date",
                ))
            value_date = None

    if not currency and not organisation.default_currency:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "currency",
                "currency not specified and no default specified on \
                    organisation",
                apiField="currency.code",
            ))

    return {
        "warnings": warnings,
        "errors": errors,
        "validated_data": {
            "organisation": organisation,
            "period_start": period_start,
            "period_end": period_end,
            "value": value,
            "currency": currency,
            "value_date": value_date,
        },
    }
Exemple #16
0
def organisation_recipient_org_budget(
    organisation,
    status_code,
    recipient_org_identifier,
    period_start_raw,
    period_end_raw,
    value,
    currency_code,
    value_date_raw,
):
    warnings = []
    errors = []

    status = get_or_none(models.BudgetStatus, code=status_code)
    currency = get_or_none(models.Currency, code=currency_code)
    recipient_org = get_or_none(organisation_models.Organisation,
                                pk=recipient_org_identifier)

    if not status_code:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "status",
                apiField="status.code",
            ))
    if not status:
        errors.append(
            FieldValidationError(
                "recipient-org-budget",
                "status",
                "codelist entry not found for {}".format(status_code),
                apiField="status.code",
            ))

    if not recipient_org_identifier:
        errors.append(
            RequiredFieldError(
                "recipient-org-identifier",
                "recipient_org",
                apiField="recipient_org.code",
            ))
    # TODO: require that the org is in iati? - 2017-03-14
    # if not recipient_org:
    #     errors.append(
    #         FieldValidationError(
    #             "recipient-org-budget",
    #             "recipient_org",
    #             "codelist entry not found for {}".format(
    #                 recipient_org_identifier
    #             ),
    #             apiField="recipient_org.code",
    #             ))

    if not period_start_raw:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "period-start",
                apiField="period_start",
            ))
        period_start = None
    else:
        try:
            period_start = validate_date(period_start_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "recipient-org-budget",
                    "period-start",
                    "iso-date not of type xsd:date",
                    apiField="period_start",
                ))
            period_start = None

    if not period_end_raw:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "period-end",
                apiField="period_end",
            ))
        period_end = None
    else:
        try:
            period_end = validate_date(period_end_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "recipient-org-budget",
                    "period-end",
                    "iso-date not of type xsd:date",
                    apiField="period_end",
                ))
            period_end = None

    if not value:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "value",
                apiField="value",
            ))

    if not value_date_raw:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "value-date",
                apiField="value_date",
            ))
        value_date = None
    else:
        try:
            value_date = validate_date(value_date_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "recipient-org-budget",
                    "value-date",
                    "iso-date not of type xsd:date",
                    apiField="value_date",
                ))
            value_date = None

    if not currency and not organisation.default_currency:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "currency",
                "currency not specified and no default specified on \
                    organisation",
                apiField="currency.code",
            ))

    return {
        "warnings": warnings,
        "errors": errors,
        "validated_data": {
            "organisation": organisation,
            "status": status,
            "recipient_org_identifier": recipient_org_identifier,
            "recipient_org": recipient_org,
            "period_start": period_start,
            "period_end": period_end,
            "value": value,
            "currency": currency,
            "value_date": value_date,
        },
    }
Exemple #17
0
def organisation_recipient_region_budget(
    organisation,
    status_code,
    region_code,
    period_start_raw,
    period_end_raw,
    value,
    currency_code,
    value_date_raw,
):
    warnings = []
    errors = []

    status = get_or_none(models.BudgetStatus, code=status_code)
    currency = get_or_none(models.Currency, code=currency_code)
    region = get_or_none(models.Region, code=region_code)

    if not status_code:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "status",
                apiField="status.code",
            ))
    if not status:
        errors.append(
            FieldValidationError(
                "recipient-org-budget",
                "status",
                "codelist entry not found for {}".format(status_code),
                apiField="status.code",
            ))

    if not region_code:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "region",
                apiField="region.code",
            ))
    if not region:
        errors.append(
            FieldValidationError(
                "recipient-org-budget",
                "region",
                "codelist entry not found for {}".format(region_code),
                apiField="region.code",
            ))

    if not period_start_raw:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "period-start",
                apiField="period_start",
            ))
        period_start = None
    else:
        try:
            period_start = validate_date(period_start_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "recipient-org-budget",
                    "period-start",
                    "iso-date not of type xsd:date",
                    apiField="period_start",
                ))
            period_start = None

    if not period_end_raw:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "period-end",
                apiField="period_end",
            ))
        period_end = None
    else:
        try:
            period_end = validate_date(period_end_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "recipient-org-budget",
                    "period-end",
                    "iso-date not of type xsd:date",
                    apiField="period_end",
                ))
            period_end = None

    if not value:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "value",
                apiField="value",
            ))

    if not value_date_raw:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "value-date",
                apiField="value_date",
            ))
        value_date = None
    else:
        try:
            value_date = validate_date(value_date_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "recipient-org-budget",
                    "value-date",
                    "iso-date not of type xsd:date",
                    apiField="value_date",
                ))
            value_date = None

    if not currency and not organisation.default_currency:
        errors.append(
            RequiredFieldError(
                "recipient-org-budget",
                "currency",
                "currency not specified and no default specified on \
                    organisation",
                apiField="currency.code",
            ))

    return {
        "warnings": warnings,
        "errors": errors,
        "validated_data": {
            "organisation": organisation,
            "status": status,
            "region": region,
            "period_start": period_start,
            "period_end": period_end,
            "value": value,
            "currency": currency,
            "value_date": value_date,
        },
    }
Exemple #18
0
def organisation_recipient_country_budget_line(
    recipient_country_budget,
    ref,
    value,
    currency_code,
    value_date_raw,
    narratives_data,
):
    warnings = []
    errors = []

    if not narratives_data:
        narratives_data = []

    currency = get_or_none(models.Currency, code=currency_code)

    if not value:
        errors.append(
            RequiredFieldError(
                "total-budget/budget-line",
                "value",
                apiField="value",
            ))

    if not value_date_raw:
        errors.append(
            RequiredFieldError(
                "total-budget/budget-line",
                "value-date",
                apiField="value_date",
            ))
        value_date = None
    else:
        try:
            value_date = validate_date(value_date_raw)
        except RequiredFieldError:
            errors.append(
                FieldValidationError(
                    "total-budget/budget-line",
                    "value-date",
                    "iso-date not of type xsd:date",
                    apiField="value_date",
                ))
            value_date = None

    if (not currency
            and not recipient_country_budget.organisation.default_currency):
        errors.append(
            RequiredFieldError(
                "total-budget/budget-line",
                "currency",
                "currency not specified and no default specified on \
                    organisation",
                apiField="currency.code",
            ))

    narratives = narratives_validate(
        narratives_data, recipient_country_budget.organisation.default_lang,
        recipient_country_budget.organisation.id, warnings, errors,
        "total-budget/budget-line")
    errors = errors + narratives['errors']
    warnings = warnings + narratives['warnings']

    return {
        "warnings": warnings,
        "errors": errors,
        "validated_data": {
            "recipient_country_budget": recipient_country_budget,
            "ref": ref,
            "value": value,
            "currency": currency,
            "value_date": value_date,
            "narratives": narratives['validated_data'],
        },
    }
Exemple #19
0
def organisation_document_link(
    organisation,
    url,
    file_format_code,
    document_date_raw,
    title_narratives_data,
):
    warnings = []
    errors = []

    if not title_narratives_data:
        title_narratives_data = []

    file_format = get_or_none(models.FileFormat, code=file_format_code)

    if not file_format_code:
        errors.append(
            RequiredFieldError(
                "organisation/document-link",
                "file-format",
                apiField="file_format.code",
            ))
    elif not file_format:
        errors.append(
            FieldValidationError(
                "organisation/document-link",
                "file-format",
                "format not found for code {}".format(file_format_code),
                apiField="file_format.code",
            ))

    # TODO: check the url actually resolves? - 2016-12-14
    if not url:
        errors.append(
            RequiredFieldError(
                "document_link",
                "url",
                apiField="url",
            ))

    try:
        document_date = validate_date(document_date_raw)
    except RequiredFieldError:
        # if not document_date:
        #     errors.append(
        #             RequiredFieldError(
        #                 "organisation/document-link",
        #                 "document-date",
        #                 ))

        document_date = None

    title_narratives = narratives_validate(title_narratives_data,
                                           organisation.default_lang,
                                           organisation.id, warnings, errors,
                                           "title")
    errors = errors + title_narratives['errors']
    warnings = warnings + title_narratives['warnings']

    return {
        "warnings": warnings,
        "errors": errors,
        "validated_data": {
            "organisation": organisation,
            "url": url,
            "file_format": file_format,
            "title_narratives": title_narratives['validated_data'],
            "iso_date": document_date,
        },
    }