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
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
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.")
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
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
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
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, }, }
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'], }, }
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, }, }
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, }, }
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, }, }