示例#1
0
    def _get_currency_or_raise(self, model_name, currency):
        """
        get default currency if not available for currency-related fields
        """
        # TODO: this does not invalidate the whole element (budget,
        # transaction, planned disbursement) while it should
        if not currency:
            currency = getattr(self.get_model('Activity'), 'default_currency')
            if not currency:
                raise RequiredFieldError(
                    model_name,
                    "currency",
                    "must specify default-currency on iati-activity or as "
                    "currency on the element itself")

        return currency
示例#2
0
    def iati_activities__iati_activity__location__location_type(self, element):
        code = element.attrib.get('code')

        if not code:
            raise RequiredFieldError(
                "location/location-type",
                "code",
                "required attribute missing")

        feature_designation = E('feature-designation', code=code)
        super(
            Parse, self
        ).iati_activities__iati_activity__location__feature_designation(
            feature_designation
        )

        return element
示例#3
0
    def validate_date(self, unvalidated_date):

        if unvalidated_date:
            unvalidated_date = unvalidated_date.strip(' \t\n\rZ')
        else:
            return None

        # check if standard data parser works
        try:
            date = dateutil.parser.parse(unvalidated_date, ignoretz=True)
            if date.year >= 1900 and date.year <= 2100:
                return date
            else:
                return None
        except BaseException:
            raise RequiredFieldError(
                "TO DO", "iso-date",
                "Unspecified or invalid. Date should be of type xml:date.")
示例#4
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
示例#5
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
示例#6
0
    def iati_organisations__iati_organisation(self, element):
        id = element.xpath('organisation-identifier/text()')[0]
        normalized_id = self._normalize(id)
        last_updated_datetime = self.validate_date(
            element.attrib.get('last-updated-datetime'))
        # default is here to make it default to settings 'DEFAULT_LANG' on no
        # language set (validation error we want to be flexible per instance)

        default_lang_code = element.attrib.get(
            '{http://www.w3.org/XML/1998/namespace}lang',
            settings.DEFAULT_LANG)
        if default_lang_code:
            default_lang_code = default_lang_code.lower()

        default_lang = self.get_or_none(codelist_models.Language,
                                        code=default_lang_code)

        default_currency = self.get_or_none(
            codelist_models.Currency,
            code=element.attrib.get('default-currency'))

        if not id:
            raise RequiredFieldError(
                "", "id", "organisation: must contain organisation-identifier")

        # TODO: check for last-updated-datetime - 2017-03-27
        old_organisation = self.get_or_none(Organisation,
                                            organisation_identifier=id)

        if old_organisation:
            OrganisationName.objects.filter(
                organisation=old_organisation).delete()
            OrganisationReportingOrganisation.objects.filter(
                organisation=old_organisation).delete()
            TotalBudget.objects.filter(organisation=old_organisation).delete()
            RecipientOrgBudget.objects.filter(
                organisation=old_organisation).delete()
            RecipientCountryBudget.objects.filter(
                organisation=old_organisation).delete()
            RecipientRegionBudget.objects.filter(
                organisation=old_organisation).delete()
            TotalExpenditure.objects.filter(
                organisation=old_organisation).delete()
            OrganisationDocumentLink.objects.filter(
                organisation=old_organisation).delete()

            organisation = old_organisation
        else:
            organisation = Organisation()

        organisation.organisation_identifier = id
        organisation.normalized_organisation_identifier = normalized_id
        organisation.last_updated_datetime = last_updated_datetime
        organisation.default_lang = default_lang
        organisation.iati_standard_version_id = self.VERSION
        organisation.default_currency = default_currency

        organisation.published = True
        organisation.ready_to_publish = True
        organisation.modified = False

        self.organisation_identifier = organisation.organisation_identifier
        self.default_currency = default_currency

        # for later reference
        self.default_lang = default_lang

        self.register_model('Organisation', organisation)

        return element
示例#7
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,
        },
    }
示例#8
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'],
        },
    }
示例#9
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,
        },
    }
示例#10
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,
        },
    }
示例#11
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,
        },
    }