From bdf9e016a3f9d1e76c86f09f7c0fd6f8d6501dab Mon Sep 17 00:00:00 2001 From: "Ed (ODSC)" Date: Tue, 17 Dec 2024 12:32:27 +0000 Subject: [PATCH 1/4] libcovebods: Add handling of BODS 0.4 data Include BODS 0.4 schema, update to handle new jsonschema version, include BODS 0.4 specific checks, statistics and tests etc. --- CHANGELOG.md | 13 + MANIFEST.in | 2 + libcovebods/base_task.py | 3 + libcovebods/config.py | 8 +- libcovebods/data/schema-0-4-0.json | 4219 ++++++ .../data/schema-0-4-0/codelist-schema.json | 50 + .../schema-0-4-0/codelists/addressType.csv | 7 + .../codelists/annotationMotivation.csv | 6 + .../codelists/directOrIndirect.csv | 4 + .../schema-0-4-0/codelists/entitySubtype.csv | 6 + .../schema-0-4-0/codelists/entityType.csv | 8 + .../schema-0-4-0/codelists/interestType.csv | 24 + .../data/schema-0-4-0/codelists/nameType.csv | 7 + .../schema-0-4-0/codelists/personType.csv | 4 + .../schema-0-4-0/codelists/recordStatus.csv | 4 + .../schema-0-4-0/codelists/recordType.csv | 4 + .../codelists/securitiesIdentifierSchemes.csv | 5 + .../schema-0-4-0/codelists/sourceType.csv | 6 + .../codelists/unspecifiedReason.csv | 8 + libcovebods/data/schema-0-4-0/components.json | 237 + .../data/schema-0-4-0/entity-record.json | 356 + .../data/schema-0-4-0/person-record.json | 245 + .../schema-0-4-0/relationship-record.json | 191 + libcovebods/data/schema-0-4-0/statement.json | 337 + libcovebods/data_reader.py | 29 +- libcovebods/jsonschemavalidate.py | 39 +- libcovebods/run_tasks.py | 68 +- libcovebods/schema.py | 258 +- libcovebods/schema_dir.py | 41 + libcovebods/tasks/checks.py | 1253 +- libcovebods/tasks/statistics.py | 390 +- libcovebods/utils.py | 51 + pyproject.toml | 11 + setup.py | 9 +- tests/__init__.py | 0 tests/api.py | 5 +- ...ion_but_has_public_listing_is_false_1.json | 2 +- ...on_statement_pointer_target-invalid-1.json | 19 + ...on_statement_pointer_target-invalid-2.json | 21 + ...on_statement_pointer_target-invalid-3.json | 21 + ...tion_statement_pointer_target-valid-1.json | 21 + ...tion_statement_pointer_target-valid-2.json | 19 + ...ficial_ownership_or_control-invalid-1.json | 45 + ...neficial_ownership_or_control-valid-1.json | 43 + ...neficial_ownership_or_control-valid-2.json | 45 + ...ionship_interest_for_trusts-invalid-1.json | 43 + ...ionship_interest_for_trusts-invalid-2.json | 43 + ...ionship_interest_for_trusts-invalid-3.json | 43 + ...ationship_interest_for_trusts-valid-1.json | 44 + ...ationship_interest_for_trusts-valid-2.json | 44 + ...ationship_interest_for_trusts-valid-3.json | 44 + ...terest_nominee_or_nominator-invalid-1.json | 43 + ...terest_nominee_or_nominator-invalid-2.json | 44 + ...interest_nominee_or_nominator-valid-1.json | 44 + ...interest_nominee_or_nominator-valid-2.json | 44 + ...retrievedat_not_future_date-invalid-1.json | 18 + ...retrievedat_not_future_date-invalid-2.json | 18 + .../retrievedat_not_future_date-valid-1.json | 18 + .../retrievedat_not_future_date-valid-2.json | 18 + ...n_creation_date_future_date-invalid-1.json | 22 + ...n_creation_date_future_date-invalid-2.json | 22 + ...ion_creation_date_future_date-valid-1.json | 22 + ...tement_date_not_future_date-invalid-1.json | 15 + ...tement_date_not_future_date-invalid-2.json | 15 + ...tatement_date_not_future_date-valid-1.json | 15 + ...atement_declaration_subject-invalid-1.json | 38 + ...atement_declaration_subject-invalid-2.json | 38 + ...statement_declaration_subject-valid-1.json | 38 + ...ment_duplicate_statement_id-invalid-1.json | 38 + ...ment_duplicate_statement_id-invalid-2.json | 51 + ...tement_duplicate_statement_id-valid-1.json | 38 + ...oundation_dissolution_dates-invalid-1.json | 17 + ..._foundation_dissolution_dates-valid-1.json | 17 + ..._foundation_dissolution_dates-valid-2.json | 17 + ...ity_identifier_scheme_known-invalid-1.json | 44 + ...ity_identifier_scheme_known-invalid-2.json | 44 + ...ntity_identifier_scheme_known-valid-1.json | 44 + ...atement_entity_is_component-invalid-1.json | 85 + ...atement_entity_is_component-invalid-2.json | 86 + ...statement_entity_is_component-valid-1.json | 86 + ..._haspubliclisting_not_false-invalid-1.json | 27 + ...gs_haspubliclisting_not_false-valid-1.json | 18 + ...gs_haspubliclisting_not_false-valid-2.json | 20 + ...gs_haspubliclisting_not_false-valid-3.json | 27 + ...unique_statement_identifier-invalid-1.json | 38 + ...unique_statement_identifier-invalid-2.json | 51 + ...unique_statement_identifier-invalid-3.json | 51 + ...e_unique_statement_identifier-valid-1.json | 38 + ..._person_birth_date_sensible-invalid-1.json | 14 + ..._person_birth_date_sensible-invalid-2.json | 14 + ..._person_birth_date_sensible-invalid-3.json | 14 + ..._person_birth_date_sensible-invalid-4.json | 14 + ...nt_person_birth_date_sensible-valid-1.json | 14 + ...nt_person_birth_date_sensible-valid-2.json | 14 + ...t_person_date_of_death_sane-invalid-1.json | 15 + ...t_person_date_of_death_sane-invalid-2.json | 15 + ...t_person_date_of_death_sane-invalid-3.json | 14 + ...t_person_date_of_death_sane-invalid-4.json | 14 + ...ent_person_date_of_death_sane-valid-1.json | 15 + ...ent_person_date_of_death_sane-valid-2.json | 14 + ..._identifiers_correct_scheme-invalid-1.json | 17 + ..._identifiers_correct_scheme-invalid-2.json | 17 + ...on_identifiers_correct_scheme-valid-1.json | 17 + ...on_identifiers_correct_scheme-valid-2.json | 17 + ...tifiers_have_correct_scheme-invalid-1.json | 17 + ...tifiers_have_correct_scheme-invalid-2.json | 17 + ...tifiers_have_correct_scheme-invalid-3.json | 17 + ...tifiers_have_correct_scheme-invalid-4.json | 17 + ...tifiers_have_correct_scheme-invalid-5.json | 17 + ...tifiers_have_correct_scheme-invalid-6.json | 17 + ...entifiers_have_correct_scheme-valid-1.json | 17 + ...entifiers_have_correct_scheme-valid-2.json | 17 + ...atement_person_is_component-invalid-1.json | 44 + ...atement_person_is_component-invalid-2.json | 43 + ...statement_person_is_component-valid-1.json | 44 + ...nt_person_sensible_birth_date-valid-1.json | 14 + ...ublication_date_future_date-invalid-1.json | 20 + ...ublication_date_future_date-invalid-2.json | 22 + ..._publication_date_future_date-valid-1.json | 20 + ..._publication_date_future_date-valid-2.json | 22 + ...nent_records_are_record_ids-invalid-1.json | 86 + ...nent_records_are_record_ids-invalid-2.json | 86 + ...ponent_records_are_record_ids-valid-1.json | 86 + ...sted_party_entity_or_person-invalid-1.json | 45 + ...sted_party_entity_or_person-invalid-2.json | 63 + ...rested_party_entity_or_person-valid-1.json | 43 + ...rested_party_entity_or_person-valid-2.json | 45 + ...ship_interests_share_values-invalid-1.json | 47 + ...ship_interests_share_values-invalid-2.json | 47 + ...ship_interests_share_values-invalid-3.json | 47 + ...ship_interests_share_values-invalid-4.json | 47 + ...ship_interests_share_values-invalid-5.json | 46 + ...ship_interests_share_values-invalid-6.json | 46 + ...ship_interests_share_values-invalid-7.json | 46 + ...ship_interests_share_values-invalid-8.json | 46 + ...onship_interests_share_values-valid-1.json | 45 + ...onship_interests_share_values-valid-2.json | 46 + ...onship_interests_share_values-valid-3.json | 46 + ...p_interests_start_end_dates-invalid-1.json | 44 + ...hip_interests_start_end_dates-valid-1.json | 44 + ...hip_interests_start_end_dates-valid-2.json | 44 + ...t_relationship_is_component-invalid-1.json | 85 + ...t_relationship_is_component-invalid-2.json | 86 + ...ent_relationship_is_component-valid-1.json | 86 + ..._refers_to_entity_statement-invalid-1.json | 36 + ..._refers_to_entity_statement-invalid-2.json | 39 + ...ct_refers_to_entity_statement-valid-1.json | 38 + .../statement_serialisation-invalid-1.json | 38 + .../statement_serialisation-invalid-2.json | 38 + .../statement_serialisation-invalid-3.json | 25 + .../statement_serialisation-invalid-4.json | 27 + .../statement_serialisation-valid-1.json | 38 + .../statement_series-invalid-1.json | 68 + .../statement_series-invalid-2.json | 68 + .../statement_series-invalid-3.json | 68 + .../statement_series-invalid-4.json | 68 + .../statement_series-invalid-5.json | 26 + .../statement_series-valid-1.json | 68 + .../statement_series-valid-2.json | 63 + tests/fixtures/0.4/additional_fields_1.json | 17 + tests/fixtures/0.4/additional_fields_2.json | 34 + tests/fixtures/0.4/basic_1.json | 111 + .../0.4/basic_with_correct_mic_codes_1.json | 29 + ...sic_with_operating_mic_code_missing_1.json | 28 + .../0.4/entity_sub_type_does_align_1.json | 23 + .../0.4/entity_sub_type_does_not_align_1.json | 23 + .../0.4/entity_type_trust_arrangement.json | 23 + .../entity_type_trust_registeredentity.json | 23 + ...ion_but_has_public_listing_is_false_1.json | 27 + .../entity_addressType_placeOfBirth.json | 25 + .../entity_address_country_code_1chars.json | 25 + .../entity_address_country_code_3chars.json | 25 + ...ntity_address_country_name_not_string.json | 25 + .../entity_address_country_no_name.json | 25 + .../entity_address_country_no_object.json | 23 + .../entity_address_not_string.json | 21 + .../entity_addresses_not_array.json | 19 + .../entity_addresses_not_object.json | 18 + .../invalid-schema/entity_addresses_type.json | 21 + .../entity_alternate_names_not_array.json | 16 + .../entity_alternate_names_not_strings.json | 18 + .../entity_dissolution_date_number.json | 16 + .../entity_dissolution_date_string.json | 16 + .../entity_formed_by_statute_date_number.json | 18 + ...tity_formed_by_statute_date_year_only.json | 18 + .../entity_formed_by_statute_name_number.json | 18 + .../entity_formed_by_statute_string.json | 16 + .../entity_founding_date_not_date.json | 16 + .../entity_founding_date_not_string.json | 16 + .../entity_identifiers_id_number.json | 21 + .../entity_identifiers_no_scheme_info.json | 21 + .../entity_identifiers_not_array.json | 19 + .../entity_identifiers_not_objects.json | 18 + .../entity_identifiers_schemeName_number.json | 21 + .../entity_identifiers_uri_format.json | 22 + .../entity_isComponent_missing.json | 14 + .../entity_isComponent_not_boolean.json | 15 + .../entity_jurisdiction_code_1char.json | 19 + .../entity_jurisdiction_code_3chars.json | 19 + .../entity_jurisdiction_missing_name.json | 18 + .../entity_jurisdiction_name_number.json | 19 + .../entity_jurisdiction_not_object.json | 16 + .../entity_missing_declarationSubject.json | 14 + .../entity_name_not_string.json | 16 + .../entity_postcode_not_string.json | 21 + ...lic_listing_company_filings_not_array.json | 19 + ...ic_listing_company_filings_not_string.json | 21 + ...ublic_listing_company_filings_not_uri.json | 21 + ...ic_listing_has_public_listing_missing.json | 20 + ...c_listing_has_public_listing_not_bool.json | 18 + .../entity_public_listing_not_object.json | 16 + ...ity_recordDetails_missing_isComponent.json | 14 + .../entity_security_MIC_string.json | 28 + .../entity_security_OMIC_string.json | 28 + .../entity_security_id_number.json | 28 + .../entity_security_idscheme_wrong_code.json | 28 + ...tity_security_listing_no_jurisdiction.json | 26 + .../entity_security_listing_no_security.json | 24 + ...ty_security_listing_no_stock_exchange.json | 26 + .../entity_security_listing_no_ticker.json | 27 + .../entity_security_listing_not_array.json | 22 + .../entity_security_listing_string.json | 25 + ...ecurity_stock_jurisdiction_not_string.json | 27 + ..._security_stock_jurisdiction_too_long.json | 27 + ...security_stock_jurisdiction_too_short.json | 27 + .../entity_security_stock_name_string.json | 27 + .../entity_security_ticker_number.json | 27 + .../entity_statementDate_format.json | 15 + .../entity_statementDate_missing.json | 14 + .../entity_type_details_number.json | 23 + ...type_governmentDepartment_arrangement.json | 23 + .../entity_type_no_entity_type.json | 19 + .../entity_type_nomination_unknown.json | 23 + .../entity_type_not_object.json | 13 + .../invalid-schema/entity_type_notype.json | 21 + .../entity_type_state_stateAgency.json | 23 + .../entity_type_subtype_not_codelist.json | 16 + .../entity_type_trust_registeredentity.json | 23 + .../entity_type_type_not_codelist.json | 15 + ...ecified_entity_description_not_string.json | 19 + ...unspecified_entity_details_not_object.json | 16 + .../entity_unspecified_entity_no_reason.json | 18 + ...nspecified_entity_reason_not_codelist.json | 19 + .../0.4/invalid-schema/entity_uri_format.json | 16 + .../0.4/invalid-schema/entity_uri_string.json | 16 + .../0.4/invalid-schema/expected_errors.csv | 192 + ...erson_PepStatusDetails_endDate_string.json | 21 + ...pStatusDetails_jurisdiction_no_object.json | 21 + ...tatusDetails_missingInfoReason_string.json | 21 + .../person_PepStatusDetails_reason.json | 21 + ...son_PepStatusDetails_source_no_object.json | 21 + ...son_PepStatusDetails_startDate_string.json | 21 + .../person_addresses_birthplace.json | 19 + .../person_addresses_no_array.json | 21 + .../invalid-schema/person_addresses_type.json | 19 + .../person_birth_date_number.json | 14 + .../person_birth_place_not_object.json | 14 + .../person_death_date_number.json | 14 + .../person_identifiers_not_array.json | 17 + .../person_identifiers_not_object.json | 16 + .../person_isComponent_missing.json | 12 + .../person_iscomponent_not_bool.json | 13 + .../person_names_familyName_string.json | 19 + .../person_names_fullName_missing.json | 18 + .../person_names_fullName_string.json | 18 + .../person_names_givenName_string.json | 19 + .../person_names_not_array.json | 17 + .../person_names_not_objects.json | 16 + .../person_names_patronymic.json | 19 + .../person_names_type_code.json | 19 + ...n_politicalExposure_details_not_array.json | 19 + .../person_politicalExposure_no_object.json | 14 + .../person_politicalExposure_no_status.json | 14 + .../person_politicalExposure_status_code.json | 16 + .../person_taxResidencies_no_object.json | 14 + .../invalid-schema/person_type_missing.json | 12 + .../person_type_not_codelist.json | 13 + ...unspecified_person_details_not_object.json | 14 + .../publication_details_date_not_date.json | 22 + .../publication_details_date_not_string.json | 22 + ...ublication_details_license_not_string.json | 23 + .../publication_details_license_not_uri.json | 23 + .../publication_details_not_object.json | 16 + ...ion_details_publisher_name_not_string.json | 22 + ...ion_details_publisher_no_bods_version.json | 21 + ...ication_details_publisher_no_name_url.json | 22 + ...details_publisher_no_publication_date.json | 21 + ...cation_details_publisher_no_publisher.json | 19 + ...lication_details_publisher_not_object.json | 20 + ...tion_details_publisher_url_not_string.json | 22 + ...ication_details_publisher_url_not_uri.json | 22 + ...ublication_details_version_not_string.json | 22 + ...blication_details_version_not_version.json | 22 + ...ationship_component_records_not_array.json | 15 + ...tionship_component_records_not_string.json | 17 + .../relationship_component_records_true.json | 19 + .../relationship_interestedParty_missing.json | 13 + ...ionship_interested_party_invalid_type.json | 14 + ...eficialOwnershipOrControl_not_boolean.json | 19 + ...relationship_interests_details_string.json | 19 + ...onship_interests_direct_indirect_code.json | 19 + ...ionship_interests_end_date_dateformat.json | 19 + ...elationship_interests_end_date_string.json | 19 + ...ship_interests_exclusive_max_negative.json | 21 + ...nship_interests_exclusive_max_too_big.json | 21 + ...ship_interests_exclusive_min_negative.json | 21 + ...nship_interests_exclusive_min_too_big.json | 21 + .../relationship_interests_no_array.json | 17 + ...ionship_interests_share_exact_too_big.json | 21 + ...nship_interests_share_exact_too_small.json | 21 + ...nship_interests_share_maximum_too_big.json | 21 + ...hip_interests_share_maximum_too_small.json | 21 + ...nship_interests_share_minimum_too_big.json | 21 + ...hip_interests_share_minimum_too_small.json | 21 + ...lationship_interests_share_not_object.json | 19 + ...ship_interests_share_startDate_format.json | 19 + .../relationship_interests_type_code.json | 19 + .../relationship_isComponent_missing.json | 13 + .../relationship_isComponent_not_boolean.json | 14 + .../relationship_subject_invalid_type.json | 14 + .../relationship_subject_missing.json | 13 + ...ations.statementPointerTarget_missing.json | 20 + ...ent_annotations_createdBy_name_string.json | 24 + ...ement_annotations_createdBy_no_object.json | 22 + .../statement_annotations_createdBy_uri.json | 25 + .../statement_annotations_creationDate.json | 22 + ...nt_annotations_description_not_string.json | 22 + ...statement_annotations_motivation_code.json | 21 + ...tement_annotations_motivation_missing.json | 21 + .../statement_annotations_not_array.json | 21 + .../statement_annotations_not_object.json | 18 + ...notations_statementPointerTarget_type.json | 21 + ...tations_transformedContent_not_string.json | 22 + ...s_transformedContent_wrong_motivation.json | 22 + .../statement_annotations_url_format.json | 22 + ...ement_annotations_url_linking_missing.json | 21 + .../statement_declarationSubject_missing.json | 14 + .../statement_declarationSubject_string.json | 15 + .../statement_declaration_not_string.json | 16 + .../statement_recordDetails_missing.json | 10 + .../statement_recordDetails_no_object.json | 11 + .../statement_recordId_missing.json | 13 + .../statement_recordId_string.json | 15 + .../statement_recordStatus_code.json | 14 + .../statement_recordType_code.json | 15 + ...atement_source_assertedBy_name_string.json | 22 + ...statement_source_assertedBy_not_array.json | 20 + .../statement_source_assertedBy_uri.json | 22 + .../statement_source_description_string.json | 18 + .../statement_source_no_object.json | 16 + .../statement_source_retrievedAt_date.json | 18 + .../statement_source_type_code.json | 20 + .../statement_source_type_not_array.json | 18 + .../invalid-schema/statement_source_url.json | 18 + .../statement_statementDate_missing.json | 14 + ...atement_statementDate_not_date_string.json | 15 + .../statement_statementDate_not_string.json | 15 + .../statement_statementId_missing.json | 14 + .../statement_statementId_not_string.json | 15 + .../statement_statementId_too_long.json | 15 + .../statement_statementId_too_short.json | 15 + .../invalid-schema/statements_not_array.json | 13 + tests/fixtures/0.4/sample_300_statements.json | 10902 ++++++++++++++++ .../statistic_count_declaration_subjects.json | 152 + tests/fixtures/0.4/valid-schema/entity.json | 58 + tests/fixtures/0.4/valid-schema/entity_2.json | 47 + .../valid-schema/entity_address_address.json | 20 + .../valid-schema/entity_address_country.json | 26 + .../entity_address_country_2.json | 23 + .../entity_address_country_no_code.json | 25 + .../valid-schema/entity_address_postcode.json | 20 + .../0.4/valid-schema/entity_address_type.json | 20 + .../valid-schema/entity_addresses_type.json | 25 + .../valid-schema/entity_alternate_names.json | 18 + .../valid-schema/entity_dissolution_date.json | 16 + .../entity_formed_by_statute.json | 17 + .../entity_formed_by_statute_date.json | 18 + .../entity_formed_by_statute_name.json | 18 + .../valid-schema/entity_founding_date.json | 16 + .../valid-schema/entity_government_body.json | 23 + .../valid-schema/entity_identifiers_id.json | 21 + .../entity_identifiers_scheme.json | 20 + .../entity_identifiers_scheme_name.json | 20 + .../valid-schema/entity_identifiers_uri.json | 22 + .../entity_jurisdiction_code.json | 19 + .../entity_jurisdiction_name.json | 18 + .../0.4/valid-schema/entity_name.json | 16 + .../0.4/valid-schema/entity_nomination.json | 23 + .../valid-schema/entity_public_listing.json | 18 + ...entity_public_listing_company_filings.json | 21 + .../0.4/valid-schema/entity_security_MIC.json | 28 + .../valid-schema/entity_security_OMIC.json | 28 + .../0.4/valid-schema/entity_security_id.json | 28 + .../entity_security_idscheme.json | 28 + .../valid-schema/entity_security_listing.json | 27 + .../valid-schema/entity_statementDate.json | 15 + .../entity_statementDate_time.json | 15 + .../entity_trust_legal_entity.json | 23 + .../0.4/valid-schema/entity_type_details.json | 23 + ...entity_type_registered_entity_subtype.json | 17 + .../entity_type_statebody_other.json | 23 + .../entity_type_trust_arrangement.json | 23 + ...entity_unspecified_entity_description.json | 19 + .../entity_unspecified_entity_details.json | 18 + .../fixtures/0.4/valid-schema/entity_uri.json | 16 + tests/fixtures/0.4/valid-schema/person.json | 53 + tests/fixtures/0.4/valid-schema/person_2.json | 40 + .../person_PepStatusDetails_endDate.json | 21 + .../person_PepStatusDetails_jurisdiction.json | 24 + ...on_PepStatusDetails_missingInfoReason.json | 21 + .../person_PepStatusDetails_reason.json | 21 + .../person_PepStatusDetails_source.json | 25 + .../person_PepStatusDetails_startDate.json | 21 + .../valid-schema/person_addresses_type.json | 23 + .../0.4/valid-schema/person_birth_date.json | 14 + .../valid-schema/person_birth_date_year.json | 14 + .../person_birth_date_year_month.json | 14 + .../0.4/valid-schema/person_birth_place.json | 21 + .../valid-schema/person_death_date_full.json | 14 + .../valid-schema/person_death_date_year.json | 14 + .../person_death_date_year_month.json | 14 + .../valid-schema/person_identifiers_id.json | 19 + .../person_identifiers_scheme.json | 18 + .../person_identifiers_scheme_name.json | 18 + .../person_names_family_name.json | 19 + .../valid-schema/person_names_full_name.json | 18 + .../valid-schema/person_names_given_name.json | 19 + .../valid-schema/person_names_patronymic.json | 19 + .../0.4/valid-schema/person_names_type.json | 19 + .../person_nationalities_code.json | 19 + .../person_nationalities_name.json | 18 + .../person_politicalExposure_object.json | 16 + .../valid-schema/person_taxResidencies.json | 19 + .../person_unspecified_person_details.json | 16 + .../publication_details_date.json | 22 + .../publication_details_license.json | 23 + .../publication_details_publisher_name.json | 22 + ...ublication_details_publisher_name_url.json | 23 + .../publication_details_publisher_url.json | 22 + .../publication_details_version.json | 22 + .../0.4/valid-schema/record_status.json | 14 + .../0.4/valid-schema/relationship.json | 45 + .../0.4/valid-schema/relationship_2.json | 60 + .../relationship_component_records.json | 19 + .../relationship_interested_party.json | 14 + ...p_interested_party_unspecified_object.json | 16 + ...rests_beneficial_ownership_or_control.json | 19 + .../relationship_interests_details.json | 19 + ...tionship_interests_direct_or_indirect.json | 19 + .../relationship_interests_end_date.json | 19 + .../relationship_interests_share.json | 21 + ...ship_interests_share_exclusive_minmax.json | 22 + .../relationship_interests_start_date.json | 19 + .../relationship_interests_type.json | 19 + .../relationship_is_component_true.json | 15 + .../relationship_is_component_true2.json | 14 + .../valid-schema/relationship_subject.json | 14 + ...lationship_subject_unspecified_object.json | 16 + tests/fixtures/0.4/valid-schema/source.json | 22 + .../statement_annotations_createdBy.json | 24 + .../statement_annotations_createdBy_uri.json | 25 + .../statement_annotations_creationDate.json | 22 + ...atement_annotations_creationDate_time.json | 22 + .../statement_annotations_description.json | 22 + ...atement_annotations_empty_transformed.json | 22 + ...nt_annotations_statementPointerTarget.json | 21 + ...tement_annotations_transformedContent.json | 22 + .../statement_annotations_url.json | 22 + .../statement_annotations_url_linking.json | 22 + .../statement_source_assertedBy_uri.json | 22 + .../statement_source_description.json | 18 + .../statement_source_retrievedAt.json | 18 + .../statement_source_retrievedAt_time.json | 18 + .../valid-schema/statement_source_type.json | 20 + .../valid-schema/statement_source_url.json | 18 + tests/test_additional_checks_0_4_0.py | 2191 ++++ tests/test_additional_fields_0_4_0.py | 46 + tests/test_api_0_1.py | 4 +- tests/test_api_0_4.py | 145 + tests/test_data_reader.py | 15 + tests/test_lib_common.py | 5 +- tests/test_sample_mode.py | 24 + tests/test_schema_validation_0_4.py | 103 + tests/test_stat_count_declaration_subjects.py | 23 + tests/test_stat_count_entity_statements.py | 82 + ...at_count_ownership_or_control_statement.py | 52 + ...l_statement_interest_direct_or_indirect.py | 3 +- ...trol_statement_interest_statement_types.py | 12 +- tests/test_stat_count_person_statements.py | 55 + tests/test_stat_counts_0_4.py | 85 + 490 files changed, 32685 insertions(+), 167 deletions(-) create mode 100644 libcovebods/data/schema-0-4-0.json create mode 100644 libcovebods/data/schema-0-4-0/codelist-schema.json create mode 100644 libcovebods/data/schema-0-4-0/codelists/addressType.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/annotationMotivation.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/directOrIndirect.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/entitySubtype.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/entityType.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/interestType.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/nameType.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/personType.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/recordStatus.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/recordType.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/securitiesIdentifierSchemes.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/sourceType.csv create mode 100644 libcovebods/data/schema-0-4-0/codelists/unspecifiedReason.csv create mode 100644 libcovebods/data/schema-0-4-0/components.json create mode 100644 libcovebods/data/schema-0-4-0/entity-record.json create mode 100644 libcovebods/data/schema-0-4-0/person-record.json create mode 100644 libcovebods/data/schema-0-4-0/relationship-record.json create mode 100644 libcovebods/data/schema-0-4-0/statement.json create mode 100644 libcovebods/schema_dir.py create mode 100644 pyproject.toml create mode 100644 tests/__init__.py create mode 100644 tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_date_not_future_date-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_date_not_future_date-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_date_not_future_date-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_declaration_subject-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_declaration_subject-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_declaration_subject-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_is_component-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_is_component-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_is_component-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-4.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-4.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-4.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-5.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-6.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_is_component-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_is_component-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_is_component-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_person_sensible_birth_date-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-4.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-5.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-6.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-7.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-8.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-valid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_is_component-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_is_component-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_is_component-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-4.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_serialisation-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_series-invalid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_series-invalid-2.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_series-invalid-3.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_series-invalid-4.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_series-invalid-5.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_series-valid-1.json create mode 100644 tests/fixtures/0.4/additional-checks/statement_series-valid-2.json create mode 100644 tests/fixtures/0.4/additional_fields_1.json create mode 100644 tests/fixtures/0.4/additional_fields_2.json create mode 100644 tests/fixtures/0.4/basic_1.json create mode 100644 tests/fixtures/0.4/basic_with_correct_mic_codes_1.json create mode 100644 tests/fixtures/0.4/basic_with_operating_mic_code_missing_1.json create mode 100644 tests/fixtures/0.4/entity_sub_type_does_align_1.json create mode 100644 tests/fixtures/0.4/entity_sub_type_does_not_align_1.json create mode 100644 tests/fixtures/0.4/entity_type_trust_arrangement.json create mode 100644 tests/fixtures/0.4/entity_type_trust_registeredentity.json create mode 100644 tests/fixtures/0.4/has_public_listing_information_but_has_public_listing_is_false_1.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_addressType_placeOfBirth.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_address_country_code_1chars.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_address_country_code_3chars.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_address_country_name_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_address_country_no_name.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_address_country_no_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_address_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_addresses_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_addresses_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_addresses_type.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_alternate_names_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_alternate_names_not_strings.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_dissolution_date_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_dissolution_date_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_date_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_date_year_only.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_name_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_founding_date_not_date.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_founding_date_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_identifiers_id_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_identifiers_no_scheme_info.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_identifiers_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_identifiers_not_objects.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_identifiers_schemeName_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_identifiers_uri_format.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_isComponent_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_isComponent_not_boolean.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_jurisdiction_code_1char.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_jurisdiction_code_3chars.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_jurisdiction_missing_name.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_jurisdiction_name_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_jurisdiction_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_missing_declarationSubject.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_name_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_postcode_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_uri.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_public_listing_has_public_listing_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_public_listing_has_public_listing_not_bool.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_public_listing_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_recordDetails_missing_isComponent.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_MIC_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_OMIC_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_id_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_idscheme_wrong_code.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_listing_no_jurisdiction.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_listing_no_security.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_listing_no_stock_exchange.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_listing_no_ticker.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_listing_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_listing_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_too_long.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_too_short.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_stock_name_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_security_ticker_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_statementDate_format.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_statementDate_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_details_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_governmentDepartment_arrangement.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_no_entity_type.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_nomination_unknown.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_notype.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_state_stateAgency.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_subtype_not_codelist.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_trust_registeredentity.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_type_type_not_codelist.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_description_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_details_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_no_reason.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_reason_not_codelist.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_uri_format.json create mode 100644 tests/fixtures/0.4/invalid-schema/entity_uri_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/expected_errors.csv create mode 100644 tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_endDate_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_jurisdiction_no_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_missingInfoReason_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_reason.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_source_no_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_startDate_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_addresses_birthplace.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_addresses_no_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_addresses_type.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_birth_date_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_birth_place_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_death_date_number.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_identifiers_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_identifiers_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_isComponent_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_iscomponent_not_bool.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_names_familyName_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_names_fullName_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_names_fullName_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_names_givenName_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_names_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_names_not_objects.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_names_patronymic.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_names_type_code.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_politicalExposure_details_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_politicalExposure_no_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_politicalExposure_no_status.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_politicalExposure_status_code.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_taxResidencies_no_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_type_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_type_not_codelist.json create mode 100644 tests/fixtures/0.4/invalid-schema/person_unspecified_person_details_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_date_not_date.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_date_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_license_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_license_not_uri.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_publisher_name_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_bods_version.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_name_url.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_publication_date.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_publisher.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_publisher_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_publisher_url_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_publisher_url_not_uri.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_version_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/publication_details_version_not_version.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_component_records_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_component_records_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_component_records_true.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interestedParty_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interested_party_invalid_type.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_beneficialOwnershipOrControl_not_boolean.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_details_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_direct_indirect_code.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_end_date_dateformat.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_end_date_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_max_negative.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_max_too_big.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_min_negative.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_min_too_big.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_no_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_share_exact_too_big.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_share_exact_too_small.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_share_maximum_too_big.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_share_maximum_too_small.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_share_minimum_too_big.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_share_minimum_too_small.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_share_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_share_startDate_format.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_interests_type_code.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_isComponent_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_isComponent_not_boolean.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_subject_invalid_type.json create mode 100644 tests/fixtures/0.4/invalid-schema/relationship_subject_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations.statementPointerTarget_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_name_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_no_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_uri.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_creationDate.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_description_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_motivation_code.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_motivation_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_not_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_statementPointerTarget_type.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_transformedContent_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_transformedContent_wrong_motivation.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_url_format.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_annotations_url_linking_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_declarationSubject_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_declarationSubject_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_declaration_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_recordDetails_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_recordDetails_no_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_recordId_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_recordId_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_recordStatus_code.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_recordType_code.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_name_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_uri.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_source_description_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_source_no_object.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_source_retrievedAt_date.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_source_type_code.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_source_type_not_array.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_source_url.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_statementDate_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_statementDate_not_date_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_statementDate_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_statementId_missing.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_statementId_not_string.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_statementId_too_long.json create mode 100644 tests/fixtures/0.4/invalid-schema/statement_statementId_too_short.json create mode 100644 tests/fixtures/0.4/invalid-schema/statements_not_array.json create mode 100644 tests/fixtures/0.4/sample_300_statements.json create mode 100644 tests/fixtures/0.4/statistic_count_declaration_subjects.json create mode 100644 tests/fixtures/0.4/valid-schema/entity.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_2.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_address_address.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_address_country.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_address_country_2.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_address_country_no_code.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_address_postcode.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_address_type.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_addresses_type.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_alternate_names.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_dissolution_date.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_formed_by_statute.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_formed_by_statute_date.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_formed_by_statute_name.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_founding_date.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_government_body.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_identifiers_id.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_identifiers_scheme.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_identifiers_scheme_name.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_identifiers_uri.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_jurisdiction_code.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_jurisdiction_name.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_name.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_nomination.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_public_listing.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_public_listing_company_filings.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_security_MIC.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_security_OMIC.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_security_id.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_security_idscheme.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_security_listing.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_statementDate.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_statementDate_time.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_trust_legal_entity.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_type_details.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_type_registered_entity_subtype.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_type_statebody_other.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_type_trust_arrangement.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_unspecified_entity_description.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_unspecified_entity_details.json create mode 100644 tests/fixtures/0.4/valid-schema/entity_uri.json create mode 100644 tests/fixtures/0.4/valid-schema/person.json create mode 100644 tests/fixtures/0.4/valid-schema/person_2.json create mode 100644 tests/fixtures/0.4/valid-schema/person_PepStatusDetails_endDate.json create mode 100644 tests/fixtures/0.4/valid-schema/person_PepStatusDetails_jurisdiction.json create mode 100644 tests/fixtures/0.4/valid-schema/person_PepStatusDetails_missingInfoReason.json create mode 100644 tests/fixtures/0.4/valid-schema/person_PepStatusDetails_reason.json create mode 100644 tests/fixtures/0.4/valid-schema/person_PepStatusDetails_source.json create mode 100644 tests/fixtures/0.4/valid-schema/person_PepStatusDetails_startDate.json create mode 100644 tests/fixtures/0.4/valid-schema/person_addresses_type.json create mode 100644 tests/fixtures/0.4/valid-schema/person_birth_date.json create mode 100644 tests/fixtures/0.4/valid-schema/person_birth_date_year.json create mode 100644 tests/fixtures/0.4/valid-schema/person_birth_date_year_month.json create mode 100644 tests/fixtures/0.4/valid-schema/person_birth_place.json create mode 100644 tests/fixtures/0.4/valid-schema/person_death_date_full.json create mode 100644 tests/fixtures/0.4/valid-schema/person_death_date_year.json create mode 100644 tests/fixtures/0.4/valid-schema/person_death_date_year_month.json create mode 100644 tests/fixtures/0.4/valid-schema/person_identifiers_id.json create mode 100644 tests/fixtures/0.4/valid-schema/person_identifiers_scheme.json create mode 100644 tests/fixtures/0.4/valid-schema/person_identifiers_scheme_name.json create mode 100644 tests/fixtures/0.4/valid-schema/person_names_family_name.json create mode 100644 tests/fixtures/0.4/valid-schema/person_names_full_name.json create mode 100644 tests/fixtures/0.4/valid-schema/person_names_given_name.json create mode 100644 tests/fixtures/0.4/valid-schema/person_names_patronymic.json create mode 100644 tests/fixtures/0.4/valid-schema/person_names_type.json create mode 100644 tests/fixtures/0.4/valid-schema/person_nationalities_code.json create mode 100644 tests/fixtures/0.4/valid-schema/person_nationalities_name.json create mode 100644 tests/fixtures/0.4/valid-schema/person_politicalExposure_object.json create mode 100644 tests/fixtures/0.4/valid-schema/person_taxResidencies.json create mode 100644 tests/fixtures/0.4/valid-schema/person_unspecified_person_details.json create mode 100644 tests/fixtures/0.4/valid-schema/publication_details_date.json create mode 100644 tests/fixtures/0.4/valid-schema/publication_details_license.json create mode 100644 tests/fixtures/0.4/valid-schema/publication_details_publisher_name.json create mode 100644 tests/fixtures/0.4/valid-schema/publication_details_publisher_name_url.json create mode 100644 tests/fixtures/0.4/valid-schema/publication_details_publisher_url.json create mode 100644 tests/fixtures/0.4/valid-schema/publication_details_version.json create mode 100644 tests/fixtures/0.4/valid-schema/record_status.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_2.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_component_records.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interested_party.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interested_party_unspecified_object.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interests_beneficial_ownership_or_control.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interests_details.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interests_direct_or_indirect.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interests_end_date.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interests_share.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interests_share_exclusive_minmax.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interests_start_date.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_interests_type.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_is_component_true.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_is_component_true2.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_subject.json create mode 100644 tests/fixtures/0.4/valid-schema/relationship_subject_unspecified_object.json create mode 100644 tests/fixtures/0.4/valid-schema/source.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_createdBy.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_createdBy_uri.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_creationDate.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_creationDate_time.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_description.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_empty_transformed.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_statementPointerTarget.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_transformedContent.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_url.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_annotations_url_linking.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_source_assertedBy_uri.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_source_description.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_source_retrievedAt.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_source_retrievedAt_time.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_source_type.json create mode 100644 tests/fixtures/0.4/valid-schema/statement_source_url.json create mode 100644 tests/test_additional_checks_0_4_0.py create mode 100644 tests/test_additional_fields_0_4_0.py create mode 100644 tests/test_api_0_4.py create mode 100644 tests/test_sample_mode.py create mode 100644 tests/test_schema_validation_0_4.py create mode 100644 tests/test_stat_count_declaration_subjects.py create mode 100644 tests/test_stat_count_entity_statements.py create mode 100644 tests/test_stat_count_ownership_or_control_statement.py create mode 100644 tests/test_stat_count_person_statements.py create mode 100644 tests/test_stat_counts_0_4.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c7043e3..5307915 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Changed + +- Update to handle new jsonschema version (Draft202012Validator) +- Adapt infrastructure to handle BODS 0.4 (structure, statement types etc.) + +### Added + +- Include the BODS 0.4 schema +- Include BODS 0.4 specific additional checks +- Include BODS 0.4 specific statistics +- Add tests for BODS 0.4 schema validation +- Add tests for BODS 0.4 specific additional checks + ## [0.15.0] - 2023-06-16 This Release marks a very big refactoring to use with new cove and new libcove2 library. diff --git a/MANIFEST.in b/MANIFEST.in index ac63333..b45dac7 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,3 @@ include libcovebods/data/*.json +include libcovebods/data/schema-0-4-0/*.json +include libcovebods/data/schema-0-4-0/codelists/*.csv diff --git a/libcovebods/base_task.py b/libcovebods/base_task.py index 55af36d..a91bb7e 100644 --- a/libcovebods/base_task.py +++ b/libcovebods/base_task.py @@ -35,6 +35,9 @@ def check_person_statement_first_pass(self, statement): def check_ownership_or_control_statement_first_pass(self, statement): pass + def check_statement_second_pass(self, statement): + pass + def check_entity_statement_second_pass(self, statement): pass diff --git a/libcovebods/config.py b/libcovebods/config.py index 4cbcf23..482274c 100644 --- a/libcovebods/config.py +++ b/libcovebods/config.py @@ -18,10 +18,16 @@ "schema_url": os.path.join(_schema_folder, "schema-0-3-0.json"), "schema_url_host": _schema_folder, }, + "0.4": { + "schema_url": os.path.join(_schema_folder, "schema-0-4-0"), + "schema_url_host": _schema_folder, + }, }, # In some cases we default to the latest schema version, so we need to know what the latest version is. # It should be a key that is in the 'schema_versions' data. - "schema_latest_version": "0.3", + "schema_latest_version": "0.4", + # Or latest version before change to records (in 0.4) + "schema_latest_nonrecord_version": "0.3", # These default values are very wide on purpose. It is left to apps using this to tighten them up. "bods_additional_checks_person_birthdate_min_year": 1, "bods_additional_checks_person_birthdate_max_year": datetime.datetime.now().year, diff --git a/libcovebods/data/schema-0-4-0.json b/libcovebods/data/schema-0-4-0.json new file mode 100644 index 0000000..98a88a9 --- /dev/null +++ b/libcovebods/data/schema-0-4-0.json @@ -0,0 +1,4219 @@ +{ + "$id": "urn:statement", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Statements", + "description": "An array of Statements.", + "version": "0.4", + "type": "array", + "items": { + "title": "Statement", + "description": "A claim about a person, entity or relationship, made at a particular point in time.", + "type": "object", + "properties": { + "statementId": { + "title": "Statement Identifier", + "description": "A persistent globally unique identifier for this Statement. Length MUST be 32 - 64 characters (inclusive).", + "type": "string", + "minLength": 32, + "maxLength": 64 + }, + "statementDate": { + "title": "Statement Date", + "description": "The date on which this statement was declared by the source, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "annotations": { + "title": "Annotations", + "description": "Annotations about this Statement or parts of this Statement", + "type": "array", + "items": { + "title": "Annotation", + "description": "Additional information about the data contained in this Statement. Annotations can apply to a whole statement, an object or a single field. Custom properties can be included within the Annotation object to provide structured data where required.", + "type": "object", + "properties": { + "statementPointerTarget": { + "title": "Statement Fragment Pointer", + "description": "An RFC6901 JSON Pointer (https://tools.ietf.org/html/rfc6901) describing the target fragment of the statement that this Annotation applies to, starting from the root of the Statement. An empty string (\"\") indicates that the Annotation applies to the whole Statement.", + "type": "string" + }, + "creationDate": { + "title": "Creation Date", + "description": "The date on which this Annotation was created, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "createdBy": { + "title": "Created By", + "description": "The person, organisation or agent that created this Annotation.", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the person, organisation or agent that created this Annotation.", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the person, organisation or agent that created this Annotation.", + "type": "string", + "format": "uri" + } + } + }, + "motivation": { + "title": "Motivation", + "description": "The reason for this Annotation, using the annotationMotivation codelist.", + "type": "string", + "enum": [ + "commenting", + "correcting", + "identifying", + "linking", + "transformation" + ], + "codelist": "annotationMotivation.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "A free text description providing extra information about part of this Statement.", + "type": "string" + }, + "transformedContent": { + "type": "string", + "title": "Transformed Content", + "description": "A representation of the Annotation target after the transformation in the `description` field has been applied. This field MUST only be used when the `motivation` is 'transformation'." + }, + "url": { + "title": "URL", + "description": "A linked resource that annotates, provides context for or enhances this Statement. The content of the resource, or the relationship to the statement, MAY be described in the `description` field. This field is REQUIRED if the value of `motivation` is 'linking'.", + "type": "string", + "format": "uri" + } + }, + "allOf": [ + { + "if": { + "properties": { + "motivation": { + "const": "linking" + } + } + }, + "then": { + "required": [ + "statementPointerTarget", + "motivation", + "url" + ] + }, + "else": { + "required": [ + "statementPointerTarget", + "motivation" + ] + } + }, + { + "if": { + "not": { + "properties": { + "motivation": { + "const": "transformation" + } + } + } + }, + "then": { + "properties": { + "transformedContent": { + "const": "" + } + } + } + } + ] + } + }, + "publicationDetails": { + "title": "Publication Details", + "description": "Information concerning the publication of this Statement.", + "type": "object", + "properties": { + "publicationDate": { + "title": "Publication date", + "description": "The date on which this statement was published, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "bodsVersion": { + "title": "BODS Version", + "description": "The version of the Beneficial Ownership Data Standard to which this Statement conforms, expressed as major.minor (e.g. 0.2 or 1.0). In a published BODS dataset, all Statements MUST have the same major version number.", + "type": "string", + "pattern": "^(\\d+\\.)(\\d+)$" + }, + "license": { + "title": "License URL", + "description": "A link to the license that applies to this Statement. The canonical URI of the license SHOULD be used. Publishers are encouraged to use a Public Domain Dedication or Open Definition Conformant (http://opendefinition.org/licenses/) license.", + "type": "string", + "format": "uri" + }, + "publisher": { + "type": "object", + "title": "Publisher", + "description": "Details of the organisation or person publishing a Statement.", + "properties": { + "name": { + "title": "Name", + "description": "The name of the publisher.", + "type": "string" + }, + "url": { + "title": "URL", + "description": "The URL where details of the full dataset, or of the publisher, can be found.", + "type": "string", + "format": "uri" + } + }, + "anyOf": [ + { + "required": [ + "name" + ] + }, + { + "required": [ + "url" + ] + } + ] + } + }, + "required": [ + "publicationDate", + "bodsVersion", + "publisher" + ] + }, + "source": { + "title": "Source", + "description": "The source of information in this statement. Each statement SHOULD contain source information.", + "type": "object", + "properties": { + "type": { + "title": "Source Type", + "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "selfDeclaration", + "officialRegister", + "thirdParty", + "primaryResearch", + "verified" + ], + "codelist": "sourceType.csv", + "openCodelist": false + } + }, + "description": { + "title": "Description", + "description": "Additional, free text information about the source of information.", + "type": "string" + }, + "url": { + "title": "Source URL", + "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", + "type": "string", + "format": "uri" + }, + "retrievedAt": { + "title": "Retrieved At", + "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "assertedBy": { + "title": "Asserted By", + "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the agent making the assertion", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the agent making the assertion", + "type": "string", + "format": "uri" + } + } + } + } + } + }, + "declaration": { + "title": "Declaration Reference", + "description": "An identifier or reference for a declaration within the publisher\u2019s system. Where a Statement is a claim from a particular declaration (made at a point in time by a `source` about a `declarationSubject`) this field identifies the declaration.", + "type": "string" + }, + "declarationSubject": { + "title": "Declaration Subject", + "description": "A `recordId` value for the subject of a beneficial ownership network (always an entity or person).", + "type": "string" + }, + "recordId": { + "title": "Record Identifier", + "description": "A unique identifier for the record (within the publisher's system) to which this Statement relates. (A record captures information about an entity, natural person or relationship within the beneficial ownership network of a particular declaration subject.)", + "type": "string" + }, + "recordType": { + "title": "Record Type", + "description": "The type of record (within the publisher's system) to which this Statement relates: entity, person, or relationship.", + "type": "string", + "enum": [ + "person", + "entity", + "relationship" + ], + "codelist": "recordType.csv", + "openCodelist": false + }, + "recordStatus": { + "title": "Record Status", + "description": "The lifecycle status of the record (within the publisher's system) to which this Statement relates, using the recordStatus codelist.", + "type": "string", + "enum": [ + "new", + "updated", + "closed" + ], + "codelist": "recordStatus.csv", + "openCodelist": false + }, + "recordDetails": { + "title": "Record Details", + "description": "The details of the entity, person or relationship as declared on the Statement Date.", + "type": "object" + } + }, + "allOf": [ + { + "if": { + "properties": { + "recordType": { + "const": "entity" + } + } + }, + "then": { + "properties": { + "recordDetails": { + "$id": "urn:entity", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": "0.4", + "title": "Entity Record Details", + "description": "Information about an entity.", + "type": "object", + "properties": { + "isComponent": { + "title": "Is component", + "description": "Whether this entity is a component in an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this entity MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Entity Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Entity Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship statement MUST have a `isComponent` value of 'false'.", + "type": "boolean" + }, + "entityType": { + "type": "object", + "title": "Entity Type", + "description": "The form of the entity described in the Statement.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "title": "Type", + "description": "The general form of the entity, using the entityType codelist.", + "codelist": "entityType.csv", + "enum": [ + "registeredEntity", + "legalEntity", + "arrangement", + "anonymousEntity", + "unknownEntity", + "state", + "stateBody" + ] + }, + "subtype": { + "type": "string", + "title": "Subtype", + "description": "The particular form of the entity, where relevant, using the entitySubtype codelist. The value MUST align with the `entityType` value.", + "codelist": "entitySubtype.csv", + "enum": [ + "governmentDepartment", + "stateAgency", + "other", + "trust", + "nomination" + ], + "openCodelist": false + }, + "details": { + "type": "string", + "title": "Details", + "description": "This may be used to provide a local name for this type of entity, or any further information to identify the type of entity. For example, in Finland 'ministeri\u00f6' for a government department." + } + }, + "propertyOrder": 4, + "allOf": [ + { + "if": { + "properties": { + "type": { + "enum": [ + "arrangement" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "trust", + "nomination", + "other" + ] + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "legalEntity" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "trust", + "other" + ] + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "stateBody" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "governmentDepartment", + "stateAgency", + "other" + ] + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "registeredEntity", + "state", + "anonymousEntity", + "unknownEntity" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "other" + ] + } + } + } + } + ] + }, + "unspecifiedEntityDetails": { + "title": "Unspecified or unknown person or entity", + "description": "A `reason` MUST be supplied.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", + "type": "string", + "enum": [ + "noBeneficialOwners", + "subjectUnableToConfirmOrIdentifyBeneficialOwner", + "interestedPartyHasNotProvidedInformation", + "subjectExemptFromDisclosure", + "interestedPartyExemptFromDisclosure", + "unknown", + "informationUnknownToPublisher" + ], + "codelist": "unspecifiedReason.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", + "type": "string" + } + }, + "required": [ + "reason" + ] + }, + "name": { + "title": "Entity Name", + "description": "The declared name of this entity.", + "type": "string", + "propertyOrder": 10 + }, + "alternateNames": { + "title": "Alternative Names", + "description": "An array of other names this entity is known by.", + "type": "array", + "items": { + "type": "string", + "title": "Name", + "description": "A name this entity is known by." + }, + "propertyOrder": 12 + }, + "jurisdiction": { + "title": "Jurisdiction", + "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the jurisdiction", + "type": "string" + }, + "code": { + "title": "Country or Subdivision Code", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", + "type": "string", + "maxLength": 6, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "identifiers": { + "title": "Identifiers", + "description": "One or more official identifiers for this entity. Where available, official registration numbers should be provided.", + "type": "array", + "items": { + "title": "Identifier", + "description": "An identifier that has been assigned to a person or entity. `scheme` or `schemeName` (or both) MUST be included in an Identifier object.", + "type": "object", + "properties": { + "id": { + "title": "ID", + "description": "The identifier for a person or entity, as issued by the scheme.", + "type": "string" + }, + "scheme": { + "title": "Scheme Code", + "description": "For entities, a code from org-id.guide (https://www.org-id.guide) for an identifier-issuing authority (e.g. 'GB-COH'). For natural persons, a value with the pattern {JURISDICTION}-{TYPE} where JURISDICTION is an ISO 3166-1 3-digit country code and TYPE is one of PASSPORT, TAXID or IDCARD.", + "type": "string" + }, + "schemeName": { + "title": "Scheme Name", + "description": "The name of the identifier-issuing authority.", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "A canonical URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) for the identifier and associated details of the person or entity, if one exists.", + "type": "string", + "format": "uri" + } + }, + "anyOf": [ + { + "required": [ + "scheme" + ] + }, + { + "required": [ + "schemeName" + ] + }, + { + "required": [ + "scheme", + "schemeName" + ] + } + ] + }, + "propertyOrder": 20 + }, + "foundingDate": { + "title": "Founding Date", + "description": "The date on which this entity was founded, created or registered. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date", + "propertyOrder": 30 + }, + "dissolutionDate": { + "title": "Dissolution Date", + "description": "The date on which this entity was dissolved or ceased, if it is no longer active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date", + "propertyOrder": 35 + }, + "addresses": { + "title": "Addresses", + "description": "One or more addresses for this entity.", + "type": "array", + "items": { + "title": "Address", + "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", + "type": "object", + "properties": { + "type": { + "title": "Type", + "description": "The function of the address, using the addressType codelist.", + "type": "string", + "enum": [ + "placeOfBirth", + "residence", + "registered", + "service", + "alternative", + "business" + ], + "codelist": "addressType.csv", + "openCodelist": false + }, + "address": { + "title": "Address", + "description": "The address, with each line or component separated by a line-break or comma.", + "type": "string" + }, + "postCode": { + "title": "Postcode", + "description": "The postal code for this address.", + "type": "string" + }, + "country": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + } + } + }, + "propertyOrder": 40 + }, + "uri": { + "title": "URI", + "description": "Where a persistent URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) is available for this entity this should be included.", + "type": "string", + "format": "uri", + "propertyOrder": 21 + }, + "publicListing": { + "type": "object", + "title": "Public Listing", + "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", + "required": [ + "hasPublicListing" + ], + "minProperties": 1, + "properties": { + "hasPublicListing": { + "type": "boolean", + "title": "Has Public Listing", + "description": "Whether the entity is a publicly listed company." + }, + "companyFilingsURLs": { + "type": "array", + "title": "Company Filings URLs", + "description": "URL or URLs where regulatory filings related to major holdings can be retrieved. URLs may point to pages maintained by regulatory bodies, stock exchanges or by the company itself.", + "items": { + "type": "string", + "format": "uri" + } + }, + "securitiesListings": { + "type": "array", + "title": "Securities Listings", + "description": "Details of the entity's securities and the public exchanges and markets on which they are traded. All equity securities SHOULD be listed here, plus any other securities from which beneficial ownership might be derived. Where a security is traded on more than one market, there SHOULD be an entry for each market (or market segment).", + "items": { + "type": "object", + "title": "Securities Listing", + "description": "Details of a security and the market on which it is traded.", + "required": [ + "stockExchangeJurisdiction", + "security", + "stockExchangeName" + ], + "properties": { + "marketIdentifierCode": { + "type": "string", + "title": "Market Identifier Code (MIC)", + "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "operatingMarketIdentifierCode": { + "type": "string", + "title": "Operating Market Identifier Code (Operating MIC)", + "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "stockExchangeJurisdiction": { + "type": "string", + "title": "Stock Exchange Jurisdiction", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", + "maxLength": 6, + "minLength": 2 + }, + "stockExchangeName": { + "type": "string", + "title": "Stock Exchange Name", + "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." + }, + "security": { + "type": "object", + "title": "Security", + "description": "Identifying information of the stock or other security.", + "required": [ + "ticker" + ], + "properties": { + "idScheme": { + "type": "string", + "title": "Identifier Scheme", + "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", + "enum": [ + "isin", + "figi", + "cusip", + "cins" + ], + "codelist": "securitiesIdentifierSchemes.csv" + }, + "id": { + "type": "string", + "title": "Identifier", + "description": "The unique identifier of the security as issued under the `idScheme`." + }, + "ticker": { + "type": "string", + "title": "Stock Ticker", + "description": "The stock ticker identifying this security on the named stock exchange." + } + } + } + } + } + } + } + }, + "formedByStatute": { + "type": "object", + "title": "Formed by Statute", + "description": "The law which mandated the formation of the entity described in the statement, where applicable. This information SHOULD be provided where a state has created an agency or other entity with specific legislation.", + "properties": { + "name": { + "type": "string", + "title": "Statute Name", + "description": "The name of the law. " + }, + "date": { + "type": "string", + "title": "Date", + "description": "The date on which the law came into force. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "format": "date" + } + }, + "propertyOrder": 18 + } + }, + "required": [ + "isComponent", + "entityType" + ], + "$defs": { + "PublicListing": { + "type": "object", + "title": "Public Listing", + "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", + "required": [ + "hasPublicListing" + ], + "minProperties": 1, + "properties": { + "hasPublicListing": { + "type": "boolean", + "title": "Has Public Listing", + "description": "Whether the entity is a publicly listed company." + }, + "companyFilingsURLs": { + "type": "array", + "title": "Company Filings URLs", + "description": "URL or URLs where regulatory filings related to major holdings can be retrieved. URLs may point to pages maintained by regulatory bodies, stock exchanges or by the company itself.", + "items": { + "type": "string", + "format": "uri" + } + }, + "securitiesListings": { + "type": "array", + "title": "Securities Listings", + "description": "Details of the entity's securities and the public exchanges and markets on which they are traded. All equity securities SHOULD be listed here, plus any other securities from which beneficial ownership might be derived. Where a security is traded on more than one market, there SHOULD be an entry for each market (or market segment).", + "items": { + "type": "object", + "title": "Securities Listing", + "description": "Details of a security and the market on which it is traded.", + "required": [ + "stockExchangeJurisdiction", + "security", + "stockExchangeName" + ], + "properties": { + "marketIdentifierCode": { + "type": "string", + "title": "Market Identifier Code (MIC)", + "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "operatingMarketIdentifierCode": { + "type": "string", + "title": "Operating Market Identifier Code (Operating MIC)", + "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "stockExchangeJurisdiction": { + "type": "string", + "title": "Stock Exchange Jurisdiction", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", + "maxLength": 6, + "minLength": 2 + }, + "stockExchangeName": { + "type": "string", + "title": "Stock Exchange Name", + "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." + }, + "security": { + "type": "object", + "title": "Security", + "description": "Identifying information of the stock or other security.", + "required": [ + "ticker" + ], + "properties": { + "idScheme": { + "type": "string", + "title": "Identifier Scheme", + "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", + "enum": [ + "isin", + "figi", + "cusip", + "cins" + ], + "codelist": "securitiesIdentifierSchemes.csv" + }, + "id": { + "type": "string", + "title": "Identifier", + "description": "The unique identifier of the security as issued under the `idScheme`." + }, + "ticker": { + "type": "string", + "title": "Stock Ticker", + "description": "The stock ticker identifying this security on the named stock exchange." + } + } + } + } + } + } + } + }, + "SecuritiesListing": { + "type": "object", + "title": "Securities Listing", + "description": "Details of a security and the market on which it is traded.", + "required": [ + "stockExchangeJurisdiction", + "security", + "stockExchangeName" + ], + "properties": { + "marketIdentifierCode": { + "type": "string", + "title": "Market Identifier Code (MIC)", + "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "operatingMarketIdentifierCode": { + "type": "string", + "title": "Operating Market Identifier Code (Operating MIC)", + "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "stockExchangeJurisdiction": { + "type": "string", + "title": "Stock Exchange Jurisdiction", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", + "maxLength": 6, + "minLength": 2 + }, + "stockExchangeName": { + "type": "string", + "title": "Stock Exchange Name", + "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." + }, + "security": { + "type": "object", + "title": "Security", + "description": "Identifying information of the stock or other security.", + "required": [ + "ticker" + ], + "properties": { + "idScheme": { + "type": "string", + "title": "Identifier Scheme", + "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", + "enum": [ + "isin", + "figi", + "cusip", + "cins" + ], + "codelist": "securitiesIdentifierSchemes.csv" + }, + "id": { + "type": "string", + "title": "Identifier", + "description": "The unique identifier of the security as issued under the `idScheme`." + }, + "ticker": { + "type": "string", + "title": "Stock Ticker", + "description": "The stock ticker identifying this security on the named stock exchange." + } + } + } + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "recordType": { + "const": "person" + } + } + }, + "then": { + "properties": { + "recordDetails": { + "$id": "urn:person", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": "0.4", + "type": "object", + "title": "Person Record Details", + "description": "Information about a natural person.", + "properties": { + "isComponent": { + "title": "Is component", + "description": "Whether this person is a component of an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this person MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Person Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Person Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship Statement MUST have a `isComponent` value of 'false'.", + "type": "boolean" + }, + "personType": { + "title": "Person Type", + "description": "The status of this person, using the personType codelist. Where a person has the type 'anonymousPerson' or 'unknownPerson' a reason for the absence of information SHOULD be provided in 'unspecifiedPersonDetails'", + "type": "string", + "enum": [ + "anonymousPerson", + "unknownPerson", + "knownPerson" + ], + "propertyOrder": 4, + "codelist": "personType.csv", + "openCodelist": false + }, + "unspecifiedPersonDetails": { + "title": "Unspecified or unknown person or entity", + "description": "A `reason` MUST be supplied.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", + "type": "string", + "enum": [ + "noBeneficialOwners", + "subjectUnableToConfirmOrIdentifyBeneficialOwner", + "interestedPartyHasNotProvidedInformation", + "subjectExemptFromDisclosure", + "interestedPartyExemptFromDisclosure", + "unknown", + "informationUnknownToPublisher" + ], + "codelist": "unspecifiedReason.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", + "type": "string" + } + }, + "required": [ + "reason" + ] + }, + "names": { + "title": "Names", + "description": "One or more known names for this person.", + "type": "array", + "items": { + "title": "Name", + "description": "A name by which this person is known. A name MUST be provided in `fullName`, and MAY be broken down in the `familyName`, `givenName` and `patronymicName` fields, based on the EC ISA Core Person Vocabulary (https://joinup.ec.europa.eu/solution/e-government-core-vocabularies) definitions.", + "type": "object", + "required": [ + "fullName" + ], + "properties": { + "type": { + "title": "Type", + "description": "The status of this name for the person, using the nameType codelist.", + "type": "string", + "enum": [ + "legal", + "translation", + "transliteration", + "former", + "alternative", + "birth" + ], + "codelist": "nameType.csv", + "openCodelist": false + }, + "fullName": { + "title": "Full Name", + "description": "The complete name of the person.", + "type": "string" + }, + "familyName": { + "title": "Family Name", + "description": "Part of the person's `fullName` which is shared by family members. The value may include prefixes or suffixes, e.g. 'de Boer', 'van de Putte', 'von und zu Orlow'. The value may be a multiple-part family name, such as are commonly found in Hispanic countries. For example, Miguel de Cervantes Saavedra's Family Name would be recorded as 'de Cervantes Saavedra.'", + "type": "string" + }, + "givenName": { + "title": "Given Names", + "description": "The part of the person's `fullName` that identifies the person within their family. These are given to a person by their parents at birth or may be legally recognised as 'given names' through a formal process. For example, the given name for Johann Sebastian Bach is 'Johann Sebastian'.", + "type": "string" + }, + "patronymicName": { + "title": "Patronymic Name", + "description": "Part of the person's `fullName` which is inherited from their father, as is common in countries such as Iceland, Ethiopia and Russia. For example, the 'Sergeyevich' in 'Mikhail Sergeyevich Gorbachev'.", + "type": "string" + } + } + }, + "propertyOrder": 10 + }, + "identifiers": { + "title": "Identifiers", + "description": "One or more official identifiers for this person. Where available, official registration numbers should be provided.", + "type": "array", + "items": { + "title": "Identifier", + "description": "An identifier that has been assigned to a person or entity. `scheme` or `schemeName` (or both) MUST be included in an Identifier object.", + "type": "object", + "properties": { + "id": { + "title": "ID", + "description": "The identifier for a person or entity, as issued by the scheme.", + "type": "string" + }, + "scheme": { + "title": "Scheme Code", + "description": "For entities, a code from org-id.guide (https://www.org-id.guide) for an identifier-issuing authority (e.g. 'GB-COH'). For natural persons, a value with the pattern {JURISDICTION}-{TYPE} where JURISDICTION is an ISO 3166-1 3-digit country code and TYPE is one of PASSPORT, TAXID or IDCARD.", + "type": "string" + }, + "schemeName": { + "title": "Scheme Name", + "description": "The name of the identifier-issuing authority.", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "A canonical URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) for the identifier and associated details of the person or entity, if one exists.", + "type": "string", + "format": "uri" + } + }, + "anyOf": [ + { + "required": [ + "scheme" + ] + }, + { + "required": [ + "schemeName" + ] + }, + { + "required": [ + "scheme", + "schemeName" + ] + } + ] + }, + "propertyOrder": 20 + }, + "nationalities": { + "title": "Nationality", + "description": "The nationalities held by this person.", + "type": "array", + "items": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "propertyOrder": 30 + }, + "placeOfBirth": { + "title": "Address", + "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", + "type": "object", + "properties": { + "type": { + "title": "Type", + "description": "The function of the address, using the addressType codelist.", + "type": "string", + "enum": [ + "placeOfBirth", + "residence", + "registered", + "service", + "alternative", + "business" + ], + "codelist": "addressType.csv", + "openCodelist": false + }, + "address": { + "title": "Address", + "description": "The address, with each line or component separated by a line-break or comma.", + "type": "string" + }, + "postCode": { + "title": "Postcode", + "description": "The postal code for this address.", + "type": "string" + }, + "country": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + } + } + }, + "birthDate": { + "title": "Date of Birth", + "description": "The date of birth for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", + "type": "string", + "anyOf": [ + { + "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" + }, + { + "format": "date" + } + ], + "propertyOrder": 35 + }, + "deathDate": { + "title": "Death Date", + "description": "The date of death for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", + "type": "string", + "anyOf": [ + { + "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" + }, + { + "format": "date" + } + ], + "propertyOrder": 36 + }, + "taxResidencies": { + "title": "Tax Residency", + "description": "The tax residencies held by this person, as an array of Country objects.", + "type": "array", + "items": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "propertyOrder": 55 + }, + "addresses": { + "title": "Addresses", + "description": "One or more addresses for this person.", + "type": "array", + "items": { + "title": "Address", + "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", + "type": "object", + "properties": { + "type": { + "title": "Type", + "description": "The function of the address, using the addressType codelist.", + "type": "string", + "enum": [ + "placeOfBirth", + "residence", + "registered", + "service", + "alternative", + "business" + ], + "codelist": "addressType.csv", + "openCodelist": false + }, + "address": { + "title": "Address", + "description": "The address, with each line or component separated by a line-break or comma.", + "type": "string" + }, + "postCode": { + "title": "Postcode", + "description": "The postal code for this address.", + "type": "string" + }, + "country": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + } + } + }, + "propertyOrder": 60 + }, + "politicalExposure": { + "type": "object", + "title": "Political Exposure", + "description": "Information about whether, and how, the person described by this statement is politically exposed. Use this property only if politically exposed person (PEP) declarations are expected as part of beneficial ownership declarations.", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "title": "Politically Exposed Person (PEP) Status", + "description": "This value is 'isPep' or 'isNotPep' according to whether the person described by this statement has the status of politically exposed person (PEP). An 'unknown' value means a PEP status declaration is expected but missing; the reason for the missing data SHOULD be supplied in the `details` array.", + "enum": [ + "isPep", + "isNotPep", + "unknown" + ] + }, + "details": { + "type": "array", + "title": "Politically Exposed Person (PEP) Details", + "description": "One or more descriptions of this person's Politically Exposed Person (PEP) status.", + "items": { + "title": "PEP Status Details", + "description": "Information about a person's political involvement.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason for this person being declared a politically-exposed person.", + "type": "string" + }, + "missingInfoReason": { + "title": "Missing Information Reasons", + "description": "An explanation of why the PEP status for the person is not provided (i.e. `politicalExposure.status` is 'unknown'). This may be a standard descriptive phrase from the source system, or a free text justification. Where this field is present it should be the only field except for `source`.", + "type": "string" + }, + "jurisdiction": { + "title": "Jurisdiction", + "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the jurisdiction", + "type": "string" + }, + "code": { + "title": "Country or Subdivision Code", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", + "type": "string", + "maxLength": 6, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "startDate": { + "title": "State Date", + "description": "The date from which this person had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this person no longer had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "source": { + "title": "Source", + "description": "Details describing an information source.", + "type": "object", + "properties": { + "type": { + "title": "Source Type", + "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "selfDeclaration", + "officialRegister", + "thirdParty", + "primaryResearch", + "verified" + ], + "codelist": "sourceType.csv", + "openCodelist": false + } + }, + "description": { + "title": "Description", + "description": "Additional, free text information about the source of information.", + "type": "string" + }, + "url": { + "title": "Source URL", + "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", + "type": "string", + "format": "uri" + }, + "retrievedAt": { + "title": "Retrieved At", + "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "assertedBy": { + "title": "Asserted By", + "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the agent making the assertion", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the agent making the assertion", + "type": "string", + "format": "uri" + } + } + } + } + } + } + } + } + } + } + } + }, + "required": [ + "personType", + "isComponent" + ], + "$defs": { + "Name": { + "title": "Name", + "description": "A name by which this person is known. A name MUST be provided in `fullName`, and MAY be broken down in the `familyName`, `givenName` and `patronymicName` fields, based on the EC ISA Core Person Vocabulary (https://joinup.ec.europa.eu/solution/e-government-core-vocabularies) definitions.", + "type": "object", + "required": [ + "fullName" + ], + "properties": { + "type": { + "title": "Type", + "description": "The status of this name for the person, using the nameType codelist.", + "type": "string", + "enum": [ + "legal", + "translation", + "transliteration", + "former", + "alternative", + "birth" + ], + "codelist": "nameType.csv", + "openCodelist": false + }, + "fullName": { + "title": "Full Name", + "description": "The complete name of the person.", + "type": "string" + }, + "familyName": { + "title": "Family Name", + "description": "Part of the person's `fullName` which is shared by family members. The value may include prefixes or suffixes, e.g. 'de Boer', 'van de Putte', 'von und zu Orlow'. The value may be a multiple-part family name, such as are commonly found in Hispanic countries. For example, Miguel de Cervantes Saavedra's Family Name would be recorded as 'de Cervantes Saavedra.'", + "type": "string" + }, + "givenName": { + "title": "Given Names", + "description": "The part of the person's `fullName` that identifies the person within their family. These are given to a person by their parents at birth or may be legally recognised as 'given names' through a formal process. For example, the given name for Johann Sebastian Bach is 'Johann Sebastian'.", + "type": "string" + }, + "patronymicName": { + "title": "Patronymic Name", + "description": "Part of the person's `fullName` which is inherited from their father, as is common in countries such as Iceland, Ethiopia and Russia. For example, the 'Sergeyevich' in 'Mikhail Sergeyevich Gorbachev'.", + "type": "string" + } + } + }, + "PepStatusDetails": { + "title": "PEP Status Details", + "description": "Information about a person's political involvement.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason for this person being declared a politically-exposed person.", + "type": "string" + }, + "missingInfoReason": { + "title": "Missing Information Reasons", + "description": "An explanation of why the PEP status for the person is not provided (i.e. `politicalExposure.status` is 'unknown'). This may be a standard descriptive phrase from the source system, or a free text justification. Where this field is present it should be the only field except for `source`.", + "type": "string" + }, + "jurisdiction": { + "title": "Jurisdiction", + "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the jurisdiction", + "type": "string" + }, + "code": { + "title": "Country or Subdivision Code", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", + "type": "string", + "maxLength": 6, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "startDate": { + "title": "State Date", + "description": "The date from which this person had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this person no longer had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "source": { + "title": "Source", + "description": "Details describing an information source.", + "type": "object", + "properties": { + "type": { + "title": "Source Type", + "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "selfDeclaration", + "officialRegister", + "thirdParty", + "primaryResearch", + "verified" + ], + "codelist": "sourceType.csv", + "openCodelist": false + } + }, + "description": { + "title": "Description", + "description": "Additional, free text information about the source of information.", + "type": "string" + }, + "url": { + "title": "Source URL", + "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", + "type": "string", + "format": "uri" + }, + "retrievedAt": { + "title": "Retrieved At", + "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "assertedBy": { + "title": "Asserted By", + "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the agent making the assertion", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the agent making the assertion", + "type": "string", + "format": "uri" + } + } + } + } + } + } + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "recordType": { + "const": "relationship" + } + } + }, + "then": { + "properties": { + "recordDetails": { + "$id": "urn:relationship", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": "0.4", + "title": "Relationship Record Details", + "description": "Information about the interests that an interested party (a person or entity) holds in the subject (an entity).", + "type": "object", + "properties": { + "isComponent": { + "title": "Is component", + "description": "Whether this relationship is a component of a wider indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this secondary Relationship Statement MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Relationship Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Relationship Statement SHOULD be considered when replacing the primary Relationship Statement, and (4) the primary Relationship Statement MUST have an `isComponent` value of 'false'. Where `isComponent` is 'false', this Relationship Statement is the primary declaration of the relationship between the `subject` and the `interestedParty`.", + "type": "boolean" + }, + "componentRecords": { + "title": "Component Record IDs", + "description": "The `recordId` values of all component records that provide detail about this relationship between the `subject` and the `interestedParty` (if it is indirect). If this relationship has components, its own `isComponent` value MUST be 'false'.", + "type": "array", + "items": { + "type": "string" + } + }, + "subject": { + "title": "Subject", + "description": "The `recordId` for the subject of the relationship, or a reason why the subject cannot be specified. The subject MUST be an entity.", + "oneOf": [ + { + "type": "string" + }, + { + "title": "Unspecified or unknown person or entity", + "description": "A `reason` MUST be supplied.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", + "type": "string", + "enum": [ + "noBeneficialOwners", + "subjectUnableToConfirmOrIdentifyBeneficialOwner", + "interestedPartyHasNotProvidedInformation", + "subjectExemptFromDisclosure", + "interestedPartyExemptFromDisclosure", + "unknown", + "informationUnknownToPublisher" + ], + "codelist": "unspecifiedReason.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", + "type": "string" + } + }, + "required": [ + "reason" + ] + } + ] + }, + "interestedParty": { + "title": "Interested Party", + "description": "The `recordId` for the interested party in the relationship, or an Unspecified Record object with a reason for why this information has not been disclosed. The interested party MAY be an entity or a person. An Unspecified Record SHOULD only be used where no information at all is known about interested parties beyond this point of the beneficial ownership network. If the interested party is known to be an entity or person but their particular identity is unavailable, a `recordId` for them SHOULD be provided here (and the their `recordDetails.[person|entity]Type` should indicate that they are anonymous or unknown).", + "oneOf": [ + { + "type": "string" + }, + { + "title": "Unspecified or unknown person or entity", + "description": "A `reason` MUST be supplied.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", + "type": "string", + "enum": [ + "noBeneficialOwners", + "subjectUnableToConfirmOrIdentifyBeneficialOwner", + "interestedPartyHasNotProvidedInformation", + "subjectExemptFromDisclosure", + "interestedPartyExemptFromDisclosure", + "unknown", + "informationUnknownToPublisher" + ], + "codelist": "unspecifiedReason.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", + "type": "string" + } + }, + "required": [ + "reason" + ] + } + ] + }, + "interests": { + "title": "Interests", + "description": "A description of the interests held by the interested party in the subject.", + "type": "array", + "items": { + "title": "Interest", + "description": "A description of an interest held by an interestedParty in the subject.", + "type": "object", + "properties": { + "type": { + "title": "Type of Interest", + "description": "The nature of the interest, using the interestType codelist.", + "type": "string", + "enum": [ + "shareholding", + "votingRights", + "appointmentOfBoard", + "otherInfluenceOrControl", + "seniorManagingOfficial", + "settlor", + "trustee", + "protector", + "beneficiaryOfLegalArrangement", + "rightsToSurplusAssetsOnDissolution", + "rightsToProfitOrIncome", + "rightsGrantedByContract", + "conditionalRightsGrantedByContract", + "controlViaCompanyRulesOrArticles", + "controlByLegalFramework", + "boardMember", + "boardChair", + "unknownInterest", + "unpublishedInterest", + "enjoymentAndUseOfAssets", + "rightToProfitOrIncomeFromAssets", + "nominee", + "nominator" + ], + "codelist": "interestType.csv", + "openCodelist": false + }, + "directOrIndirect": { + "title": "Direct or Indirect", + "description": "How directly the interest is exercised by the interested party. The value MUST be 'indirect' if intermediate entities or agents are known to exist, and MUST be 'direct' if such intermediaries are known not to exist. Otherwise the value MUST be 'unknown'.", + "type": "string", + "enum": [ + "direct", + "indirect", + "unknown" + ], + "codelist": "directOrIndirect.csv", + "openCodelist": false + }, + "beneficialOwnershipOrControl": { + "title": "Beneficial Ownership or Control", + "description": "Whether this interest (alone or with others) means the interested party is a beneficial owner of the subject. If 'true' the interested party MUST be a natural person. The definition of 'beneficial owner' in operation SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "boolean" + }, + "details": { + "title": "Details", + "description": "The local name given to this kind of interest, or further information (semi-structured or unstructured) to clarify the nature of the interest.", + "type": "string" + }, + "share": { + "title": "Percentage Share", + "description": "The proportion of this type of interest held by the interested party, where an interest is countable. Provide the `exact` percentage if known. Otherwise, `minimum` (or `exclusiveMinimum`) and `maximum` (or `exclusiveMaximum`) can be used to record the range into which the proportion falls. (The `minimum` and `maximum` values are inclusive.)", + "type": "object", + "properties": { + "exact": { + "title": "Exact percentage", + "description": "The exact share of this interest held (if available).", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "maximum": { + "title": "Maximum Percentage", + "description": "The inclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "minimum": { + "title": "Minimum Percentage", + "description": "The inclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMinimum": { + "title": "Exclusive Minimum percentage", + "description": "The exclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMaximum": { + "title": "Exclusive Maximum Percentage", + "description": "The exclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + } + } + }, + "startDate": { + "title": "Start Date", + "description": "The date from which this interest was active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this interest ceased to exist. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + } + } + } + } + }, + "required": [ + "isComponent", + "subject", + "interestedParty" + ], + "if": { + "properties": { + "isComponent": { + "const": true + } + } + }, + "then": { + "properties": { + "componentRecords": { + "const": [] + } + } + }, + "$defs": { + "Interest": { + "title": "Interest", + "description": "A description of an interest held by an interestedParty in the subject.", + "type": "object", + "properties": { + "type": { + "title": "Type of Interest", + "description": "The nature of the interest, using the interestType codelist.", + "type": "string", + "enum": [ + "shareholding", + "votingRights", + "appointmentOfBoard", + "otherInfluenceOrControl", + "seniorManagingOfficial", + "settlor", + "trustee", + "protector", + "beneficiaryOfLegalArrangement", + "rightsToSurplusAssetsOnDissolution", + "rightsToProfitOrIncome", + "rightsGrantedByContract", + "conditionalRightsGrantedByContract", + "controlViaCompanyRulesOrArticles", + "controlByLegalFramework", + "boardMember", + "boardChair", + "unknownInterest", + "unpublishedInterest", + "enjoymentAndUseOfAssets", + "rightToProfitOrIncomeFromAssets", + "nominee", + "nominator" + ], + "codelist": "interestType.csv", + "openCodelist": false + }, + "directOrIndirect": { + "title": "Direct or Indirect", + "description": "How directly the interest is exercised by the interested party. The value MUST be 'indirect' if intermediate entities or agents are known to exist, and MUST be 'direct' if such intermediaries are known not to exist. Otherwise the value MUST be 'unknown'.", + "type": "string", + "enum": [ + "direct", + "indirect", + "unknown" + ], + "codelist": "directOrIndirect.csv", + "openCodelist": false + }, + "beneficialOwnershipOrControl": { + "title": "Beneficial Ownership or Control", + "description": "Whether this interest (alone or with others) means the interested party is a beneficial owner of the subject. If 'true' the interested party MUST be a natural person. The definition of 'beneficial owner' in operation SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "boolean" + }, + "details": { + "title": "Details", + "description": "The local name given to this kind of interest, or further information (semi-structured or unstructured) to clarify the nature of the interest.", + "type": "string" + }, + "share": { + "title": "Percentage Share", + "description": "The proportion of this type of interest held by the interested party, where an interest is countable. Provide the `exact` percentage if known. Otherwise, `minimum` (or `exclusiveMinimum`) and `maximum` (or `exclusiveMaximum`) can be used to record the range into which the proportion falls. (The `minimum` and `maximum` values are inclusive.)", + "type": "object", + "properties": { + "exact": { + "title": "Exact percentage", + "description": "The exact share of this interest held (if available).", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "maximum": { + "title": "Maximum Percentage", + "description": "The inclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "minimum": { + "title": "Minimum Percentage", + "description": "The inclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMinimum": { + "title": "Exclusive Minimum percentage", + "description": "The exclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMaximum": { + "title": "Exclusive Maximum Percentage", + "description": "The exclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + } + } + }, + "startDate": { + "title": "Start Date", + "description": "The date from which this interest was active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this interest ceased to exist. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + } + } + } + } + } + } + } + } + ], + "required": [ + "statementId", + "declarationSubject", + "recordId", + "recordType", + "recordDetails", + "statementDate" + ] + }, + "$defs": { + "Statement": { + "title": "Statement", + "description": "A claim about a person, entity or relationship, made at a particular point in time.", + "type": "object", + "properties": { + "statementId": { + "title": "Statement Identifier", + "description": "A persistent globally unique identifier for this Statement. Length MUST be 32 - 64 characters (inclusive).", + "type": "string", + "minLength": 32, + "maxLength": 64 + }, + "statementDate": { + "title": "Statement Date", + "description": "The date on which this statement was declared by the source, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "annotations": { + "title": "Annotations", + "description": "Annotations about this Statement or parts of this Statement", + "type": "array", + "items": { + "title": "Annotation", + "description": "Additional information about the data contained in this Statement. Annotations can apply to a whole statement, an object or a single field. Custom properties can be included within the Annotation object to provide structured data where required.", + "type": "object", + "properties": { + "statementPointerTarget": { + "title": "Statement Fragment Pointer", + "description": "An RFC6901 JSON Pointer (https://tools.ietf.org/html/rfc6901) describing the target fragment of the statement that this Annotation applies to, starting from the root of the Statement. An empty string (\"\") indicates that the Annotation applies to the whole Statement.", + "type": "string" + }, + "creationDate": { + "title": "Creation Date", + "description": "The date on which this Annotation was created, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "createdBy": { + "title": "Created By", + "description": "The person, organisation or agent that created this Annotation.", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the person, organisation or agent that created this Annotation.", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the person, organisation or agent that created this Annotation.", + "type": "string", + "format": "uri" + } + } + }, + "motivation": { + "title": "Motivation", + "description": "The reason for this Annotation, using the annotationMotivation codelist.", + "type": "string", + "enum": [ + "commenting", + "correcting", + "identifying", + "linking", + "transformation" + ], + "codelist": "annotationMotivation.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "A free text description providing extra information about part of this Statement.", + "type": "string" + }, + "transformedContent": { + "type": "string", + "title": "Transformed Content", + "description": "A representation of the Annotation target after the transformation in the `description` field has been applied. This field MUST only be used when the `motivation` is 'transformation'." + }, + "url": { + "title": "URL", + "description": "A linked resource that annotates, provides context for or enhances this Statement. The content of the resource, or the relationship to the statement, MAY be described in the `description` field. This field is REQUIRED if the value of `motivation` is 'linking'.", + "type": "string", + "format": "uri" + } + }, + "allOf": [ + { + "if": { + "properties": { + "motivation": { + "const": "linking" + } + } + }, + "then": { + "required": [ + "statementPointerTarget", + "motivation", + "url" + ] + }, + "else": { + "required": [ + "statementPointerTarget", + "motivation" + ] + } + }, + { + "if": { + "not": { + "properties": { + "motivation": { + "const": "transformation" + } + } + } + }, + "then": { + "properties": { + "transformedContent": { + "const": "" + } + } + } + } + ] + } + }, + "publicationDetails": { + "title": "Publication Details", + "description": "Information concerning the publication of this Statement.", + "type": "object", + "properties": { + "publicationDate": { + "title": "Publication date", + "description": "The date on which this statement was published, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "bodsVersion": { + "title": "BODS Version", + "description": "The version of the Beneficial Ownership Data Standard to which this Statement conforms, expressed as major.minor (e.g. 0.2 or 1.0). In a published BODS dataset, all Statements MUST have the same major version number.", + "type": "string", + "pattern": "^(\\d+\\.)(\\d+)$" + }, + "license": { + "title": "License URL", + "description": "A link to the license that applies to this Statement. The canonical URI of the license SHOULD be used. Publishers are encouraged to use a Public Domain Dedication or Open Definition Conformant (http://opendefinition.org/licenses/) license.", + "type": "string", + "format": "uri" + }, + "publisher": { + "type": "object", + "title": "Publisher", + "description": "Details of the organisation or person publishing a Statement.", + "properties": { + "name": { + "title": "Name", + "description": "The name of the publisher.", + "type": "string" + }, + "url": { + "title": "URL", + "description": "The URL where details of the full dataset, or of the publisher, can be found.", + "type": "string", + "format": "uri" + } + }, + "anyOf": [ + { + "required": [ + "name" + ] + }, + { + "required": [ + "url" + ] + } + ] + } + }, + "required": [ + "publicationDate", + "bodsVersion", + "publisher" + ] + }, + "source": { + "title": "Source", + "description": "Details describing an information source.", + "type": "object", + "properties": { + "type": { + "title": "Source Type", + "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "selfDeclaration", + "officialRegister", + "thirdParty", + "primaryResearch", + "verified" + ], + "codelist": "sourceType.csv", + "openCodelist": false + } + }, + "description": { + "title": "Description", + "description": "Additional, free text information about the source of information.", + "type": "string" + }, + "url": { + "title": "Source URL", + "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", + "type": "string", + "format": "uri" + }, + "retrievedAt": { + "title": "Retrieved At", + "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "assertedBy": { + "title": "Asserted By", + "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the agent making the assertion", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the agent making the assertion", + "type": "string", + "format": "uri" + } + } + } + } + } + }, + "declaration": { + "title": "Declaration Reference", + "description": "An identifier or reference for a declaration within the publisher\u2019s system. Where a Statement is a claim from a particular declaration (made at a point in time by a `source` about a `declarationSubject`) this field identifies the declaration.", + "type": "string" + }, + "declarationSubject": { + "title": "Declaration Subject", + "description": "A `recordId` value for the subject of a beneficial ownership network (always an entity or person).", + "type": "string" + }, + "recordId": { + "title": "Record Identifier", + "description": "A unique identifier for the record (within the publisher's system) to which this Statement relates. (A record captures information about an entity, natural person or relationship within the beneficial ownership network of a particular declaration subject.)", + "type": "string" + }, + "recordType": { + "title": "Record Type", + "description": "The type of record (within the publisher's system) to which this Statement relates: entity, person, or relationship.", + "type": "string", + "enum": [ + "entity", + "person", + "relationship" + ], + "codelist": "recordType.csv", + "openCodelist": false + }, + "recordStatus": { + "title": "Record Status", + "description": "The lifecycle status of the record (within the publisher's system) to which this Statement relates, using the recordStatus codelist.", + "type": "string", + "enum": [ + "new", + "updated", + "closed" + ], + "codelist": "recordStatus.csv", + "openCodelist": false + }, + "recordDetails": { + "title": "Record Details", + "description": "The details of the entity, person or relationship as declared on the Statement Date.", + "type": "object" + } + }, + "allOf": [ + { + "if": { + "properties": { + "recordType": { + "const": "entity" + } + } + }, + "then": { + "properties": { + "recordDetails": { + "$id": "urn:entity", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": "0.4", + "title": "Entity Record Details", + "description": "Information about an entity.", + "type": "object", + "properties": { + "isComponent": { + "title": "Is component", + "description": "Whether this entity is a component in an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this entity MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Entity Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Entity Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship statement MUST have a `isComponent` value of 'false'.", + "type": "boolean" + }, + "entityType": { + "type": "object", + "title": "Entity Type", + "description": "The form of the entity described in the Statement.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "title": "Type", + "description": "The general form of the entity, using the entityType codelist.", + "codelist": "entityType.csv", + "enum": [ + "registeredEntity", + "legalEntity", + "arrangement", + "anonymousEntity", + "unknownEntity", + "state", + "stateBody" + ] + }, + "subtype": { + "type": "string", + "title": "Subtype", + "description": "The particular form of the entity, where relevant, using the entitySubtype codelist. The value MUST align with the `entityType` value.", + "codelist": "entitySubtype.csv", + "enum": [ + "governmentDepartment", + "stateAgency", + "other", + "trust", + "nomination" + ], + "openCodelist": false + }, + "details": { + "type": "string", + "title": "Details", + "description": "This may be used to provide a local name for this type of entity, or any further information to identify the type of entity. For example, in Finland 'ministeri\u00f6' for a government department." + } + }, + "propertyOrder": 4, + "allOf": [ + { + "if": { + "properties": { + "type": { + "enum": [ + "arrangement" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "trust", + "nomination", + "other" + ] + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "legalEntity" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "trust", + "other" + ] + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "stateBody" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "governmentDepartment", + "stateAgency", + "other" + ] + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "registeredEntity", + "state", + "anonymousEntity", + "unknownEntity" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "other" + ] + } + } + } + } + ] + }, + "unspecifiedEntityDetails": { + "title": "Unspecified or unknown person or entity", + "description": "A `reason` MUST be supplied.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", + "type": "string", + "enum": [ + "noBeneficialOwners", + "subjectUnableToConfirmOrIdentifyBeneficialOwner", + "interestedPartyHasNotProvidedInformation", + "subjectExemptFromDisclosure", + "interestedPartyExemptFromDisclosure", + "unknown", + "informationUnknownToPublisher" + ], + "codelist": "unspecifiedReason.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", + "type": "string" + } + }, + "required": [ + "reason" + ] + }, + "name": { + "title": "Entity Name", + "description": "The declared name of this entity.", + "type": "string", + "propertyOrder": 10 + }, + "alternateNames": { + "title": "Alternative Names", + "description": "An array of other names this entity is known by.", + "type": "array", + "items": { + "type": "string", + "title": "Name", + "description": "A name this entity is known by." + }, + "propertyOrder": 12 + }, + "jurisdiction": { + "title": "Jurisdiction", + "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the jurisdiction", + "type": "string" + }, + "code": { + "title": "Country or Subdivision Code", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", + "type": "string", + "maxLength": 6, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "identifiers": { + "title": "Identifiers", + "description": "One or more official identifiers for this entity. Where available, official registration numbers should be provided.", + "type": "array", + "items": { + "title": "Identifier", + "description": "An identifier that has been assigned to a person or entity. `scheme` or `schemeName` (or both) MUST be included in an Identifier object.", + "type": "object", + "properties": { + "id": { + "title": "ID", + "description": "The identifier for a person or entity, as issued by the scheme.", + "type": "string" + }, + "scheme": { + "title": "Scheme Code", + "description": "For entities, a code from org-id.guide (https://www.org-id.guide) for an identifier-issuing authority (e.g. 'GB-COH'). For natural persons, a value with the pattern {JURISDICTION}-{TYPE} where JURISDICTION is an ISO 3166-1 3-digit country code and TYPE is one of PASSPORT, TAXID or IDCARD.", + "type": "string" + }, + "schemeName": { + "title": "Scheme Name", + "description": "The name of the identifier-issuing authority.", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "A canonical URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) for the identifier and associated details of the person or entity, if one exists.", + "type": "string", + "format": "uri" + } + }, + "anyOf": [ + { + "required": [ + "scheme" + ] + }, + { + "required": [ + "schemeName" + ] + }, + { + "required": [ + "scheme", + "schemeName" + ] + } + ] + }, + "propertyOrder": 20 + }, + "foundingDate": { + "title": "Founding Date", + "description": "The date on which this entity was founded, created or registered. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date", + "propertyOrder": 30 + }, + "dissolutionDate": { + "title": "Dissolution Date", + "description": "The date on which this entity was dissolved or ceased, if it is no longer active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date", + "propertyOrder": 35 + }, + "addresses": { + "title": "Addresses", + "description": "One or more addresses for this entity.", + "type": "array", + "items": { + "title": "Address", + "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", + "type": "object", + "properties": { + "type": { + "title": "Type", + "description": "The function of the address, using the addressType codelist.", + "type": "string", + "enum": [ + "placeOfBirth", + "residence", + "registered", + "service", + "alternative", + "business" + ], + "codelist": "addressType.csv", + "openCodelist": false + }, + "address": { + "title": "Address", + "description": "The address, with each line or component separated by a line-break or comma.", + "type": "string" + }, + "postCode": { + "title": "Postcode", + "description": "The postal code for this address.", + "type": "string" + }, + "country": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + } + } + }, + "propertyOrder": 40 + }, + "uri": { + "title": "URI", + "description": "Where a persistent URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) is available for this entity this should be included.", + "type": "string", + "format": "uri", + "propertyOrder": 21 + }, + "publicListing": { + "type": "object", + "title": "Public Listing", + "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", + "required": [ + "hasPublicListing" + ], + "minProperties": 1, + "properties": { + "hasPublicListing": { + "type": "boolean", + "title": "Has Public Listing", + "description": "Whether the entity is a publicly listed company." + }, + "companyFilingsURLs": { + "type": "array", + "title": "Company Filings URLs", + "description": "URL or URLs where regulatory filings related to major holdings can be retrieved. URLs may point to pages maintained by regulatory bodies, stock exchanges or by the company itself.", + "items": { + "type": "string", + "format": "uri" + } + }, + "securitiesListings": { + "type": "array", + "title": "Securities Listings", + "description": "Details of the entity's securities and the public exchanges and markets on which they are traded. All equity securities SHOULD be listed here, plus any other securities from which beneficial ownership might be derived. Where a security is traded on more than one market, there SHOULD be an entry for each market (or market segment).", + "items": { + "type": "object", + "title": "Securities Listing", + "description": "Details of a security and the market on which it is traded.", + "required": [ + "stockExchangeJurisdiction", + "security", + "stockExchangeName" + ], + "properties": { + "marketIdentifierCode": { + "type": "string", + "title": "Market Identifier Code (MIC)", + "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "operatingMarketIdentifierCode": { + "type": "string", + "title": "Operating Market Identifier Code (Operating MIC)", + "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "stockExchangeJurisdiction": { + "type": "string", + "title": "Stock Exchange Jurisdiction", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", + "maxLength": 6, + "minLength": 2 + }, + "stockExchangeName": { + "type": "string", + "title": "Stock Exchange Name", + "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." + }, + "security": { + "type": "object", + "title": "Security", + "description": "Identifying information of the stock or other security.", + "required": [ + "ticker" + ], + "properties": { + "idScheme": { + "type": "string", + "title": "Identifier Scheme", + "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", + "enum": [ + "isin", + "figi", + "cusip", + "cins" + ], + "codelist": "securitiesIdentifierSchemes.csv" + }, + "id": { + "type": "string", + "title": "Identifier", + "description": "The unique identifier of the security as issued under the `idScheme`." + }, + "ticker": { + "type": "string", + "title": "Stock Ticker", + "description": "The stock ticker identifying this security on the named stock exchange." + } + } + } + } + } + } + } + }, + "formedByStatute": { + "type": "object", + "title": "Formed by Statute", + "description": "The law which mandated the formation of the entity described in the statement, where applicable. This information SHOULD be provided where a state has created an agency or other entity with specific legislation.", + "properties": { + "name": { + "type": "string", + "title": "Statute Name", + "description": "The name of the law. " + }, + "date": { + "type": "string", + "title": "Date", + "description": "The date on which the law came into force. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "format": "date" + } + }, + "propertyOrder": 18 + } + }, + "required": [ + "isComponent", + "entityType" + ], + "$defs": { + "PublicListing": { + "type": "object", + "title": "Public Listing", + "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", + "required": [ + "hasPublicListing" + ], + "minProperties": 1, + "properties": { + "hasPublicListing": { + "type": "boolean", + "title": "Has Public Listing", + "description": "Whether the entity is a publicly listed company." + }, + "companyFilingsURLs": { + "type": "array", + "title": "Company Filings URLs", + "description": "URL or URLs where regulatory filings related to major holdings can be retrieved. URLs may point to pages maintained by regulatory bodies, stock exchanges or by the company itself.", + "items": { + "type": "string", + "format": "uri" + } + }, + "securitiesListings": { + "type": "array", + "title": "Securities Listings", + "description": "Details of the entity's securities and the public exchanges and markets on which they are traded. All equity securities SHOULD be listed here, plus any other securities from which beneficial ownership might be derived. Where a security is traded on more than one market, there SHOULD be an entry for each market (or market segment).", + "items": { + "type": "object", + "title": "Securities Listing", + "description": "Details of a security and the market on which it is traded.", + "required": [ + "stockExchangeJurisdiction", + "security", + "stockExchangeName" + ], + "properties": { + "marketIdentifierCode": { + "type": "string", + "title": "Market Identifier Code (MIC)", + "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "operatingMarketIdentifierCode": { + "type": "string", + "title": "Operating Market Identifier Code (Operating MIC)", + "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "stockExchangeJurisdiction": { + "type": "string", + "title": "Stock Exchange Jurisdiction", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", + "maxLength": 6, + "minLength": 2 + }, + "stockExchangeName": { + "type": "string", + "title": "Stock Exchange Name", + "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." + }, + "security": { + "type": "object", + "title": "Security", + "description": "Identifying information of the stock or other security.", + "required": [ + "ticker" + ], + "properties": { + "idScheme": { + "type": "string", + "title": "Identifier Scheme", + "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", + "enum": [ + "isin", + "figi", + "cusip", + "cins" + ], + "codelist": "securitiesIdentifierSchemes.csv" + }, + "id": { + "type": "string", + "title": "Identifier", + "description": "The unique identifier of the security as issued under the `idScheme`." + }, + "ticker": { + "type": "string", + "title": "Stock Ticker", + "description": "The stock ticker identifying this security on the named stock exchange." + } + } + } + } + } + } + } + }, + "SecuritiesListing": { + "type": "object", + "title": "Securities Listing", + "description": "Details of a security and the market on which it is traded.", + "required": [ + "stockExchangeJurisdiction", + "security", + "stockExchangeName" + ], + "properties": { + "marketIdentifierCode": { + "type": "string", + "title": "Market Identifier Code (MIC)", + "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "operatingMarketIdentifierCode": { + "type": "string", + "title": "Operating Market Identifier Code (Operating MIC)", + "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "stockExchangeJurisdiction": { + "type": "string", + "title": "Stock Exchange Jurisdiction", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", + "maxLength": 6, + "minLength": 2 + }, + "stockExchangeName": { + "type": "string", + "title": "Stock Exchange Name", + "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." + }, + "security": { + "type": "object", + "title": "Security", + "description": "Identifying information of the stock or other security.", + "required": [ + "ticker" + ], + "properties": { + "idScheme": { + "type": "string", + "title": "Identifier Scheme", + "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", + "enum": [ + "isin", + "figi", + "cusip", + "cins" + ], + "codelist": "securitiesIdentifierSchemes.csv" + }, + "id": { + "type": "string", + "title": "Identifier", + "description": "The unique identifier of the security as issued under the `idScheme`." + }, + "ticker": { + "type": "string", + "title": "Stock Ticker", + "description": "The stock ticker identifying this security on the named stock exchange." + } + } + } + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "recordType": { + "const": "person" + } + } + }, + "then": { + "properties": { + "recordDetails": { + "$id": "urn:person", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": "0.4", + "type": "object", + "title": "Person Record Details", + "description": "Information about a natural person.", + "properties": { + "isComponent": { + "title": "Is component", + "description": "Whether this person is a component of an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this person MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Person Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Person Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship Statement MUST have a `isComponent` value of 'false'.", + "type": "boolean" + }, + "personType": { + "title": "Person Type", + "description": "The status of this person, using the personType codelist. Where a person has the type 'anonymousPerson' or 'unknownPerson' a reason for the absence of information SHOULD be provided in 'unspecifiedPersonDetails'", + "type": "string", + "enum": [ + "anonymousPerson", + "unknownPerson", + "knownPerson" + ], + "propertyOrder": 4, + "codelist": "personType.csv", + "openCodelist": false + }, + "unspecifiedPersonDetails": { + "title": "Unspecified or unknown person or entity", + "description": "A `reason` MUST be supplied.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", + "type": "string", + "enum": [ + "noBeneficialOwners", + "subjectUnableToConfirmOrIdentifyBeneficialOwner", + "interestedPartyHasNotProvidedInformation", + "subjectExemptFromDisclosure", + "interestedPartyExemptFromDisclosure", + "unknown", + "informationUnknownToPublisher" + ], + "codelist": "unspecifiedReason.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", + "type": "string" + } + }, + "required": [ + "reason" + ] + }, + "names": { + "title": "Names", + "description": "One or more known names for this person.", + "type": "array", + "items": { + "title": "Name", + "description": "A name by which this person is known. A name MUST be provided in `fullName`, and MAY be broken down in the `familyName`, `givenName` and `patronymicName` fields, based on the EC ISA Core Person Vocabulary (https://joinup.ec.europa.eu/solution/e-government-core-vocabularies) definitions.", + "type": "object", + "required": [ + "fullName" + ], + "properties": { + "type": { + "title": "Type", + "description": "The status of this name for the person, using the nameType codelist.", + "type": "string", + "enum": [ + "legal", + "translation", + "transliteration", + "former", + "alternative", + "birth" + ], + "codelist": "nameType.csv", + "openCodelist": false + }, + "fullName": { + "title": "Full Name", + "description": "The complete name of the person.", + "type": "string" + }, + "familyName": { + "title": "Family Name", + "description": "Part of the person's `fullName` which is shared by family members. The value may include prefixes or suffixes, e.g. 'de Boer', 'van de Putte', 'von und zu Orlow'. The value may be a multiple-part family name, such as are commonly found in Hispanic countries. For example, Miguel de Cervantes Saavedra's Family Name would be recorded as 'de Cervantes Saavedra.'", + "type": "string" + }, + "givenName": { + "title": "Given Names", + "description": "The part of the person's `fullName` that identifies the person within their family. These are given to a person by their parents at birth or may be legally recognised as 'given names' through a formal process. For example, the given name for Johann Sebastian Bach is 'Johann Sebastian'.", + "type": "string" + }, + "patronymicName": { + "title": "Patronymic Name", + "description": "Part of the person's `fullName` which is inherited from their father, as is common in countries such as Iceland, Ethiopia and Russia. For example, the 'Sergeyevich' in 'Mikhail Sergeyevich Gorbachev'.", + "type": "string" + } + } + }, + "propertyOrder": 10 + }, + "identifiers": { + "title": "Identifiers", + "description": "One or more official identifiers for this person. Where available, official registration numbers should be provided.", + "type": "array", + "items": { + "title": "Identifier", + "description": "An identifier that has been assigned to a person or entity. `scheme` or `schemeName` (or both) MUST be included in an Identifier object.", + "type": "object", + "properties": { + "id": { + "title": "ID", + "description": "The identifier for a person or entity, as issued by the scheme.", + "type": "string" + }, + "scheme": { + "title": "Scheme Code", + "description": "For entities, a code from org-id.guide (https://www.org-id.guide) for an identifier-issuing authority (e.g. 'GB-COH'). For natural persons, a value with the pattern {JURISDICTION}-{TYPE} where JURISDICTION is an ISO 3166-1 3-digit country code and TYPE is one of PASSPORT, TAXID or IDCARD.", + "type": "string" + }, + "schemeName": { + "title": "Scheme Name", + "description": "The name of the identifier-issuing authority.", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "A canonical URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) for the identifier and associated details of the person or entity, if one exists.", + "type": "string", + "format": "uri" + } + }, + "anyOf": [ + { + "required": [ + "scheme" + ] + }, + { + "required": [ + "schemeName" + ] + }, + { + "required": [ + "scheme", + "schemeName" + ] + } + ] + }, + "propertyOrder": 20 + }, + "nationalities": { + "title": "Nationality", + "description": "The nationalities held by this person.", + "type": "array", + "items": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "propertyOrder": 30 + }, + "placeOfBirth": { + "title": "Address", + "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", + "type": "object", + "properties": { + "type": { + "title": "Type", + "description": "The function of the address, using the addressType codelist.", + "type": "string", + "enum": [ + "placeOfBirth", + "residence", + "registered", + "service", + "alternative", + "business" + ], + "codelist": "addressType.csv", + "openCodelist": false + }, + "address": { + "title": "Address", + "description": "The address, with each line or component separated by a line-break or comma.", + "type": "string" + }, + "postCode": { + "title": "Postcode", + "description": "The postal code for this address.", + "type": "string" + }, + "country": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + } + } + }, + "birthDate": { + "title": "Date of Birth", + "description": "The date of birth for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", + "type": "string", + "anyOf": [ + { + "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" + }, + { + "format": "date" + } + ], + "propertyOrder": 35 + }, + "deathDate": { + "title": "Death Date", + "description": "The date of death for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", + "type": "string", + "anyOf": [ + { + "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" + }, + { + "format": "date" + } + ], + "propertyOrder": 36 + }, + "taxResidencies": { + "title": "Tax Residency", + "description": "The tax residencies held by this person, as an array of Country objects.", + "type": "array", + "items": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "propertyOrder": 55 + }, + "addresses": { + "title": "Addresses", + "description": "One or more addresses for this person.", + "type": "array", + "items": { + "title": "Address", + "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", + "type": "object", + "properties": { + "type": { + "title": "Type", + "description": "The function of the address, using the addressType codelist.", + "type": "string", + "enum": [ + "placeOfBirth", + "residence", + "registered", + "service", + "alternative", + "business" + ], + "codelist": "addressType.csv", + "openCodelist": false + }, + "address": { + "title": "Address", + "description": "The address, with each line or component separated by a line-break or comma.", + "type": "string" + }, + "postCode": { + "title": "Postcode", + "description": "The postal code for this address.", + "type": "string" + }, + "country": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + } + } + }, + "propertyOrder": 60 + }, + "politicalExposure": { + "type": "object", + "title": "Political Exposure", + "description": "Information about whether, and how, the person described by this statement is politically exposed. Use this property only if politically exposed person (PEP) declarations are expected as part of beneficial ownership declarations.", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "title": "Politically Exposed Person (PEP) Status", + "description": "This value is 'isPep' or 'isNotPep' according to whether the person described by this statement has the status of politically exposed person (PEP). An 'unknown' value means a PEP status declaration is expected but missing; the reason for the missing data SHOULD be supplied in the `details` array.", + "enum": [ + "isPep", + "isNotPep", + "unknown" + ] + }, + "details": { + "type": "array", + "title": "Politically Exposed Person (PEP) Details", + "description": "One or more descriptions of this person's Politically Exposed Person (PEP) status.", + "items": { + "title": "PEP Status Details", + "description": "Information about a person's political involvement.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason for this person being declared a politically-exposed person.", + "type": "string" + }, + "missingInfoReason": { + "title": "Missing Information Reasons", + "description": "An explanation of why the PEP status for the person is not provided (i.e. `politicalExposure.status` is 'unknown'). This may be a standard descriptive phrase from the source system, or a free text justification. Where this field is present it should be the only field except for `source`.", + "type": "string" + }, + "jurisdiction": { + "title": "Jurisdiction", + "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the jurisdiction", + "type": "string" + }, + "code": { + "title": "Country or Subdivision Code", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", + "type": "string", + "maxLength": 6, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "startDate": { + "title": "State Date", + "description": "The date from which this person had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this person no longer had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "source": { + "title": "Source", + "description": "Details describing an information source.", + "type": "object", + "properties": { + "type": { + "title": "Source Type", + "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "selfDeclaration", + "officialRegister", + "thirdParty", + "primaryResearch", + "verified" + ], + "codelist": "sourceType.csv", + "openCodelist": false + } + }, + "description": { + "title": "Description", + "description": "Additional, free text information about the source of information.", + "type": "string" + }, + "url": { + "title": "Source URL", + "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", + "type": "string", + "format": "uri" + }, + "retrievedAt": { + "title": "Retrieved At", + "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "assertedBy": { + "title": "Asserted By", + "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the agent making the assertion", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the agent making the assertion", + "type": "string", + "format": "uri" + } + } + } + } + } + } + } + } + } + } + } + }, + "required": [ + "personType", + "isComponent" + ], + "$defs": { + "Name": { + "title": "Name", + "description": "A name by which this person is known. A name MUST be provided in `fullName`, and MAY be broken down in the `familyName`, `givenName` and `patronymicName` fields, based on the EC ISA Core Person Vocabulary (https://joinup.ec.europa.eu/solution/e-government-core-vocabularies) definitions.", + "type": "object", + "required": [ + "fullName" + ], + "properties": { + "type": { + "title": "Type", + "description": "The status of this name for the person, using the nameType codelist.", + "type": "string", + "enum": [ + "legal", + "translation", + "transliteration", + "former", + "alternative", + "birth" + ], + "codelist": "nameType.csv", + "openCodelist": false + }, + "fullName": { + "title": "Full Name", + "description": "The complete name of the person.", + "type": "string" + }, + "familyName": { + "title": "Family Name", + "description": "Part of the person's `fullName` which is shared by family members. The value may include prefixes or suffixes, e.g. 'de Boer', 'van de Putte', 'von und zu Orlow'. The value may be a multiple-part family name, such as are commonly found in Hispanic countries. For example, Miguel de Cervantes Saavedra's Family Name would be recorded as 'de Cervantes Saavedra.'", + "type": "string" + }, + "givenName": { + "title": "Given Names", + "description": "The part of the person's `fullName` that identifies the person within their family. These are given to a person by their parents at birth or may be legally recognised as 'given names' through a formal process. For example, the given name for Johann Sebastian Bach is 'Johann Sebastian'.", + "type": "string" + }, + "patronymicName": { + "title": "Patronymic Name", + "description": "Part of the person's `fullName` which is inherited from their father, as is common in countries such as Iceland, Ethiopia and Russia. For example, the 'Sergeyevich' in 'Mikhail Sergeyevich Gorbachev'.", + "type": "string" + } + } + }, + "PepStatusDetails": { + "title": "PEP Status Details", + "description": "Information about a person's political involvement.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason for this person being declared a politically-exposed person.", + "type": "string" + }, + "missingInfoReason": { + "title": "Missing Information Reasons", + "description": "An explanation of why the PEP status for the person is not provided (i.e. `politicalExposure.status` is 'unknown'). This may be a standard descriptive phrase from the source system, or a free text justification. Where this field is present it should be the only field except for `source`.", + "type": "string" + }, + "jurisdiction": { + "title": "Jurisdiction", + "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the jurisdiction", + "type": "string" + }, + "code": { + "title": "Country or Subdivision Code", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", + "type": "string", + "maxLength": 6, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "startDate": { + "title": "State Date", + "description": "The date from which this person had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this person no longer had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "source": { + "title": "Source", + "description": "Details describing an information source.", + "type": "object", + "properties": { + "type": { + "title": "Source Type", + "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "selfDeclaration", + "officialRegister", + "thirdParty", + "primaryResearch", + "verified" + ], + "codelist": "sourceType.csv", + "openCodelist": false + } + }, + "description": { + "title": "Description", + "description": "Additional, free text information about the source of information.", + "type": "string" + }, + "url": { + "title": "Source URL", + "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", + "type": "string", + "format": "uri" + }, + "retrievedAt": { + "title": "Retrieved At", + "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "assertedBy": { + "title": "Asserted By", + "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the agent making the assertion", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the agent making the assertion", + "type": "string", + "format": "uri" + } + } + } + } + } + } + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "recordType": { + "const": "relationship" + } + } + }, + "then": { + "properties": { + "recordDetails": { + "$id": "urn:relationship", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": "0.4", + "title": "Relationship Record Details", + "description": "Information about the interests that an interested party (a person or entity) holds in the subject (an entity).", + "type": "object", + "properties": { + "isComponent": { + "title": "Is component", + "description": "Whether this relationship is a component of a wider indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this secondary Relationship Statement MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Relationship Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Relationship Statement SHOULD be considered when replacing the primary Relationship Statement, and (4) the primary Relationship Statement MUST have an `isComponent` value of 'false'. Where `isComponent` is 'false', this Relationship Statement is the primary declaration of the relationship between the `subject` and the `interestedParty`.", + "type": "boolean" + }, + "componentRecords": { + "title": "Component Record IDs", + "description": "The `recordId` values of all component records that provide detail about this relationship between the `subject` and the `interestedParty` (if it is indirect). If this relationship has components, its own `isComponent` value MUST be 'false'.", + "type": "array", + "items": { + "type": "string" + } + }, + "subject": { + "title": "Subject", + "description": "The `recordId` for the subject of the relationship, or a reason why the subject cannot be specified. The subject MUST be an entity.", + "oneOf": [ + { + "type": "string" + }, + { + "title": "Unspecified or unknown person or entity", + "description": "A `reason` MUST be supplied.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", + "type": "string", + "enum": [ + "noBeneficialOwners", + "subjectUnableToConfirmOrIdentifyBeneficialOwner", + "interestedPartyHasNotProvidedInformation", + "subjectExemptFromDisclosure", + "interestedPartyExemptFromDisclosure", + "unknown", + "informationUnknownToPublisher" + ], + "codelist": "unspecifiedReason.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", + "type": "string" + } + }, + "required": [ + "reason" + ] + } + ] + }, + "interestedParty": { + "title": "Interested Party", + "description": "The `recordId` for the interested party in the relationship, or an Unspecified Record object with a reason for why this information has not been disclosed. The interested party MAY be an entity or a person. An Unspecified Record SHOULD only be used where no information at all is known about interested parties beyond this point of the beneficial ownership network. If the interested party is known to be an entity or person but their particular identity is unavailable, a `recordId` for them SHOULD be provided here (and the their `recordDetails.[person|entity]Type` should indicate that they are anonymous or unknown).", + "oneOf": [ + { + "type": "string" + }, + { + "title": "Unspecified or unknown person or entity", + "description": "A `reason` MUST be supplied.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", + "type": "string", + "enum": [ + "noBeneficialOwners", + "subjectUnableToConfirmOrIdentifyBeneficialOwner", + "interestedPartyHasNotProvidedInformation", + "subjectExemptFromDisclosure", + "interestedPartyExemptFromDisclosure", + "unknown", + "informationUnknownToPublisher" + ], + "codelist": "unspecifiedReason.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", + "type": "string" + } + }, + "required": [ + "reason" + ] + } + ] + }, + "interests": { + "title": "Interests", + "description": "A description of the interests held by the interested party in the subject.", + "type": "array", + "items": { + "title": "Interest", + "description": "A description of an interest held by an interestedParty in the subject.", + "type": "object", + "properties": { + "type": { + "title": "Type of Interest", + "description": "The nature of the interest, using the interestType codelist.", + "type": "string", + "enum": [ + "shareholding", + "votingRights", + "appointmentOfBoard", + "otherInfluenceOrControl", + "seniorManagingOfficial", + "settlor", + "trustee", + "protector", + "beneficiaryOfLegalArrangement", + "rightsToSurplusAssetsOnDissolution", + "rightsToProfitOrIncome", + "rightsGrantedByContract", + "conditionalRightsGrantedByContract", + "controlViaCompanyRulesOrArticles", + "controlByLegalFramework", + "boardMember", + "boardChair", + "unknownInterest", + "unpublishedInterest", + "enjoymentAndUseOfAssets", + "rightToProfitOrIncomeFromAssets", + "nominee", + "nominator" + ], + "codelist": "interestType.csv", + "openCodelist": false + }, + "directOrIndirect": { + "title": "Direct or Indirect", + "description": "How directly the interest is exercised by the interested party. The value MUST be 'indirect' if intermediate entities or agents are known to exist, and MUST be 'direct' if such intermediaries are known not to exist. Otherwise the value MUST be 'unknown'.", + "type": "string", + "enum": [ + "direct", + "indirect", + "unknown" + ], + "codelist": "directOrIndirect.csv", + "openCodelist": false + }, + "beneficialOwnershipOrControl": { + "title": "Beneficial Ownership or Control", + "description": "Whether this interest (alone or with others) means the interested party is a beneficial owner of the subject. If 'true' the interested party MUST be a natural person. The definition of 'beneficial owner' in operation SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "boolean" + }, + "details": { + "title": "Details", + "description": "The local name given to this kind of interest, or further information (semi-structured or unstructured) to clarify the nature of the interest.", + "type": "string" + }, + "share": { + "title": "Percentage Share", + "description": "The proportion of this type of interest held by the interested party, where an interest is countable. Provide the `exact` percentage if known. Otherwise, `minimum` (or `exclusiveMinimum`) and `maximum` (or `exclusiveMaximum`) can be used to record the range into which the proportion falls. (The `minimum` and `maximum` values are inclusive.)", + "type": "object", + "properties": { + "exact": { + "title": "Exact percentage", + "description": "The exact share of this interest held (if available).", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "maximum": { + "title": "Maximum Percentage", + "description": "The inclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "minimum": { + "title": "Minimum Percentage", + "description": "The inclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMinimum": { + "title": "Exclusive Minimum percentage", + "description": "The exclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMaximum": { + "title": "Exclusive Maximum Percentage", + "description": "The exclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + } + } + }, + "startDate": { + "title": "Start Date", + "description": "The date from which this interest was active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this interest ceased to exist. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + } + } + } + } + }, + "required": [ + "isComponent", + "subject", + "interestedParty" + ], + "if": { + "properties": { + "isComponent": { + "const": true + } + } + }, + "then": { + "properties": { + "componentRecords": { + "const": [] + } + } + }, + "$defs": { + "Interest": { + "title": "Interest", + "description": "A description of an interest held by an interestedParty in the subject.", + "type": "object", + "properties": { + "type": { + "title": "Type of Interest", + "description": "The nature of the interest, using the interestType codelist.", + "type": "string", + "enum": [ + "shareholding", + "votingRights", + "appointmentOfBoard", + "otherInfluenceOrControl", + "seniorManagingOfficial", + "settlor", + "trustee", + "protector", + "beneficiaryOfLegalArrangement", + "rightsToSurplusAssetsOnDissolution", + "rightsToProfitOrIncome", + "rightsGrantedByContract", + "conditionalRightsGrantedByContract", + "controlViaCompanyRulesOrArticles", + "controlByLegalFramework", + "boardMember", + "boardChair", + "unknownInterest", + "unpublishedInterest", + "enjoymentAndUseOfAssets", + "rightToProfitOrIncomeFromAssets", + "nominee", + "nominator" + ], + "codelist": "interestType.csv", + "openCodelist": false + }, + "directOrIndirect": { + "title": "Direct or Indirect", + "description": "How directly the interest is exercised by the interested party. The value MUST be 'indirect' if intermediate entities or agents are known to exist, and MUST be 'direct' if such intermediaries are known not to exist. Otherwise the value MUST be 'unknown'.", + "type": "string", + "enum": [ + "direct", + "indirect", + "unknown" + ], + "codelist": "directOrIndirect.csv", + "openCodelist": false + }, + "beneficialOwnershipOrControl": { + "title": "Beneficial Ownership or Control", + "description": "Whether this interest (alone or with others) means the interested party is a beneficial owner of the subject. If 'true' the interested party MUST be a natural person. The definition of 'beneficial owner' in operation SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "boolean" + }, + "details": { + "title": "Details", + "description": "The local name given to this kind of interest, or further information (semi-structured or unstructured) to clarify the nature of the interest.", + "type": "string" + }, + "share": { + "title": "Percentage Share", + "description": "The proportion of this type of interest held by the interested party, where an interest is countable. Provide the `exact` percentage if known. Otherwise, `minimum` (or `exclusiveMinimum`) and `maximum` (or `exclusiveMaximum`) can be used to record the range into which the proportion falls. (The `minimum` and `maximum` values are inclusive.)", + "type": "object", + "properties": { + "exact": { + "title": "Exact percentage", + "description": "The exact share of this interest held (if available).", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "maximum": { + "title": "Maximum Percentage", + "description": "The inclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "minimum": { + "title": "Minimum Percentage", + "description": "The inclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMinimum": { + "title": "Exclusive Minimum percentage", + "description": "The exclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMaximum": { + "title": "Exclusive Maximum Percentage", + "description": "The exclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + } + } + }, + "startDate": { + "title": "Start Date", + "description": "The date from which this interest was active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this interest ceased to exist. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + } + } + } + } + } + } + } + } + ], + "required": [ + "statementId", + "declarationSubject", + "recordId", + "recordType", + "recordDetails", + "statementDate" + ] + }, + "Annotation": { + "title": "Annotation", + "description": "Additional information about the data contained in this Statement. Annotations can apply to a whole statement, an object or a single field. Custom properties can be included within the Annotation object to provide structured data where required.", + "type": "object", + "properties": { + "statementPointerTarget": { + "title": "Statement Fragment Pointer", + "description": "An RFC6901 JSON Pointer (https://tools.ietf.org/html/rfc6901) describing the target fragment of the statement that this Annotation applies to, starting from the root of the Statement. An empty string (\"\") indicates that the Annotation applies to the whole Statement.", + "type": "string" + }, + "creationDate": { + "title": "Creation Date", + "description": "The date on which this Annotation was created, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "createdBy": { + "title": "Created By", + "description": "The person, organisation or agent that created this Annotation.", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the person, organisation or agent that created this Annotation.", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the person, organisation or agent that created this Annotation.", + "type": "string", + "format": "uri" + } + } + }, + "motivation": { + "title": "Motivation", + "description": "The reason for this Annotation, using the annotationMotivation codelist.", + "type": "string", + "enum": [ + "commenting", + "correcting", + "identifying", + "linking", + "transformation" + ], + "codelist": "annotationMotivation.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "A free text description providing extra information about part of this Statement.", + "type": "string" + }, + "transformedContent": { + "type": "string", + "title": "Transformed Content", + "description": "A representation of the Annotation target after the transformation in the `description` field has been applied. This field MUST only be used when the `motivation` is 'transformation'." + }, + "url": { + "title": "URL", + "description": "A linked resource that annotates, provides context for or enhances this Statement. The content of the resource, or the relationship to the statement, MAY be described in the `description` field. This field is REQUIRED if the value of `motivation` is 'linking'.", + "type": "string", + "format": "uri" + } + }, + "allOf": [ + { + "if": { + "properties": { + "motivation": { + "const": "linking" + } + } + }, + "then": { + "required": [ + "statementPointerTarget", + "motivation", + "url" + ] + }, + "else": { + "required": [ + "statementPointerTarget", + "motivation" + ] + } + }, + { + "if": { + "not": { + "properties": { + "motivation": { + "const": "transformation" + } + } + } + }, + "then": { + "properties": { + "transformedContent": { + "const": "" + } + } + } + } + ] + } + } +} diff --git a/libcovebods/data/schema-0-4-0/codelist-schema.json b/libcovebods/data/schema-0-4-0/codelist-schema.json new file mode 100644 index 0000000..5156332 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelist-schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "urn:codelists", + "version": "0.4", + "title": "Codelist schema", + "description": "Schema for BODS codelist CSV files.", + "type": "array", + "items": { + "type": "object", + "required": [ + "code", + "title", + "description" + ], + "additionalProperties": false, + "properties": { + "code": { + "title": "code", + "description": "The value to use in BODS data. Codes should match the letter case of external codes (e.g. ISO 4217) and should be camel case, otherwise.", + "type": "string", + "minLength": 1, + "pattern": "^[^\\s].*[^\\s]$" + }, + "title": { + "title": "title", + "description": "A short title for the code.", + "type": "string", + "minLength": 1, + "pattern": "^[^\\s].*[^\\s]$" + }, + "description": { + "title": "description", + "description": "A longer-form description of the code.", + "type": "string", + "minLength": 1, + "pattern": "^[^\\s].*[^\\s]$" + }, + "technical note": { + "title": "technical note", + "description": "Notes on the application of the code.", + "type": [ + "string", + "null" + ] + } + } + }, + "minItems": 1, + "uniqueItems": true +} diff --git a/libcovebods/data/schema-0-4-0/codelists/addressType.csv b/libcovebods/data/schema-0-4-0/codelists/addressType.csv new file mode 100644 index 0000000..97d33da --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/addressType.csv @@ -0,0 +1,7 @@ +code,title,description +placeOfBirth,Place of birth,The place where a person was born. A town (in the `address` field) and `country` may be sufficient information. This MUST only apply to the `placeOfBirth` field for natural persons. +residence,Residential address,An address where someone lives. This MUST only apply to natural persons. +registered,Registered address,An official address for delivering statutory mail and legal notices which must be provided to company registers. This MUST only apply to entities. +service,Service address,An address which can be used as an alternative to a residential address for the purpose of receiving post. This MUST only apply to natural persons. +alternative,Alternative address,An address provided in addition to the primary address for this entity or person that is neither a service nor a registered address. +business,Business address,A place where the entity conducts its business. diff --git a/libcovebods/data/schema-0-4-0/codelists/annotationMotivation.csv b/libcovebods/data/schema-0-4-0/codelists/annotationMotivation.csv new file mode 100644 index 0000000..18e8437 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/annotationMotivation.csv @@ -0,0 +1,6 @@ +code,title,description +commenting,Commenting,"The description field provides contextual comments for a field, object or statement." +correcting,Correcting,"The value of this field, object or statement has been corrected, using the method in the description field or from the original value given in the description field." +identifying,Identifying,"The value of this field, object or statement has been augmented or processed for the purpose of identifying natural persons or legal entities, using the method in the description field." +linking,Linking,"The description explains how linked material relates to the field, object or statement. A URL to linked material MUST be provided in the `url` field." +transformation,Transformation,"The values of this field, object or statement have been changed from their original form using the method in the description field. The transformed representation may be provided in the `transformedContent` field." diff --git a/libcovebods/data/schema-0-4-0/codelists/directOrIndirect.csv b/libcovebods/data/schema-0-4-0/codelists/directOrIndirect.csv new file mode 100644 index 0000000..a73103a --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/directOrIndirect.csv @@ -0,0 +1,4 @@ +code,title,description +direct,Direct,The interest is held directly. +indirect,Indirect,The interest is held through one or more intermediate entities (including arrangements). +unknown,Unknown,The interest may be direct or indirect. diff --git a/libcovebods/data/schema-0-4-0/codelists/entitySubtype.csv b/libcovebods/data/schema-0-4-0/codelists/entitySubtype.csv new file mode 100644 index 0000000..3e3d10a --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/entitySubtype.csv @@ -0,0 +1,6 @@ +code,title,description +governmentDepartment,Government department,"An element of government with executive responsibilities. These terms are often used to designate such a body: ministry, department, bureau or office. This MUST be used with `entityType.type` 'stateBody'." +stateAgency,State Agency,A body overseeing or administering elements of public policy. State agencies may have responsibilities which are devolved from government departments or from the state's legislative body. This MUST be used with `entityType.type` 'stateBody. +other,Other,Any other type of entity. +trust,Trust,A trust or trust like arrangement. An arrangement where a settlor transfers ownership of assets to trustees to control for the benefit of beneficiaries. This MUST be used with `entityType.type` 'arrangement' or 'legalEntity'. +nomination,Nomination,An agreement where a nominator instructs a nominee to act on their behalf in a specified capacity. This MUST be used with `entityType.type` 'arrangement'. diff --git a/libcovebods/data/schema-0-4-0/codelists/entityType.csv b/libcovebods/data/schema-0-4-0/codelists/entityType.csv new file mode 100644 index 0000000..3c9ac50 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/entityType.csv @@ -0,0 +1,8 @@ +code,title,description +registeredEntity,Registered Entity,"A legal entity created through an act of official registration. In most cases, registered entities have an officially issued identifier." +legalEntity,Legal entity,"A body with distinct legal personality, such as an international institution or statutory corporation, but which is not otherwise uniquely identified in some official register." +arrangement,Arrangement,"A legal arrangement, agreement, contract or other mechanism via which one or more natural or legal persons can associate to exert ownership or control over an entity. Parties to an arrangement have no other form of collective legal identity." +anonymousEntity,Anonymous entity,"An entity that has been identified, but for which identifying information is being withheld. The reason for non-disclosure should be given in the accompanying `unspecifiedEntityDetails` field." +unknownEntity,Unknown entity,An entity that has not been identified. +state,State,"A country, nation or community with legal sovereignty within a territory." +stateBody,State body,A core administrative or legislative unit within a state's apparatus. diff --git a/libcovebods/data/schema-0-4-0/codelists/interestType.csv b/libcovebods/data/schema-0-4-0/codelists/interestType.csv new file mode 100644 index 0000000..0f05503 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/interestType.csv @@ -0,0 +1,24 @@ +code,title,description +shareholding,Shareholding,An economic interest in an entity gained by holding shares. +votingRights,Voting rights,"A controlling interest in an entity gained by holding shares. Defined as the right of shareholders to vote on matters of corporate policy, including decisions on the makeup of the board of directors, issuing securities, initiating corporate actions and making substantial changes in the corporation's operations." +appointmentOfBoard,Appointment of board,A controlling interest in an entity. Defined as the absolute right to appoint members of the board of directors. +otherInfluenceOrControl,Other influence or control,"Any influence or control in an entity that is distinct from being a shareholder, having voting rights or having the absolute right to appoint to the board." +seniorManagingOfficial,Senior managing official,A controlling interest in an entity gained by employment. Defined as the person who exercises control over the management of the entity. +settlor,Settlor,"A person who, either actually or by operation of law, creates a trust. They may be referred to by other names such as a trustor, a grantor or a donor. This should also be used for a person with a settlor-equivalent role in any legal arrangement that is similar to a trust." +trustee,Trustee,A person who administers a trust for the benefit of a third party and in whom the legal title of the trust property is vested either by declaration of the settlor or by operation of law. This should also be used for a person with a trustee-equivalent role in any legal arrangement that is similar to a trust. +protector,Protector,"A person appointed to protect the interests or wishes of the settlor, providing influence and guidance to the trustee who administers the trust. This should also be used for a person with a protector-equivalent role in any legal arrangement that is similar to a trust." +beneficiaryOfLegalArrangement,Beneficiary of a legal arrangement,A person who benefits from a trust or other legal arrangement's holdings or activities. +rightsToSurplusAssetsOnDissolution,Rights to surplus assets on dissolution,The right to a share in the amount of an asset or resource that exceeds the portion that is utilized upon the winding up of an entity. +rightsToProfitOrIncome,Rights to receive profits or income,An economic interest in an entity. Defined as beneficial ownership rights beyond those otherwise implied by ownership structures that are granted by contract. +rightsGrantedByContract,Rights granted by contract,An interest that is granted by contract. +conditionalRightsGrantedByContract,Conditional rights granted by contract,An interest that exists only if some contractual condition is met. +controlViaCompanyRulesOrArticles,Control via company rules or articles,Control of an entity gained through a provision in company articles or by shareholder agreement. +controlByLegalFramework,Control by legal framework,"Control of an entity gained through a legal framework, such as a combination of legislation (primary and secondary). This type of interest is created by governments and legislators in order to establish and guide agencies and entities linked to the state." +boardMember,Board member,One of a group of people constituted as the strategic decision-making body of an organization. +boardChair,Board chair,The person holding the most power and authority on the board of directors. +unknownInterest,Unknown interest,"The interestedParty is known to have an interest in the subject of this Relationship Statement, but the nature of the interest is unknown." +unpublishedInterest,Unpublished interest,The nature of this interest is known but is not published. +enjoymentAndUseOfAssets,Enjoyment and use of assets,The use of assets belonging to an entity. +rightToProfitOrIncomeFromAssets,Right to profit or income from assets,"The right to derive profits, income or both from assets belonging to an entity." +nominee,Nominee,A person who agrees to act on behalf of the nominator in a specified capacity. +nominator,Nominator,A person who instructs a nominee to act on their behalf in a specified capacity. diff --git a/libcovebods/data/schema-0-4-0/codelists/nameType.csv b/libcovebods/data/schema-0-4-0/codelists/nameType.csv new file mode 100644 index 0000000..1ce63f9 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/nameType.csv @@ -0,0 +1,7 @@ +code,title,description +legal,Legal name,"A name that identifies the person for legal, administrative and other official purposes. A person's legal name will usually be the one that is found on official government documents." +translation,Translation of name,A translation of the person's legal name in a different language. +transliteration,Transliteration of name,A transliteration of the person's legal name in a different script. +former,Former name,A name that the person has used in the past. +alternative,Alternative name,"Another name that the person is known by. This might be an alias, a nickname or a name that the person is also known as (aka)." +birth,Birth name,The legal name of the person at birth. diff --git a/libcovebods/data/schema-0-4-0/codelists/personType.csv b/libcovebods/data/schema-0-4-0/codelists/personType.csv new file mode 100644 index 0000000..fd62df0 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/personType.csv @@ -0,0 +1,4 @@ +code,title,description +knownPerson,Known person,"A natural person who has been identified, and information such as names, identifiers or biographical information can be provided about them." +anonymousPerson,Anonymous person,"A natural person who has been identified, but identifying information is being withheld. The reason for non-disclosure should be given in the accompanying `unspecifiedPersonDetails` field." +unknownPerson,Unknown person,A natural person whose identity has not been discovered or confirmed. diff --git a/libcovebods/data/schema-0-4-0/codelists/recordStatus.csv b/libcovebods/data/schema-0-4-0/codelists/recordStatus.csv new file mode 100644 index 0000000..c302cbb --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/recordStatus.csv @@ -0,0 +1,4 @@ +code,title,description +new,New Record,This is the first Statement published pertaining to the record referenced by `recordId`. +updated,Updated Record,This Statement updates information published in a prior Statement pertaining to the record referenced by `recordId`. +closed,Closed Record,This is the final Statement published pertaining to the record referenced by `recordId`. diff --git a/libcovebods/data/schema-0-4-0/codelists/recordType.csv b/libcovebods/data/schema-0-4-0/codelists/recordType.csv new file mode 100644 index 0000000..78be5c1 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/recordType.csv @@ -0,0 +1,4 @@ +code,title,description,technical note +person,Person,"The Record Details in this Statement contain information about a natural person at a particular point in time.",The recordDetails object should be validated using the Person Record schema. +entity,Entity,"The Record Details in this Statement contain information that identifies and describes an entity at a particular point in time.",The recordDetails object should be validated using the Entity Record schema. +relationship,Relationship,"The Record Details in this Statement describe the interests held by an interested party in a subject (an entity) at a particular point in time.",The recordDetails object should be validated using the Relationship Record schema. diff --git a/libcovebods/data/schema-0-4-0/codelists/securitiesIdentifierSchemes.csv b/libcovebods/data/schema-0-4-0/codelists/securitiesIdentifierSchemes.csv new file mode 100644 index 0000000..fd34b56 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/securitiesIdentifierSchemes.csv @@ -0,0 +1,5 @@ +code,title,description +isin,International Securities Identification Number (ISIN),Scheme for unique identification of securities internationally. Securities are issued 12-character identifiers. Full details of the scheme are specified by ISO 6166. +figi,Financial Instrument Global identifier (FIGI),Scheme for unique identification of securities internationally. Securities are issued 12-character identifiers. Full details of the scheme are specified as an Object Management Group standard: https://www.omg.org/spec/FIGI/. +cusip,Committee on Uniform Securities Identification Procedures (CUSIP) Number,Scheme for unique identification of securites in North America. Securities are issued 9-character identifiers. The scheme is managed by the American Bankers Association and specified as ANSI X9.6. +cins,CUSIP International Numbering System (CINS),Scheme for unique identification of securities issued outside North America. Securities are issued 9-character identifiers. The scheme is managed by the American Bankers Association and specified as ANSI X9.6. diff --git a/libcovebods/data/schema-0-4-0/codelists/sourceType.csv b/libcovebods/data/schema-0-4-0/codelists/sourceType.csv new file mode 100644 index 0000000..8595563 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/sourceType.csv @@ -0,0 +1,6 @@ +code,title,description +selfDeclaration,Self declaration,"The information was provided by the person or entity referred to from `declarationSubject`, or by their authorised representative." +officialRegister,Official register,The information was taken from an official register. +thirdParty,Third party,"The information was provided by a third party, not directly related to the person, entity or interests described by this statement." +primaryResearch,Primary research,The information was provided as a result of research into primary sources. +verified,Verified,The information has been verified through the process documented in the associated description. diff --git a/libcovebods/data/schema-0-4-0/codelists/unspecifiedReason.csv b/libcovebods/data/schema-0-4-0/codelists/unspecifiedReason.csv new file mode 100644 index 0000000..b66bb41 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/codelists/unspecifiedReason.csv @@ -0,0 +1,8 @@ +code,title,description +noBeneficialOwners,No beneficial owners,There are no beneficial owners who need to disclose ownership according to the rules under which this statement is made. +subjectUnableToConfirmOrIdentifyBeneficialOwner,Subject unable to confirm or identify beneficial owner,"The subject of this Relationship Statement has, as the disclosing party, been unwilling or unable to confirm the existence identify a beneficial owner." +interestedPartyHasNotProvidedInformation,Interested party has not provided information,The interested party in this Relationship Statement has not provided enough information to identify or confirm the identity of the beneficial owner. +subjectExemptFromDisclosure,Subject exempt from disclosure,The subject of this Relationship Statement is not required to disclose its beneficial owner. +interestedPartyExemptFromDisclosure,Interested party exempt from disclosure,The interested party in this Relationship Statement is exempt from having their identity disclosed. +unknown,Unknown reason,The reason an interested party cannot be provided is not known. +informationUnknownToPublisher,Information unknown to the publisher of the data,A publisher does not have access to information on this person or entity. This should not generally be used in situations where one party has the responsibility to provide such information. diff --git a/libcovebods/data/schema-0-4-0/components.json b/libcovebods/data/schema-0-4-0/components.json new file mode 100644 index 0000000..a28bdcc --- /dev/null +++ b/libcovebods/data/schema-0-4-0/components.json @@ -0,0 +1,237 @@ +{ + "$id": "urn:components", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$comment": "This file contains generic components which are used in multiple places throughout the BODS schema. Components used only in Statement or one type of Record should be defined in their respective files.", + "title": "Components", + "description": "Types of object that can be used via $ref throughout the BODS schema.", + "version": "0.4", + "$defs": { + "Address": { + "title": "Address", + "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", + "type": "object", + "properties": { + "type": { + "title": "Type", + "description": "The function of the address, using the addressType codelist.", + "type": "string", + "enum": [ + "placeOfBirth", + "residence", + "registered", + "service", + "alternative", + "business" + ], + "codelist": "addressType.csv", + "openCodelist": false + }, + "address": { + "title": "Address", + "description": "The address, with each line or component separated by a line-break or comma.", + "type": "string" + }, + "postCode": { + "title": "Postcode", + "description": "The postal code for this address.", + "type": "string" + }, + "country": { + "title": "Country", + "description": "The country for this address.", + "$ref": "urn:components#/$defs/Country" + } + } + }, + "Country": { + "title": "Country", + "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the country", + "type": "string" + }, + "code": { + "title": "Country Code", + "description": "The 2-letter country code (ISO 3166-1) for this country.", + "type": "string", + "maxLength": 2, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "Jurisdiction": { + "title": "Jurisdiction", + "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the jurisdiction", + "type": "string" + }, + "code": { + "title": "Country or Subdivision Code", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", + "type": "string", + "maxLength": 6, + "minLength": 2 + } + }, + "required": [ + "name" + ] + }, + "Identifier": { + "title": "Identifier", + "description": "An identifier that has been assigned to a person or entity. `scheme` or `schemeName` (or both) MUST be included in an Identifier object.", + "type": "object", + "properties": { + "id": { + "title": "ID", + "description": "The identifier for a person or entity, as issued by the scheme.", + "type": "string" + }, + "scheme": { + "title": "Scheme Code", + "description": "For entities, a code from org-id.guide (https://www.org-id.guide) for an identifier-issuing authority (e.g. 'GB-COH'). For natural persons, a value with the pattern {JURISDICTION}-{TYPE} where JURISDICTION is an ISO 3166-1 3-digit country code and TYPE is one of PASSPORT, TAXID or IDCARD.", + "type": "string" + }, + "schemeName": { + "title": "Scheme Name", + "description": "The name of the identifier-issuing authority.", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "A canonical URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) for the identifier and associated details of the person or entity, if one exists.", + "type": "string", + "format": "uri" + } + }, + "anyOf": [ + { + "required": [ + "scheme" + ] + }, + { + "required": [ + "schemeName" + ] + }, + { + "required": [ + "scheme", + "schemeName" + ] + } + ] + }, + "UnspecifiedRecord": { + "title": "Unspecified or unknown person or entity", + "description": "A `reason` MUST be supplied.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", + "type": "string", + "enum": [ + "noBeneficialOwners", + "subjectUnableToConfirmOrIdentifyBeneficialOwner", + "interestedPartyHasNotProvidedInformation", + "subjectExemptFromDisclosure", + "interestedPartyExemptFromDisclosure", + "unknown", + "informationUnknownToPublisher" + ], + "codelist": "unspecifiedReason.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", + "type": "string" + } + }, + "required": [ + "reason" + ] + }, + "Source": { + "title": "Source", + "description": "Details describing an information source.", + "type": "object", + "properties": { + "type": { + "title": "Source Type", + "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "selfDeclaration", + "officialRegister", + "thirdParty", + "primaryResearch", + "verified" + ], + "codelist": "sourceType.csv", + "openCodelist": false + } + }, + "description": { + "title": "Description", + "description": "Additional, free text information about the source of information.", + "type": "string" + }, + "url": { + "title": "Source URL", + "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", + "type": "string", + "format": "uri" + }, + "retrievedAt": { + "title": "Retrieved At", + "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "assertedBy": { + "title": "Asserted By", + "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the agent making the assertion", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the agent making the assertion", + "type": "string", + "format": "uri" + } + } + } + } + } + } + } +} diff --git a/libcovebods/data/schema-0-4-0/entity-record.json b/libcovebods/data/schema-0-4-0/entity-record.json new file mode 100644 index 0000000..12d3ba9 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/entity-record.json @@ -0,0 +1,356 @@ +{ + "$id": "urn:entity", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": "0.4", + "title": "Entity Record Details", + "description": "Information about an entity.", + "type": "object", + "properties": { + "isComponent": { + "title": "Is component", + "description": "Whether this entity is a component in an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this entity MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Entity Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Entity Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship statement MUST have a `isComponent` value of 'false'.", + "type": "boolean" + }, + "entityType": { + "type": "object", + "title": "Entity Type", + "description": "The form of the entity described in the Statement.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "title": "Type", + "description": "The general form of the entity, using the entityType codelist.", + "codelist": "entityType.csv", + "enum": [ + "registeredEntity", + "legalEntity", + "arrangement", + "anonymousEntity", + "unknownEntity", + "state", + "stateBody" + ] + }, + "subtype": { + "type": "string", + "title": "Subtype", + "description": "The particular form of the entity, where relevant, using the entitySubtype codelist. The value MUST align with the `entityType` value.", + "codelist": "entitySubtype.csv", + "enum": [ + "governmentDepartment", + "stateAgency", + "other", + "trust", + "nomination" + ], + "openCodelist": false + }, + "details": { + "type": "string", + "title": "Details", + "description": "This may be used to provide a local name for this type of entity, or any further information to identify the type of entity. For example, in Finland 'ministeriö' for a government department." + } + }, + "propertyOrder": 4, + "allOf":[ + { + "if": { + "properties": { + "type": { + "enum": [ + "arrangement" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum":[ + "trust", + "nomination", + "other" + ] + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "legalEntity" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "trust", + "other" + ] + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "stateBody" + ] + } + } + }, + "then": { + "properties": { + "subtype": { + "enum": [ + "governmentDepartment", + "stateAgency", + "other" + ] + } + } + } + }, + { + "if": { + "properties":{ + "type":{ + "enum":[ + "registeredEntity", + "state", + "anonymousEntity", + "unknownEntity" + ] + } + } + }, + "then": { + "properties": { + "subtype":{ + "enum": [ + "other" + ] + } + } + } + } + ] + }, + "unspecifiedEntityDetails": { + "$ref": "urn:components#/$defs/UnspecifiedRecord", + "description": "An explanation of why an entity is anonymous or unknown." + }, + "name": { + "title": "Entity Name", + "description": "The declared name of this entity.", + "type": "string", + "propertyOrder": 10 + }, + "alternateNames": { + "title": "Alternative Names", + "description": "An array of other names this entity is known by.", + "type": "array", + "items": { + "type": "string", + "title": "Name", + "description": "A name this entity is known by." + }, + "propertyOrder": 12 + }, + "jurisdiction": { + "title": "Jurisdiction", + "description": "The jurisdiction in which this entity was registered or created (for legal and registered entities, and arrangements). Or the state's jurisdiction (for states and state bodies).", + "propertyOrder": 15, + "$ref": "urn:components#/$defs/Jurisdiction" + }, + "identifiers": { + "title": "Identifiers", + "description": "One or more official identifiers for this entity. Where available, official registration numbers should be provided.", + "type": "array", + "items": { + "$ref": "urn:components#/$defs/Identifier" + }, + "propertyOrder": 20 + }, + "foundingDate": { + "title": "Founding Date", + "description": "The date on which this entity was founded, created or registered. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date", + "propertyOrder": 30 + }, + "dissolutionDate": { + "title": "Dissolution Date", + "description": "The date on which this entity was dissolved or ceased, if it is no longer active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date", + "propertyOrder": 35 + }, + "addresses": { + "title": "Addresses", + "description": "One or more addresses for this entity.", + "type": "array", + "items": { + "$ref": "urn:components#/$defs/Address", + "properties":{ + "type":{ + "enum":[ + "registered", + "business", + "alternative" + ] + } + } + }, + "propertyOrder": 40 + }, + "uri": { + "title": "URI", + "description": "Where a persistent URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) is available for this entity this should be included.", + "type": "string", + "format": "uri", + "propertyOrder": 21 + }, + "publicListing": { + "title": "Public Listing", + "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", + "$ref": "#/$defs/PublicListing" + }, + "formedByStatute": { + "type": "object", + "title": "Formed by Statute", + "description": "The law which mandated the formation of the entity described in the statement, where applicable. This information SHOULD be provided where a state has created an agency or other entity with specific legislation.", + "properties": { + "name": { + "type": "string", + "title": "Statute Name", + "description": "The name of the law. " + }, + "date": { + "type": "string", + "title": "Date", + "description": "The date on which the law came into force. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "format": "date" + } + }, + "propertyOrder": 18 + } + }, + "required": [ + "isComponent", + "entityType" + ], + "$defs": { + "PublicListing": { + "type": "object", + "title": "Public Listing", + "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", + "required": [ + "hasPublicListing" + ], + "minProperties": 1, + "properties": { + "hasPublicListing": { + "type": "boolean", + "title": "Has Public Listing", + "description": "Whether the entity is a publicly listed company." + }, + "companyFilingsURLs": { + "type": "array", + "title": "Company Filings URLs", + "description": "URL or URLs where regulatory filings related to major holdings can be retrieved. URLs may point to pages maintained by regulatory bodies, stock exchanges or by the company itself.", + "items": { + "type": "string", + "format": "uri" + } + }, + "securitiesListings": { + "type": "array", + "title": "Securities Listings", + "description": "Details of the entity's securities and the public exchanges and markets on which they are traded. All equity securities SHOULD be listed here, plus any other securities from which beneficial ownership might be derived. Where a security is traded on more than one market, there SHOULD be an entry for each market (or market segment).", + "items": { + "title": "Securities listing", + "description": "Details of a security and the market on which it is traded.", + "$ref": "#/$defs/SecuritiesListing" + } + } + } + }, + "SecuritiesListing": { + "type": "object", + "title": "Securities Listing", + "description": "Details of a security and the market on which it is traded.", + "required": [ + "stockExchangeJurisdiction", + "security", + "stockExchangeName" + ], + "properties": { + "marketIdentifierCode": { + "type": "string", + "title": "Market Identifier Code (MIC)", + "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "operatingMarketIdentifierCode": { + "type": "string", + "title": "Operating Market Identifier Code (Operating MIC)", + "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." + }, + "stockExchangeJurisdiction": { + "type": "string", + "title": "Stock Exchange Jurisdiction", + "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", + "maxLength": 6, + "minLength": 2 + }, + "stockExchangeName": { + "type": "string", + "title": "Stock Exchange Name", + "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." + }, + "security": { + "type": "object", + "title": "Security", + "description": "Identifying information of the stock or other security.", + "required": [ + "ticker" + ], + "properties": { + "idScheme": { + "type": "string", + "title": "Identifier Scheme", + "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", + "enum": [ + "isin", + "figi", + "cusip", + "cins" + ], + "codelist": "securitiesIdentifierSchemes.csv" + }, + "id": { + "type": "string", + "title": "Identifier", + "description": "The unique identifier of the security as issued under the `idScheme`." + }, + "ticker": { + "type": "string", + "title": "Stock Ticker", + "description": "The stock ticker identifying this security on the named stock exchange." + } + } + } + } + } + } +} diff --git a/libcovebods/data/schema-0-4-0/person-record.json b/libcovebods/data/schema-0-4-0/person-record.json new file mode 100644 index 0000000..2005461 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/person-record.json @@ -0,0 +1,245 @@ +{ + "$id": "urn:person", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": "0.4", + "type": "object", + "title": "Person Record Details", + "description": "Information about a natural person.", + "properties": { + "isComponent": { + "title": "Is component", + "description": "Whether this person is a component of an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this person MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Person Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Person Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship Statement MUST have a `isComponent` value of 'false'.", + "type": "boolean" + }, + "personType": { + "title": "Person Type", + "description": "The status of this person, using the personType codelist. Where a person has the type 'anonymousPerson' or 'unknownPerson' a reason for the absence of information SHOULD be provided in 'unspecifiedPersonDetails'", + "type": "string", + "enum": [ + "anonymousPerson", + "unknownPerson", + "knownPerson" + ], + "propertyOrder": 4, + "codelist": "personType.csv", + "openCodelist": false + }, + "unspecifiedPersonDetails": { + "$ref": "urn:components#/$defs/UnspecifiedRecord", + "description": "An explanation of why a person is anonymous or unknown." + }, + "names": { + "title": "Names", + "description": "One or more known names for this person.", + "type": "array", + "items": { + "$ref": "#/$defs/Name" + }, + "propertyOrder": 10 + }, + "identifiers": { + "title": "Identifiers", + "description": "One or more official identifiers for this person. Where available, official registration numbers should be provided.", + "type": "array", + "items": { + "$ref": "urn:components#/$defs/Identifier" + }, + "propertyOrder": 20 + }, + "nationalities": { + "title": "Nationality", + "description": "The nationalities held by this person.", + "type": "array", + "items": { + "$ref": "urn:components#/$defs/Country" + }, + "propertyOrder": 30 + }, + "placeOfBirth": { + "title": "Place of Birth", + "description": "The place where this person was born.", + "propertyOrder": 40, + "$ref": "urn:components#/$defs/Address", + "properties": { + "type": { + "enum": [ + "placeOfBirth" + ] + } + } + }, + "birthDate": { + "title": "Date of Birth", + "description": "The date of birth for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", + "type": "string", + "anyOf": [ + { + "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" + }, + { + "format": "date" + } + ], + "propertyOrder": 35 + }, + "deathDate": { + "title": "Death Date", + "description": "The date of death for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", + "type": "string", + "anyOf": [ + { + "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" + }, + { + "format": "date" + } + ], + "propertyOrder": 36 + }, + "taxResidencies": { + "title": "Tax Residency", + "description": "The tax residencies held by this person, as an array of Country objects.", + "type": "array", + "items": { + "$ref": "urn:components#/$defs/Country" + }, + "propertyOrder": 55 + }, + "addresses": { + "title": "Addresses", + "description": "One or more addresses for this person.", + "type": "array", + "items": { + "$ref": "urn:components#/$defs/Address", + "properties": { + "type": { + "enum": [ + "residence", + "service", + "alternative" + ] + } + } + }, + "propertyOrder": 60 + }, + "politicalExposure": { + "type": "object", + "title": "Political Exposure", + "description": "Information about whether, and how, the person described by this statement is politically exposed. Use this property only if politically exposed person (PEP) declarations are expected as part of beneficial ownership declarations.", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "title": "Politically Exposed Person (PEP) Status", + "description": "This value is 'isPep' or 'isNotPep' according to whether the person described by this statement has the status of politically exposed person (PEP). An 'unknown' value means a PEP status declaration is expected but missing; the reason for the missing data SHOULD be supplied in the `details` array.", + "enum": [ + "isPep", + "isNotPep", + "unknown" + ] + }, + "details": { + "type": "array", + "title": "Politically Exposed Person (PEP) Details", + "description": "One or more descriptions of this person's Politically Exposed Person (PEP) status.", + "items": { + "$ref": "#/$defs/PepStatusDetails" + } + } + } + } + }, + "required": [ + "personType", + "isComponent" + ], + "$defs": { + "Name": { + "title": "Name", + "description": "A name by which this person is known. A name MUST be provided in `fullName`, and MAY be broken down in the `familyName`, `givenName` and `patronymicName` fields, based on the EC ISA Core Person Vocabulary (https://joinup.ec.europa.eu/solution/e-government-core-vocabularies) definitions.", + "type": "object", + "required": [ + "fullName" + ], + "properties": { + "type": { + "title": "Type", + "description": "The status of this name for the person, using the nameType codelist.", + "type": "string", + "enum": [ + "legal", + "translation", + "transliteration", + "former", + "alternative", + "birth" + ], + "codelist": "nameType.csv", + "openCodelist": false + }, + "fullName": { + "title": "Full Name", + "description": "The complete name of the person.", + "type": "string" + }, + "familyName": { + "title": "Family Name", + "description": "Part of the person's `fullName` which is shared by family members. The value may include prefixes or suffixes, e.g. 'de Boer', 'van de Putte', 'von und zu Orlow'. The value may be a multiple-part family name, such as are commonly found in Hispanic countries. For example, Miguel de Cervantes Saavedra's Family Name would be recorded as 'de Cervantes Saavedra.'", + "type": "string" + }, + "givenName": { + "title": "Given Names", + "description": "The part of the person's `fullName` that identifies the person within their family. These are given to a person by their parents at birth or may be legally recognised as 'given names' through a formal process. For example, the given name for Johann Sebastian Bach is 'Johann Sebastian'.", + "type": "string" + }, + "patronymicName": { + "title": "Patronymic Name", + "description": "Part of the person's `fullName` which is inherited from their father, as is common in countries such as Iceland, Ethiopia and Russia. For example, the 'Sergeyevich' in 'Mikhail Sergeyevich Gorbachev'.", + "type": "string" + } + } + }, + "PepStatusDetails": { + "title": "PEP Status Details", + "description": "Information about a person's political involvement.", + "type": "object", + "properties": { + "reason": { + "title": "Reason", + "description": "The reason for this person being declared a politically-exposed person.", + "type": "string" + }, + "missingInfoReason": { + "title": "Missing Information Reasons", + "description": "An explanation of why the PEP status for the person is not provided (i.e. `politicalExposure.status` is 'unknown'). This may be a standard descriptive phrase from the source system, or a free text justification. Where this field is present it should be the only field except for `source`.", + "type": "string" + }, + "jurisdiction": { + "title": "Jurisdiction", + "description": "The jurisdiction where this person is a PEP.", + "$ref": "urn:components#/$defs/Jurisdiction" + }, + "startDate": { + "title": "State Date", + "description": "The date from which this person had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this person no longer had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "source": { + "title": "Source", + "description": "The source of this PEP information", + "$ref": "urn:components#/$defs/Source" + } + } + } + } +} diff --git a/libcovebods/data/schema-0-4-0/relationship-record.json b/libcovebods/data/schema-0-4-0/relationship-record.json new file mode 100644 index 0000000..a5e5d35 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/relationship-record.json @@ -0,0 +1,191 @@ +{ + "$id": "urn:relationship", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": "0.4", + "title": "Relationship Record Details", + "description": "Information about the interests that an interested party (a person or entity) holds in the subject (an entity).", + "type": "object", + "properties": { + "isComponent": { + "title": "Is component", + "description": "Whether this relationship is a component of a wider indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this secondary Relationship Statement MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Relationship Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Relationship Statement SHOULD be considered when replacing the primary Relationship Statement, and (4) the primary Relationship Statement MUST have an `isComponent` value of 'false'. Where `isComponent` is 'false', this Relationship Statement is the primary declaration of the relationship between the `subject` and the `interestedParty`.", + "type": "boolean" + }, + "componentRecords": { + "title": "Component Record IDs", + "description": "The `recordId` values of all component records that provide detail about this relationship between the `subject` and the `interestedParty` (if it is indirect). If this relationship has components, its own `isComponent` value MUST be 'false'.", + "type": "array", + "items": { + "type": "string" + } + }, + "subject": { + "title": "Subject", + "description": "The `recordId` for the subject of the relationship, or a reason why the subject cannot be specified. The subject MUST be an entity.", + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "urn:components#/$defs/UnspecifiedRecord" + } + ] + }, + "interestedParty": { + "title": "Interested Party", + "description": "The `recordId` for the interested party in the relationship, or an Unspecified Record object with a reason for why this information has not been disclosed. The interested party MAY be an entity or a person. An Unspecified Record SHOULD only be used where no information at all is known about interested parties beyond this point of the beneficial ownership network. If the interested party is known to be an entity or person but their particular identity is unavailable, a `recordId` for them SHOULD be provided here (and the their `recordDetails.[person|entity]Type` should indicate that they are anonymous or unknown).", + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "urn:components#/$defs/UnspecifiedRecord" + } + ] + }, + "interests": { + "title": "Interests", + "description": "A description of the interests held by the interested party in the subject.", + "type": "array", + "items": { + "$ref": "#/$defs/Interest" + } + } + }, + "required": [ + "isComponent", + "subject", + "interestedParty" + ], + "if": { + "properties":{ + "isComponent":{ + "const": true + } + } + }, + "then": { + "properties":{ + "componentRecords":{ + "const": [] + } + } + }, + "$defs": { + "Interest": { + "title": "Interest", + "description": "A description of an interest held by an interestedParty in the subject.", + "type": "object", + "properties": { + "type": { + "title": "Type of Interest", + "description": "The nature of the interest, using the interestType codelist.", + "type": "string", + "enum": [ + "shareholding", + "votingRights", + "appointmentOfBoard", + "otherInfluenceOrControl", + "seniorManagingOfficial", + "settlor", + "trustee", + "protector", + "beneficiaryOfLegalArrangement", + "rightsToSurplusAssetsOnDissolution", + "rightsToProfitOrIncome", + "rightsGrantedByContract", + "conditionalRightsGrantedByContract", + "controlViaCompanyRulesOrArticles", + "controlByLegalFramework", + "boardMember", + "boardChair", + "unknownInterest", + "unpublishedInterest", + "enjoymentAndUseOfAssets", + "rightToProfitOrIncomeFromAssets", + "nominee", + "nominator" + ], + "codelist": "interestType.csv", + "openCodelist": false + }, + "directOrIndirect": { + "title": "Direct or Indirect", + "description": "How directly the interest is exercised by the interested party. The value MUST be 'indirect' if intermediate entities or agents are known to exist, and MUST be 'direct' if such intermediaries are known not to exist. Otherwise the value MUST be 'unknown'.", + "type": "string", + "enum": [ + "direct", + "indirect", + "unknown" + ], + "codelist": "directOrIndirect.csv", + "openCodelist": false + }, + "beneficialOwnershipOrControl": { + "title": "Beneficial Ownership or Control", + "description": "Whether this interest (alone or with others) means the interested party is a beneficial owner of the subject. If 'true' the interested party MUST be a natural person. The definition of 'beneficial owner' in operation SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "boolean" + }, + "details": { + "title": "Details", + "description": "The local name given to this kind of interest, or further information (semi-structured or unstructured) to clarify the nature of the interest.", + "type": "string" + }, + "share": { + "title": "Percentage Share", + "description": "The proportion of this type of interest held by the interested party, where an interest is countable. Provide the `exact` percentage if known. Otherwise, `minimum` (or `exclusiveMinimum`) and `maximum` (or `exclusiveMaximum`) can be used to record the range into which the proportion falls. (The `minimum` and `maximum` values are inclusive.)", + "type": "object", + "properties": { + "exact": { + "title": "Exact percentage", + "description": "The exact share of this interest held (if available).", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "maximum": { + "title": "Maximum Percentage", + "description": "The inclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "minimum": { + "title": "Minimum Percentage", + "description": "The inclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMinimum": { + "title": "Exclusive Minimum percentage", + "description": "The exclusive lower bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + }, + "exclusiveMaximum": { + "title": "Exclusive Maximum Percentage", + "description": "The exclusive upper bound of the share of this interest.", + "type": "number", + "maximum": 100, + "minimum": 0 + } + } + }, + "startDate": { + "title": "Start Date", + "description": "The date from which this interest was active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + }, + "endDate": { + "title": "End Date", + "description": "The date from which this interest ceased to exist. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", + "type": "string", + "format": "date" + } + } + } + } +} diff --git a/libcovebods/data/schema-0-4-0/statement.json b/libcovebods/data/schema-0-4-0/statement.json new file mode 100644 index 0000000..b626336 --- /dev/null +++ b/libcovebods/data/schema-0-4-0/statement.json @@ -0,0 +1,337 @@ +{ + "$id": "urn:statement", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Statements", + "description": "An array of Statements.", + "version": "0.4", + "type": "array", + "items": { + "$ref": "#/$defs/Statement" + }, + "$defs": { + "Statement": { + "title": "Statement", + "description": "A claim about a person, entity or relationship, made at a particular point in time.", + "type": "object", + "properties": { + "statementId": { + "title": "Statement Identifier", + "description": "A persistent globally unique identifier for this Statement. Length MUST be 32 - 64 characters (inclusive).", + "type": "string", + "minLength": 32, + "maxLength": 64 + }, + "statementDate": { + "title": "Statement Date", + "description": "The date on which this statement was declared by the source, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "annotations": { + "title": "Annotations", + "description": "Annotations about this Statement or parts of this Statement", + "type": "array", + "items": { + "$ref": "#/$defs/Annotation" + } + }, + "publicationDetails": { + "title": "Publication Details", + "description": "Information concerning the publication of this Statement.", + "type": "object", + "properties": { + "publicationDate": { + "title": "Publication date", + "description": "The date on which this statement was published, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "bodsVersion": { + "title": "BODS Version", + "description": "The version of the Beneficial Ownership Data Standard to which this Statement conforms, expressed as major.minor (e.g. 0.2 or 1.0). In a published BODS dataset, all Statements MUST have the same major version number.", + "type": "string", + "pattern": "^(\\d+\\.)(\\d+)$" + }, + "license": { + "title": "License URL", + "description": "A link to the license that applies to this Statement. The canonical URI of the license SHOULD be used. Publishers are encouraged to use a Public Domain Dedication or Open Definition Conformant (http://opendefinition.org/licenses/) license.", + "type": "string", + "format": "uri" + }, + "publisher": { + "type": "object", + "title": "Publisher", + "description": "Details of the organisation or person publishing a Statement.", + "properties": { + "name": { + "title": "Name", + "description": "The name of the publisher.", + "type": "string" + }, + "url": { + "title": "URL", + "description": "The URL where details of the full dataset, or of the publisher, can be found.", + "type": "string", + "format": "uri" + } + }, + "anyOf": [ + { + "required": [ + "name" + ] + }, + { + "required": [ + "url" + ] + } + ] + } + }, + "required": [ + "publicationDate", + "bodsVersion", + "publisher" + ] + }, + "source": { + "title": "Source", + "description": "The source of information in this statement. Each statement SHOULD contain source information.", + "$ref": "urn:components#/$defs/Source" + }, + "declaration": { + "title": "Declaration Reference", + "description": "An identifier or reference for a declaration within the publisher’s system. Where a Statement is a claim from a particular declaration (made at a point in time by a `source` about a `declarationSubject`) this field identifies the declaration.", + "type": "string" + }, + "declarationSubject": { + "title": "Declaration Subject", + "description": "A `recordId` value for the subject of a beneficial ownership network (always an entity or person).", + "type": "string" + }, + "recordId": { + "title": "Record Identifier", + "description": "A unique identifier for the record (within the publisher's system) to which this Statement relates. (A record captures information about an entity, natural person or relationship within the beneficial ownership network of a particular declaration subject.)", + "type": "string" + }, + "recordType": { + "title": "Record Type", + "description": "The type of record (within the publisher's system) to which this Statement relates: entity, person, or relationship.", + "type": "string", + "enum": [ + "entity", + "person", + "relationship" + ], + "codelist": "recordType.csv", + "openCodelist": false + }, + "recordStatus": { + "title": "Record Status", + "description": "The lifecycle status of the record (within the publisher's system) to which this Statement relates, using the recordStatus codelist.", + "type": "string", + "enum": [ + "new", + "updated", + "closed" + ], + "codelist": "recordStatus.csv", + "openCodelist": false + }, + "recordDetails": { + "title": "Record Details", + "description": "The details of the entity, person or relationship as declared on the Statement Date.", + "type": "object" + } + }, + "allOf": [ + { + "if": { + "properties": { + "recordType": { + "const": "entity" + } + } + }, + "then": { + "properties": { + "recordDetails": { + "$ref": "urn:entity" + } + } + } + }, + { + "if": { + "properties": { + "recordType": { + "const": "person" + } + } + }, + "then": { + "properties": { + "recordDetails": { + "$ref": "urn:person" + } + } + } + }, + { + "if": { + "properties": { + "recordType": { + "const": "relationship" + } + } + }, + "then": { + "properties": { + "recordDetails": { + "$ref": "urn:relationship" + } + } + } + } + ], + "required": [ + "statementId", + "declarationSubject", + "recordId", + "recordType", + "recordDetails", + "statementDate" + ] + }, + "Annotation": { + "title": "Annotation", + "description": "Additional information about the data contained in this Statement. Annotations can apply to a whole statement, an object or a single field. Custom properties can be included within the Annotation object to provide structured data where required.", + "type": "object", + "properties": { + "statementPointerTarget": { + "title": "Statement Fragment Pointer", + "description": "An RFC6901 JSON Pointer (https://tools.ietf.org/html/rfc6901) describing the target fragment of the statement that this Annotation applies to, starting from the root of the Statement. An empty string (\"\") indicates that the Annotation applies to the whole Statement.", + "type": "string" + }, + "creationDate": { + "title": "Creation Date", + "description": "The date on which this Annotation was created, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", + "type": "string", + "anyOf": [ + { + "format": "date" + }, + { + "format": "date-time" + } + ] + }, + "createdBy": { + "title": "Created By", + "description": "The person, organisation or agent that created this Annotation.", + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "The name of the person, organisation or agent that created this Annotation.", + "type": "string" + }, + "uri": { + "title": "URI", + "description": "An optional URI to identify the person, organisation or agent that created this Annotation.", + "type": "string", + "format": "uri" + } + } + }, + "motivation": { + "title": "Motivation", + "description": "The reason for this Annotation, using the annotationMotivation codelist.", + "type": "string", + "enum": [ + "commenting", + "correcting", + "identifying", + "linking", + "transformation" + ], + "codelist": "annotationMotivation.csv", + "openCodelist": false + }, + "description": { + "title": "Description", + "description": "A free text description providing extra information about part of this Statement.", + "type": "string" + }, + "transformedContent": { + "type": "string", + "title": "Transformed Content", + "description": "A representation of the Annotation target after the transformation in the `description` field has been applied. This field MUST only be used when the `motivation` is 'transformation'." + }, + "url": { + "title": "URL", + "description": "A linked resource that annotates, provides context for or enhances this Statement. The content of the resource, or the relationship to the statement, MAY be described in the `description` field. This field is REQUIRED if the value of `motivation` is 'linking'.", + "type": "string", + "format": "uri" + } + }, + "allOf": [ + { + "if": { + "properties": { + "motivation": { + "const": "linking" + } + } + }, + "then": { + "required": [ + "statementPointerTarget", + "motivation", + "url" + ] + }, + "else": { + "required": [ + "statementPointerTarget", + "motivation" + ] + } + }, + { + "if": { + "not": { + "properties": { + "motivation": { + "const": "transformation" + } + } + } + }, + "then": { + "properties": { + "transformedContent":{ + "const": "" + } + } + } + } + ] + } + } +} diff --git a/libcovebods/data_reader.py b/libcovebods/data_reader.py index 97cc646..0b5385a 100644 --- a/libcovebods/data_reader.py +++ b/libcovebods/data_reader.py @@ -2,6 +2,22 @@ import ijson # type: ignore +STATEMENT_MAPPING = { + "entity": "entityStatement", + "person": "personStatement", + "relationship": "ownershipOrControlStatement", +} + + +def get_statement_type(statement): + if isinstance(statement, dict): + if isinstance(statement.get("statementType"), str): + return statement.get("statementType") + if isinstance(statement.get("recordType"), str): + if statement.get("recordType") in STATEMENT_MAPPING: + return STATEMENT_MAPPING[statement.get("recordType")] + return "unknown" + class DataReader: """Class to hold information on where to get data and provides methods to access it. @@ -40,12 +56,13 @@ def get_all_data(self): with open(self._filename, "rb") as fp: for statement in ijson.items(fp, "item"): - statementType = ( - statement.get("statementType") - if isinstance(statement, dict) - and isinstance(statement.get("statementType"), str) - else "unknown" - ) + statementType = get_statement_type(statement) + # statementType = ( + # statement.get("statementType") + # if isinstance(statement, dict) + # and isinstance(statement.get("statementType"), str) + # else "unknown" + # ) if statementType in count_statement_types: if ( count_statement_types[statementType] diff --git a/libcovebods/jsonschemavalidate.py b/libcovebods/jsonschemavalidate.py index 8d1cbf8..746b03f 100644 --- a/libcovebods/jsonschemavalidate.py +++ b/libcovebods/jsonschemavalidate.py @@ -1,9 +1,10 @@ import json from decimal import Decimal +from typing import Union from jsonschema import FormatChecker from jsonschema.exceptions import ValidationError -from jsonschema.validators import Draft4Validator +from jsonschema.validators import Draft4Validator, Draft202012Validator import libcovebods.data_reader from libcovebods.schema import SchemaBODS @@ -101,10 +102,23 @@ def __init__(self, schema: SchemaBODS): def validate(self, data_reader: libcovebods.data_reader.DataReader) -> list: """Call with data. Results are returned.""" - validator = Draft4Validator( - schema=self._schema._pkg_schema_obj, format_checker=FormatChecker() - ) - validator.VALIDATORS["oneOf"] = oneOf_draft4 + validator: Union[Draft4Validator, Draft202012Validator] + if self._schema.is_schema_version_equal_to_or_greater_than("0.4"): + # Get the registry + registry = self._schema._pkg_schema_obj + + # Make the validator + statement_schema = registry.contents("urn:statement") + validator = Draft202012Validator( + schema=statement_schema, + registry=registry, + format_checker=FormatChecker(), + ) + else: + validator = Draft4Validator( + schema=self._schema._pkg_schema_obj, format_checker=FormatChecker() + ) + validator.VALIDATORS["oneOf"] = oneOf_draft4 output = [] all_data = data_reader.get_all_data() for e in validator.iter_errors(all_data): @@ -141,12 +155,15 @@ def __init__( def json(self): """Return representation of this error in JSON.""" - path_ending = self._path[-1] - if isinstance(self._path[-1], int) and len(self._path) >= 2: - # We're dealing with elements in an array of items at this point - path_ending = "{}/[number]".format(self._path[-2]) - elif isinstance(self._path[0], int) and len(self._path) == 1: - path_ending = "[number]" + if self._path: + path_ending = self._path[-1] + if isinstance(self._path[-1], int) and len(self._path) >= 2: + # We're dealing with elements in an array of items at this point + path_ending = f"{self._path[-2]}/[number]" + elif isinstance(self._path[0], int) and len(self._path) == 1: + path_ending = "[number]" + else: + path_ending = "$" return { "message": self._message, diff --git a/libcovebods/run_tasks.py b/libcovebods/run_tasks.py index 5d38347..08ab182 100644 --- a/libcovebods/run_tasks.py +++ b/libcovebods/run_tasks.py @@ -2,18 +2,47 @@ import libcovebods.tasks.checks import libcovebods.tasks.peps import libcovebods.tasks.statistics +from libcovebods.utils import get_statement_type TASK_CLASSES = [ libcovebods.tasks.checks.LegacyChecks, libcovebods.tasks.checks.LegacyChecksNeedingHistory, libcovebods.tasks.checks.CheckHasPublicListing, + libcovebods.tasks.checks.CheckHasPublicListingRecord, libcovebods.tasks.checks.CheckEntityTypeAndEntitySubtypeAlign, libcovebods.tasks.checks.CheckEntitySecurityListingsMICSCodes, - libcovebods.tasks.statistics.LegacyStatistics, + libcovebods.tasks.checks.CheckEntitySecurityListingsMICSCodesRecord, + libcovebods.tasks.checks.CheckSourceRetrievedAtFutureDate, + libcovebods.tasks.checks.CheckStatementDateFutureDate, + libcovebods.tasks.checks.CheckAnnotationCreationDateFutureDate, + libcovebods.tasks.checks.CheckStatementPublicationDateFutureDate, + libcovebods.tasks.checks.CheckStatementPersonDateOfDeathSane, + libcovebods.tasks.checks.CheckStatementEntityFoundationDissolutionDates, + libcovebods.tasks.checks.CheckStatementPersonBirthDateSensible, + libcovebods.tasks.checks.CheckStatementRelationshipInterestsStartEndDates, + libcovebods.tasks.checks.CheckStatementRelationshipInterestsShareValues, + libcovebods.tasks.checks.CheckStatementDeclarationSubject, + libcovebods.tasks.checks.CheckStatementIsComponent, + libcovebods.tasks.checks.CheckStatementDuplicateStatementId, + libcovebods.tasks.checks.CheckStatementSeries, + libcovebods.tasks.checks.CheckStatementRelationshipParties, + libcovebods.tasks.checks.CheckAnnotationStatementPointerTarget, + libcovebods.tasks.checks.CheckStatementRelationshipInterests, + libcovebods.tasks.checks.CheckStatementSerialisation, + libcovebods.tasks.checks.CheckStatementPersonIdentifiersHaveCorrectScheme, + libcovebods.tasks.checks.CheckStatementEntityIdentifiersHaveKnownScheme, + libcovebods.tasks.statistics.StatisticsCountEntityStatements, + libcovebods.tasks.statistics.StatisticsCountEntityRecordStatements, + libcovebods.tasks.statistics.StatisticsCountPersonStatements, + libcovebods.tasks.statistics.StatisticsCountPersonRecordStatements, + libcovebods.tasks.statistics.StatisticsCountOwnershipOrControlStatements, + libcovebods.tasks.statistics.StatisticsCountOwnershipOrControlRecordStatements, libcovebods.tasks.statistics.StatisticsCurrentOwnershipOrControlStatementsAndReplacesStatementsMissing, libcovebods.tasks.statistics.StatisticAddress, libcovebods.tasks.statistics.StatisticOwnershipOrControlInterestDirectOrIndirect, libcovebods.tasks.statistics.StatisticOwnershipOrControlWithAtLeastOneInterestBeneficial, + libcovebods.tasks.statistics.StatisticDeclarationSubjects, + libcovebods.tasks.statistics.StatisticsStatementsRecordStatus, libcovebods.tasks.peps.PEPForSchema02Only, libcovebods.tasks.peps.PEPForSchema03AndAbove, ] @@ -21,12 +50,35 @@ TASK_CLASSES_IN_SAMPLE_MODE = [ libcovebods.tasks.checks.LegacyChecks, libcovebods.tasks.checks.CheckHasPublicListing, + libcovebods.tasks.checks.CheckHasPublicListingRecord, libcovebods.tasks.checks.CheckEntityTypeAndEntitySubtypeAlign, libcovebods.tasks.checks.CheckEntitySecurityListingsMICSCodes, - libcovebods.tasks.statistics.LegacyStatistics, + libcovebods.tasks.checks.CheckEntitySecurityListingsMICSCodesRecord, + libcovebods.tasks.checks.CheckSourceRetrievedAtFutureDate, + libcovebods.tasks.checks.CheckStatementDateFutureDate, + libcovebods.tasks.checks.CheckAnnotationCreationDateFutureDate, + libcovebods.tasks.checks.CheckStatementPublicationDateFutureDate, + libcovebods.tasks.checks.CheckStatementPersonDateOfDeathSane, + libcovebods.tasks.checks.CheckStatementEntityFoundationDissolutionDates, + libcovebods.tasks.checks.CheckStatementPersonBirthDateSensible, + libcovebods.tasks.checks.CheckStatementRelationshipInterestsStartEndDates, + libcovebods.tasks.checks.CheckStatementRelationshipInterestsShareValues, + libcovebods.tasks.checks.CheckStatementDuplicateStatementId, + libcovebods.tasks.checks.CheckAnnotationStatementPointerTarget, + libcovebods.tasks.checks.CheckStatementRelationshipInterests, + libcovebods.tasks.checks.CheckStatementPersonIdentifiersHaveCorrectScheme, + libcovebods.tasks.checks.CheckStatementEntityIdentifiersHaveKnownScheme, + libcovebods.tasks.statistics.StatisticsCountEntityStatements, + libcovebods.tasks.statistics.StatisticsCountEntityRecordStatements, + libcovebods.tasks.statistics.StatisticsCountPersonStatements, + libcovebods.tasks.statistics.StatisticsCountPersonRecordStatements, + libcovebods.tasks.statistics.StatisticsCountOwnershipOrControlStatements, + libcovebods.tasks.statistics.StatisticsCountOwnershipOrControlRecordStatements, libcovebods.tasks.statistics.StatisticAddress, libcovebods.tasks.statistics.StatisticOwnershipOrControlInterestDirectOrIndirect, libcovebods.tasks.statistics.StatisticOwnershipOrControlWithAtLeastOneInterestBeneficial, + libcovebods.tasks.statistics.StatisticDeclarationSubjects, + libcovebods.tasks.statistics.StatisticsStatementsRecordStatus, libcovebods.tasks.peps.PEPForSchema02Only, libcovebods.tasks.peps.PEPForSchema03AndAbove, ] @@ -45,9 +97,14 @@ def process_additional_checks( ] all_data = data_reader.get_all_data() + # If not list of statements put in list so that additional checks + # can be run (jsonschema validation will handle reporting error) + if not isinstance(all_data, list): + all_data = [all_data] + # First pass for statement in all_data: - statement_type = statement.get("statementType") + statement_type = get_statement_type(statement, schema_object) for additional_check_instance in additional_check_instances: additional_check_instance.check_statement_first_pass(statement) if statement_type == "entityStatement": @@ -64,7 +121,10 @@ def process_additional_checks( # Second Pass for statement in all_data: - statement_type = statement.get("statementType") + # statement_type = statement.get("statementType") + statement_type = get_statement_type(statement, schema_object) + for additional_check_instance in additional_check_instances: + additional_check_instance.check_statement_second_pass(statement) if statement_type == "entityStatement": for additional_check_instance in additional_check_instances: additional_check_instance.check_entity_statement_second_pass(statement) diff --git a/libcovebods/schema.py b/libcovebods/schema.py index 845d60e..7020aee 100644 --- a/libcovebods/schema.py +++ b/libcovebods/schema.py @@ -7,6 +7,7 @@ import libcovebods.data_reader from libcovebods.config import LibCoveBODSConfig +from libcovebods.schema_dir import get_scheme_file_data, schema_registry try: from functools import cached_property @@ -14,6 +15,17 @@ from cached_property import cached_property # type: ignore +def record_based_statement(statement): + if ( + "recordDetails" in statement + or "recordId" in statement + or "recordType" in statement + ): + return True + else: + return False + + class SchemaBODS: def __init__( self, @@ -49,6 +61,16 @@ def __work_out_schema_version( # If bad data passed, then we assume it's the default version all_data = data_reader.get_all_data() if not isinstance(all_data, list) or len(all_data) == 0: + if not isinstance(all_data, list): + if record_based_statement(all_data): + self.schema_version = self.config.config["schema_latest_version"] + self.pkg_schema_url = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url"] + self.schema_host = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url_host"] + return self.pkg_schema_url = self.config.config["schema_url"] self.schema_host = self.config.config["schema_url_host"] self.schema_version_attempted = self.config.config["schema_version"] @@ -65,10 +87,20 @@ def __work_out_schema_version( or not isinstance(statement["publicationDetails"], dict) or "bodsVersion" not in statement["publicationDetails"] ): - self.pkg_schema_url = self.config.config["schema_url"] - self.schema_host = self.config.config["schema_url_host"] - self.schema_version_attempted = self.config.config["schema_version"] - self.schema_version = self.config.config["schema_version"] + # Use default version if not record based else latest version (revisit) + if not record_based_statement(statement): + self.pkg_schema_url = self.config.config["schema_url"] + self.schema_host = self.config.config["schema_url_host"] + self.schema_version_attempted = self.config.config["schema_version"] + self.schema_version = self.config.config["schema_version"] + else: + self.schema_version = self.config.config["schema_latest_version"] + self.pkg_schema_url = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url"] + self.schema_host = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url_host"] return # The statement is trying to set a version @@ -81,13 +113,25 @@ def __work_out_schema_version( "type": "unknown_schema_version_used", "schema_version": str(self.schema_version_attempted), } - self.schema_version = self.config.config["schema_latest_version"] - self.pkg_schema_url = self.config.config["schema_versions"][ - self.schema_version - ]["schema_url"] - self.schema_host = self.config.config["schema_versions"][ - self.schema_version - ]["schema_url_host"] + # Use latest non-record version if not record based else latest version (revisit) + if not record_based_statement(statement): + self.schema_version = self.config.config[ + "schema_latest_nonrecord_version" + ] + self.pkg_schema_url = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url"] + self.schema_host = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url_host"] + else: + self.schema_version = self.config.config["schema_latest_version"] + self.pkg_schema_url = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url"] + self.schema_host = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url_host"] return # The statement tries to specify a version which is not known. @@ -97,13 +141,25 @@ def __work_out_schema_version( "type": "unknown_schema_version_used", "schema_version": self.schema_version_attempted, } - self.schema_version = self.config.config["schema_latest_version"] - self.pkg_schema_url = self.config.config["schema_versions"][ - self.schema_version - ]["schema_url"] - self.schema_host = self.config.config["schema_versions"][ - self.schema_version - ]["schema_url_host"] + # Use latest non-record version if not record based else latest version (revisit) + if not record_based_statement(statement): + self.schema_version = self.config.config[ + "schema_latest_nonrecord_version" + ] + self.pkg_schema_url = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url"] + self.schema_host = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url_host"] + else: + self.schema_version = self.config.config["schema_latest_version"] + self.pkg_schema_url = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url"] + self.schema_host = self.config.config["schema_versions"][ + self.schema_version + ]["schema_url_host"] return # All checks passed - We have found a specified schema version! @@ -116,60 +172,92 @@ def __work_out_schema_version( ] def get_entity_statement_types_list(self): - for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: - if ( - statement_schema["properties"]["statementType"]["enum"][0] - == "entityStatement" - ): - return statement_schema["properties"]["entityType"]["enum"] + if self.is_schema_version_equal_to_or_less_than("0.3"): + for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: + if ( + statement_schema["properties"]["statementType"]["enum"][0] + == "entityStatement" + ): + return statement_schema["properties"]["entityType"]["enum"] + else: + entity_schema = get_scheme_file_data(self.pkg_schema_url, "entity") + return entity_schema["properties"]["entityType"]["properties"]["type"][ + "enum" + ] def get_person_statement_types_list(self): - for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: - if ( - statement_schema["properties"]["statementType"]["enum"][0] - == "personStatement" - ): - return statement_schema["properties"]["personType"]["enum"] + if self.is_schema_version_equal_to_or_less_than("0.3"): + for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: + if ( + statement_schema["properties"]["statementType"]["enum"][0] + == "personStatement" + ): + return statement_schema["properties"]["personType"]["enum"] + else: + person_schema = get_scheme_file_data(self.pkg_schema_url, "person") + return person_schema["properties"]["personType"]["enum"] def get_ownership_or_control_statement_interest_statement_types_list(self): - for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: - if ( - statement_schema["properties"]["statementType"]["enum"][0] - == "ownershipOrControlStatement" - ): - return statement_schema["properties"]["interests"]["items"][ - "properties" - ]["type"]["enum"] + if self.is_schema_version_equal_to_or_less_than("0.3"): + for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: + if ( + statement_schema["properties"]["statementType"]["enum"][0] + == "ownershipOrControlStatement" + ): + return statement_schema["properties"]["interests"]["items"][ + "properties" + ]["type"]["enum"] + else: + relationship_schema = get_scheme_file_data( + self.pkg_schema_url, "relationship" + ) + return relationship_schema["$defs"]["Interest"]["properties"]["type"][ + "enum" + ] def get_ownership_or_control_statement_interest_direct_or_indirect_list(self): - for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: - if ( - statement_schema["properties"]["statementType"]["enum"][0] - == "ownershipOrControlStatement" - ): - direct_or_indirect_json_schema = statement_schema["properties"][ - "interests" - ]["items"]["properties"].get("directOrIndirect") - # This is only available in 0.3 and above. - if isinstance(direct_or_indirect_json_schema, dict): - return direct_or_indirect_json_schema.get("enum") - else: - return [] + if self.is_schema_version_equal_to_or_less_than("0.3"): + for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: + if ( + statement_schema["properties"]["statementType"]["enum"][0] + == "ownershipOrControlStatement" + ): + direct_or_indirect_json_schema = statement_schema["properties"][ + "interests" + ]["items"]["properties"].get("directOrIndirect") + # This is only available in 0.3 and above. + if isinstance(direct_or_indirect_json_schema, dict): + return direct_or_indirect_json_schema.get("enum") + else: + return [] + else: + relationship_schema = get_scheme_file_data( + self.pkg_schema_url, "relationship" + ) + return relationship_schema["$defs"]["Interest"]["properties"][ + "directOrIndirect" + ]["enum"] def get_person_statement_political_exposure_status_list(self): - for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: - if ( - statement_schema["properties"]["statementType"]["enum"][0] - == "personStatement" - ): - political_exposure_schema = statement_schema["properties"].get( - "politicalExposure" - ) - # This is only available in 0.3 and above. - if isinstance(political_exposure_schema, dict): - return political_exposure_schema["properties"]["status"]["enum"] - else: - return [] + if self.is_schema_version_equal_to_or_less_than("0.3"): + for statement_schema in self._pkg_schema_obj["items"]["oneOf"]: + if ( + statement_schema["properties"]["statementType"]["enum"][0] + == "personStatement" + ): + political_exposure_schema = statement_schema["properties"].get( + "politicalExposure" + ) + # This is only available in 0.3 and above. + if isinstance(political_exposure_schema, dict): + return political_exposure_schema["properties"]["status"]["enum"] + else: + return [] + else: + person_schema = get_scheme_file_data(self.pkg_schema_url, "person") + return person_schema["properties"]["politicalExposure"]["properties"][ + "status" + ]["enum"] def get_inconsistent_schema_version_used_for_statement(self, statement): # If version is not set at all, then we assume it's the default version @@ -201,20 +289,44 @@ def is_schema_version_equal_to_or_greater_than(self, version): version ) + def is_schema_version_equal_to_or_less_than(self, version): + return packaging_version.parse(self.schema_version) <= packaging_version.parse( + version + ) + + def is_schema_version_less_than(self, version): + return packaging_version.parse(self.schema_version) <= packaging_version.parse( + version + ) + def get_package_schema_fields(self) -> set: - return set(schema_dict_fields_generator(self._pkg_schema_obj)) + if self.is_schema_version_equal_to_or_greater_than("0.4"): + return set( + schema_dict_fields_generator( + self._pkg_schema_obj.contents("urn:statement"), + registry=self._pkg_schema_obj, + ) + ) + else: + return set(schema_dict_fields_generator(self._pkg_schema_obj)) @cached_property def pkg_schema_str(self): - uri_scheme = urlparse(self.pkg_schema_url).scheme - if uri_scheme == "http" or uri_scheme == "https": - raise NotImplementedError( - "Downloading schema files over HTTP/HTTPS is not supported" - ) + if self.is_schema_version_equal_to_or_greater_than("0.4"): + return "" else: - with open(self.pkg_schema_url) as fp: - return fp.read() + uri_scheme = urlparse(self.pkg_schema_url).scheme + if uri_scheme == "http" or uri_scheme == "https": + raise NotImplementedError( + "Downloading schema files over HTTP/HTTPS is not supported" + ) + else: + with open(self.pkg_schema_url) as fp: + return fp.read() @property def _pkg_schema_obj(self): - return json.loads(self.pkg_schema_str) + if self.is_schema_version_equal_to_or_greater_than("0.4"): + return schema_registry(self.pkg_schema_url) + else: + return json.loads(self.pkg_schema_str) diff --git a/libcovebods/schema_dir.py b/libcovebods/schema_dir.py new file mode 100644 index 0000000..7d67d7d --- /dev/null +++ b/libcovebods/schema_dir.py @@ -0,0 +1,41 @@ +import json +from pathlib import Path + +from jscc.schema import is_json_schema # type: ignore +from jscc.testing.filesystem import walk_json_data # type: ignore +from referencing import Registry, Resource +from referencing.jsonschema import DRAFT202012 + + +def get_schema_paths(schema_dir): + """ + Returns an array of paths, filenames, and contents (parsed JSON) for each of the schema files. + """ + schema_paths = [ + (path, name, data) + for path, name, _, data in walk_json_data(top=schema_dir) + if is_json_schema(data) + ] + return schema_paths + + +def schema_registry(schema_dir): + """ + This loads the BODS schema files into a jsonschema registry, so the + validator can resolve $refs across all of the schema files. + """ + schemas = [] + for _, _, schema in get_schema_paths(schema_dir): + schemas.append( + (schema.get("$id"), Resource(contents=schema, specification=DRAFT202012)) + ) + + registry = Registry().with_resources(schemas) + return registry + + +def get_scheme_file_data(schema_dir, component): + for file_path in Path(schema_dir).glob("*.json"): + if file_path.name.startswith(component): + with open(file_path) as json_file: + return json.load(json_file) diff --git a/libcovebods/tasks/checks.py b/libcovebods/tasks/checks.py index 77af98a..43e5da8 100644 --- a/libcovebods/tasks/checks.py +++ b/libcovebods/tasks/checks.py @@ -1,7 +1,17 @@ +from collections import defaultdict +from datetime import datetime + +import jsonpointer # type: ignore +import pycountry from libcove2.common import get_orgids_prefixes # type: ignore from libcovebods.base_task import AdditionalCheck -from libcovebods.utils import get_year_from_bods_birthdate_or_deathdate +from libcovebods.utils import ( + get_year_from_bods_birthdate_or_deathdate, + numeric_value, + parse_date_field, + sort_by_date, +) class LegacyChecks(AdditionalCheck): @@ -10,6 +20,10 @@ class LegacyChecks(AdditionalCheck): This now only has legacy checks that don't need to store a history. Ones that need to store history are in LegacyChecksNeedingHistory.""" + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_less_than("0.4") + @staticmethod def get_additional_check_types_possible( lib_cove_bods_config, schema_object @@ -30,7 +44,8 @@ def __init__(self, lib_cove_bods_config, schema_object): self.orgids_prefixes = get_orgids_prefixes() def check_entity_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, but this should be evaluated. + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. if not statement.get("statementID"): return identifiers = statement.get("identifiers") @@ -40,7 +55,7 @@ def check_entity_statement_first_pass(self, statement): if ( "scheme" in identifier and identifier["scheme"] - and not identifier["scheme"] in self.orgids_prefixes + and identifier["scheme"] not in self.orgids_prefixes ): self._additional_check_results.append( { @@ -83,7 +98,8 @@ def check_entity_statement_first_pass(self, statement): ) def check_person_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, but this should be evaluated. + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. if not statement.get("statementID"): return if "birthDate" in statement: @@ -151,7 +167,8 @@ def check_person_statement_first_pass(self, statement): ) def check_ownership_or_control_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, but this should be evaluated. + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. if not statement.get("statementID"): return ( @@ -241,6 +258,10 @@ class LegacyChecksNeedingHistory(AdditionalCheck): This now only has legacy checks that need to store a history. Ones that don't need to store history are in LegacyChecks.""" + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_less_than("0.4") + @staticmethod def get_additional_check_types_possible( lib_cove_bods_config, schema_object @@ -270,7 +291,8 @@ def __init__(self, lib_cove_bods_config, schema_object): self.statement_ids_counted = {} def check_entity_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, but this should be evaluated. + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. if not statement.get("statementID"): return self.entity_statements_seen.append(statement.get("statementID")) @@ -290,13 +312,15 @@ def check_entity_statement_first_pass(self, statement): ) def check_person_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, but this should be evaluated. + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. if not statement.get("statementID"): return self.person_statements_seen.append(statement.get("statementID")) def check_ownership_or_control_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, but this should be evaluated. + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. if not statement.get("statementID"): return self.ownership_or_control_statements_seen.append(statement.get("statementID")) @@ -391,7 +415,8 @@ def check_ownership_or_control_statement_first_pass(self, statement): ) def check_entity_statement_second_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, but this should be evaluated. + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. if not statement.get("statementID"): return if ( @@ -420,7 +445,8 @@ def check_entity_statement_second_pass(self, statement): ) def check_person_statement_second_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, but this should be evaluated. + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. if not statement.get("statementID"): return if ( @@ -449,7 +475,8 @@ def check_person_statement_second_pass(self, statement): ) def check_ownership_or_control_statement_second_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, but this should be evaluated. + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. if not statement.get("statementID"): return interested_party = statement.get("interestedParty") @@ -597,7 +624,9 @@ def _add_statement_ids_to_statement_ids_counted(self, statement_ids): class CheckHasPublicListing(AdditionalCheck): @staticmethod def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than("0.3") + return schema_object.is_schema_version_equal_to_or_greater_than( + "0.3" + ) and schema_object.is_schema_version_less_than("0.4") @staticmethod def get_additional_check_types_possible( @@ -619,10 +648,38 @@ def check_entity_statement_first_pass(self, statement): ) +class CheckHasPublicListingRecord(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + @staticmethod + def get_additional_check_types_possible( + lib_cove_bods_config, schema_object + ) -> list: + return ["has_public_listing_information_but_has_public_listing_is_false"] + + def check_entity_statement_first_pass(self, statement): + record = statement.get("recordDetails") + if isinstance(record, dict) and isinstance(record.get("publicListing"), dict): + pl = record.get("publicListing") + if pl.get("companyFilingsURLs") or pl.get("securitiesListings"): + if not pl.get("hasPublicListing"): + self._additional_check_results.append( + { + "type": "has_public_listing_information_but_has_public_listing_is_false", + "statement_type": "entity", + "statement": statement.get("statementId"), + } + ) + + class CheckEntityTypeAndEntitySubtypeAlign(AdditionalCheck): @staticmethod def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than("0.3") + return schema_object.is_schema_version_equal_to_or_greater_than( + "0.3" + ) and schema_object.is_schema_version_less_than("0.4") @staticmethod def get_additional_check_types_possible( @@ -652,7 +709,9 @@ def __init__(self, lib_cove_bods_config, schema_object): @staticmethod def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than("0.3") + return schema_object.is_schema_version_equal_to_or_greater_than( + "0.3" + ) and schema_object.is_schema_version_less_than("0.4") @staticmethod def get_additional_check_types_possible( @@ -663,7 +722,10 @@ def get_additional_check_types_possible( "entity_security_listing_market_identifier_code_set_but_not_operating_market_identifier_code", "entity_security_listing_operating_market_identifier_code_set_but_not_market_identifier_code", ] - if schema_object.is_schema_version_equal_to_or_greater_than("0.3") + if ( + schema_object.is_schema_version_equal_to_or_greater_than("0.3") + and schema_object.is_schema_version_less_than("0.4") + ) else [] ) @@ -695,3 +757,1164 @@ def check_entity_statement_first_pass(self, statement): "statement": statement.get("statementID"), } ) + + +class CheckEntitySecurityListingsMICSCodesRecord(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + @staticmethod + def get_additional_check_types_possible( + lib_cove_bods_config, schema_object + ) -> list: + return ( + [ + "entity_security_listing_market_identifier_code_set_but_not_operating_market_identifier_code", + "entity_security_listing_operating_market_identifier_code_set_but_not_market_identifier_code", + ] + if schema_object.is_schema_version_equal_to_or_greater_than("0.3") + else [] + ) + + def check_entity_statement_first_pass(self, statement): + record = statement.get("recordDetails") + if ( + isinstance(record, dict) + and isinstance(record.get("publicListing"), dict) + and isinstance(record["publicListing"].get("securitiesListings"), list) + ): + for securitiesListing in record["publicListing"].get("securitiesListings"): + if isinstance(securitiesListing, dict): + marketIdentifierCode = securitiesListing.get("marketIdentifierCode") + operatingMarketIdentifierCode = securitiesListing.get( + "operatingMarketIdentifierCode" + ) + if marketIdentifierCode and not operatingMarketIdentifierCode: + self._additional_check_results.append( + { + "type": "entity_security_listing_market_identifier_code_set_but_not_operating_market_identifier_code", + "statement_type": "entity", + "statement": statement.get("statementId"), + } + ) + elif operatingMarketIdentifierCode and not marketIdentifierCode: + self._additional_check_results.append( + { + "type": "entity_security_listing_operating_market_identifier_code_set_but_not_market_identifier_code", + "statement_type": "entity", + "statement": statement.get("statementId"), + } + ) + + +class CheckSourceRetrievedAtFutureDate(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if ( + "source" in statement + and isinstance(statement["source"], dict) + and "retrievedAt" in statement["source"] + and statement["source"]["retrievedAt"] + ): + retrieved_at = parse_date_field(statement["source"]["retrievedAt"]) + if retrieved_at and retrieved_at > datetime.now().date(): + self._additional_check_results.append( + { + "type": "statement_source_retrieved_at_future_date", + "statement_type": None, + "retrieval_date": str(retrieved_at), + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementDateFutureDate(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if "statementDate" in statement and statement["statementDate"]: + statement_date = parse_date_field(statement["statementDate"]) + if statement_date and statement_date > datetime.now().date(): + self._additional_check_results.append( + { + "type": "statement_date_is_future_date", + "statement_type": None, + "statement_date": str(statement_date), + "statement": statement.get("statementId"), + } + ) + + +class CheckAnnotationCreationDateFutureDate(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if "annotations" in statement and isinstance(statement["annotations"], list): + for annotation in statement["annotations"]: + if ( + isinstance(annotation, dict) + and "creationDate" in annotation + and annotation["creationDate"] + ): + creation_date = parse_date_field(annotation["creationDate"]) + if creation_date and creation_date > datetime.now().date(): + self._additional_check_results.append( + { + "type": "statement_annotation_creation_date_is_future_date", + "statement_type": None, + "creation_date": creation_date.strftime("%Y-%m-%d"), + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementPublicationDateFutureDate(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if ( + "publicationDetails" in statement + and isinstance(statement["publicationDetails"], dict) + and "publicationDate" in statement["publicationDetails"] + and statement["publicationDetails"]["publicationDate"] + ): + publication_date = parse_date_field( + statement["publicationDetails"]["publicationDate"] + ) + if publication_date and publication_date > datetime.now().date(): + self._additional_check_results.append( + { + "type": "statement_publication_date_is_future_date", + "statement_type": None, + "publication_date": publication_date.strftime("%Y-%m-%d"), + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementPersonDateOfDeathSane(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_person_statement_first_pass(self, statement): + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "deathDate" in statement["recordDetails"] + and statement["recordDetails"]["deathDate"] + ): + death_date = parse_date_field(statement["recordDetails"]["deathDate"]) + if death_date: + if ( + death_date > datetime.now().date() + or death_date < datetime.strptime("1800-01-01", "%Y-%m-%d").date() + ): + self._additional_check_results.append( + { + "type": "statement_person_death_date_not_sensible_value", + "statement_type": None, + "death_date": death_date.strftime("%Y-%m-%d"), + "statement": statement.get("statementId"), + } + ) + elif ( + "birthDate" in statement["recordDetails"] + and statement["recordDetails"]["birthDate"] + ): + birth_date = parse_date_field( + statement["recordDetails"]["birthDate"] + ) + if ( + death_date < birth_date + or (death_date - birth_date).days > 43830 + ): + self._additional_check_results.append( + { + "type": "statement_person_death_date_not_sensible_value", + "statement_type": None, + "death_date": death_date.strftime("%Y-%m-%d"), + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementEntityFoundationDissolutionDates(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_entity_statement_first_pass(self, statement): + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "foundingDate" in statement["recordDetails"] + and statement["recordDetails"]["foundingDate"] + and "dissolutionDate" in statement["recordDetails"] + and statement["recordDetails"]["dissolutionDate"] + ): + founding_date = parse_date_field(statement["recordDetails"]["foundingDate"]) + dissolution_date = parse_date_field( + statement["recordDetails"]["dissolutionDate"] + ) + if founding_date > dissolution_date: + self._additional_check_results.append( + { + "type": "statement_entity_dissolution_before_founding_date", + "statement_type": None, + "founding_date": founding_date.strftime("%Y-%m-%d"), + "dissolution_date": dissolution_date.strftime("%Y-%m-%d"), + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementPersonBirthDateSensible(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_person_statement_first_pass(self, statement): + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "birthDate" in statement["recordDetails"] + and statement["recordDetails"]["birthDate"] + ): + birth_date = parse_date_field(statement["recordDetails"]["birthDate"]) + if birth_date: + if birth_date > datetime.now().date(): + self._additional_check_results.append( + { + "type": "statement_person_birth_date_in_future", + "statement_type": None, + "birth_date": birth_date.strftime("%Y-%m-%d"), + "statement": statement.get("statementId"), + } + ) + elif birth_date < datetime.strptime("1800-01-01", "%Y-%m-%d").date(): + self._additional_check_results.append( + { + "type": "statement_person_birth_date_too_far_in_past", + "statement_type": None, + "birth_date": birth_date.strftime("%Y-%m-%d"), + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementRelationshipInterestsStartEndDates(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_ownership_or_control_statement_first_pass(self, statement): + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "interests" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["interests"], list) + ): + for interest in statement["recordDetails"]["interests"]: + if ( + "startDate" in interest + and interest["startDate"] + and "endDate" in interest + and interest["endDate"] + ): + start_date = parse_date_field(interest["startDate"]) + end_date = parse_date_field(interest["endDate"]) + if start_date and end_date: + if start_date > end_date: + self._additional_check_results.append( + { + "type": "statement_relationship_interests_start_after_end_date", + "statement_type": None, + "start_date": start_date.strftime("%Y-%m-%d"), + "end_date": end_date.strftime("%Y-%m-%d"), + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementEntitySecuritiesListingsHasPublicListing(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_entity_statement_first_pass(self, statement): + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "publicListing" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["publicListing"], dict) + and "securitiesListings" in statement["recordDetails"]["publicListing"] + and isinstance( + statement["recordDetails"]["publicListing"]["securitiesListings"], list + ) + and len(statement["recordDetails"]["publicListing"]["securitiesListings"]) + > 0 + ): + if statement["recordDetails"]["publicListing"]["hasPublicListing"] is False: + self._additional_check_results.append( + { + "type": "statement_entity_securities_listings_haspubliclisting_is_false", + "statement_type": None, + "securities_listings": statement["recordDetails"][ + "publicListing" + ]["securitiesListings"], + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementRelationshipInterestsShareValues(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_ownership_or_control_statement_first_pass(self, statement): + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "interests" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["interests"], list) + ): + for interest in statement["recordDetails"]["interests"]: + if "share" in interest and isinstance(interest["share"], dict): + share = interest["share"] + if "exclusiveMinimum" in share and "minimum" in share: + self._additional_check_results.append( + { + "type": "statement_relationship_interests_share_min_and_exclusivemin", + "statement_type": None, + "share": interest["share"], + "statement": statement.get("statementId"), + } + ) + elif "maximum" in share and "exclusiveMaximum" in share: + self._additional_check_results.append( + { + "type": "statement_relationship_interests_share_max_and_exclusivemax", + "statement_type": None, + "share": interest["share"], + "statement": statement.get("statementId"), + } + ) + if "exact" in share and share["exact"]: + if any( + [ + limit in share + for limit in ( + "exclusiveMinimum", + "minimum", + "maximum", + "exclusiveMaximum", + ) + ] + ): + self._additional_check_results.append( + { + "type": "statement_relationship_interests_exact_has_min_max", + "statement_type": None, + "share_exact": share["exact"], + "statement": statement.get("statementId"), + } + ) + return + if ( + ( + "exclusiveMinimum" in share + and numeric_value(share["exclusiveMinimum"]) + ) + or ("minimum" in share and numeric_value(share["minimum"])) + ) and ( + ( + "exclusiveMaximum" in share + and numeric_value(share["exclusiveMaximum"]) + ) + or ("maximum" in share and numeric_value(share["maximum"])) + ): + min_val = ( + float(share["minimum"]) + if "minimum" in share + else float(share["exclusiveMinimum"]) + ) + max_val = ( + float(share["maximum"]) + if "maximum" in share + else float(share["exclusiveMaximum"]) + ) + if not max_val >= min_val: + self._additional_check_results.append( + { + "type": "statement_relationship_interests_not_exact_max_greater_than_min", + "statement_type": None, + "minval": min_val, + "maxval": max_val, + "statement": statement.get("statementId"), + } + ) + elif max_val == min_val: + self._additional_check_results.append( + { + "type": "statement_relationship_interests_exact_max_equals_min", + "statement_type": None, + "minval": min_val, + "maxval": max_val, + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementDeclarationSubject(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._statements = {} + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if "recordId" in statement and "recordType" in statement: + if statement["recordId"] in self._statements: + self._statements[statement["recordId"]].append(statement["recordType"]) + else: + self._statements[statement["recordId"]] = [statement["recordType"]] + + def check_statement_second_pass(self, statement): + if "declarationSubject" in statement: + if statement["declarationSubject"] not in self._statements: + self._additional_check_results.append( + { + "type": "statement_declaration_subject_not_exist", + "statement_type": None, + "declaration_subject": statement["declarationSubject"], + "statement": statement.get("statementId"), + } + ) + else: + for record_type in self._statements[statement["declarationSubject"]]: + if record_type not in ("entity", "person"): + self._additional_check_results.append( + { + "type": "statement_declaration_subject_not_entity_person", + "statement_type": None, + "record_id": statement["declarationSubject"], + "record_type": record_type, + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementIsComponent(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._count = 0 + self._statements = {} + self._components = {} + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if "recordId" in statement: + self._statements[statement["recordId"]] = self._count + self._count += 1 + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "componentRecords" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["componentRecords"], list) + ): + for component_id in statement["recordDetails"]["componentRecords"]: + self._components[component_id] = statement["recordId"] + + def check_statement_second_pass(self, statement): + if ( + "recordId" in statement + and "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "isComponent" in statement["recordDetails"] + ): + if statement["recordDetails"]["isComponent"] is True: + if statement["recordId"] not in self._components or not ( + self._statements[statement["recordId"]] + < self._statements[self._components[statement["recordId"]]] + ): + if "recordType" in statement: + if statement["recordType"] == "entity": + self._additional_check_results.append( + { + "type": "statement_entity_is_component_not_in_component_details", + "statement_type": None, + "statement": statement.get("statementId"), + } + ) + elif statement["recordType"] == "person": + self._additional_check_results.append( + { + "type": "statement_person_is_component_not_in_component_details", + "statement_type": None, + "statement": statement.get("statementId"), + } + ) + elif statement["recordType"] == "relationship": + self._additional_check_results.append( + { + "type": "statement_relationship_is_component_not_in_component_details", + "statement_type": None, + "statement": statement.get("statementId"), + } + ) + + +class CheckStatementDuplicateStatementId(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._count = 0 + self._statements = defaultdict(int) + self._components = {} + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if "statementId" in statement: + self._statements[statement["statementId"]] += 1 + + def check_statement_second_pass(self, statement): + if "statementId" in statement: + if self._statements[statement["statementId"]] > 1: + self._statements[statement["statementId"]] -= 1 + self._additional_check_results.append( + { + "type": "duplicate_statement_id", + "statement_type": None, + "id": statement.get("statementId"), + } + ) + + +class CheckStatementSeries(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._count = 0 + self._series = {} + self._components = {} + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if ( + "recordId" in statement + and "statementDate" in statement + and "statementDate" in statement + and statement["statementDate"] + ): + record_status = statement.get("recordStatus") + record_type = statement.get("recordType") + statement_id = statement.get("statementId") + if statement["recordId"] in self._series: + self._series[statement["recordId"]].append( + [ + statement["statementDate"], + record_status, + record_type, + statement_id, + ] + ) + else: + self._series[statement["recordId"]] = [ + [ + statement["statementDate"], + record_status, + record_type, + statement_id, + ] + ] + + def final_checks(self): + for series in self._series: + sorted_series = sort_by_date(self._series[series], 0) + statuses = [s[1] for s in sorted_series] + types = [s[2] for s in sorted_series] + if len([s for s in statuses if s == "new"]) > 1: + self._additional_check_results.append( + { + "type": "multiple_statements_in_series_with_record_status_new", + "statement_type": None, + "record_id": series, + } + ) + elif "new" in statuses and statuses[0] != "new": + self._additional_check_results.append( + { + "type": "statement_with_record_status_new_must_be_first", + "statement_type": None, + "record_id": series, + "statement_id": sorted_series[0][-1], + } + ) + elif len([s for s in statuses if s == "closed"]) > 1: + self._additional_check_results.append( + { + "type": "multiple_statements_in_series_with_record_status_closed", + "statement_type": None, + "record_id": series, + } + ) + elif "closed" in statuses and statuses[-1] != "closed": + self._additional_check_results.append( + { + "type": "statement_with_record_status_closed_must_be_last", + "statement_type": None, + "record_id": series, + "statement_id": sorted_series[0][-1], + } + ) + elif len(set(types)) > 1: + self._additional_check_results.append( + { + "type": "statements_in_series_with_different_record_types", + "statement_type": None, + "record_id": series, + } + ) + + +class CheckComponentRecordsRecordIds(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._records = {} + self._statements = {} + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if "recordId" in statement: + self._records[statement["recordId"]] = None + if "statementId" in statement: + self._records[statement["statementId"]] = None + + def check_ownership_or_control_statement_second_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + if "componentRecords" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["componentRecords"], list + ): + for component in statement["recordDetails"]["componentRecords"]: + if component not in self._records: + if component in self._statements: + self._additional_check_results.append( + { + "type": "component_record_is_statement_id", + "statement_type": None, + "statement": statement.get("statementId"), + "compoment_id": component, + } + ) + else: + self._additional_check_results.append( + { + "type": "component_record_id_not_in_dataset", + "statement_type": None, + "statement": statement.get("statementId"), + "compoment_id": component, + } + ) + + +class CheckStatementRelationshipParties(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._records = {} + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if "recordId" in statement: + record_type = statement.get("recordType") + self._records[statement["recordId"]] = record_type + + def check_ownership_or_control_statement_second_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + if "subject" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["subject"], str + ): + if statement["recordDetails"]["subject"] not in self._records: + self._additional_check_results.append( + { + "type": "subject_must_be_record_id", + "statement_type": None, + "statement": statement.get("statementId"), + "subject": statement["recordDetails"]["subject"], + } + ) + elif ( + not self._records[statement["recordDetails"]["subject"]] == "entity" + ): + self._additional_check_results.append( + { + "type": "subject_can_only_refer_to_entity", + "statement_type": None, + "statement": statement.get("statementId"), + "subject": statement["recordDetails"]["subject"], + } + ) + if "interestedParty" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["interestedParty"], str + ): + if statement["recordDetails"]["interestedParty"] not in self._records: + self._additional_check_results.append( + { + "type": "interested_party_must_be_record_id", + "statement_type": None, + "statement": statement.get("statementId"), + "interested_party": statement["recordDetails"][ + "interestedParty" + ], + } + ) + elif self._records[ + statement["recordDetails"]["interestedParty"] + ] not in ("entity", "person"): + self._additional_check_results.append( + { + "type": "interested_party_can_only_refer_to_entity_or_person", + "statement_type": None, + "statement": statement.get("statementId"), + "interested_party": statement["recordDetails"][ + "interestedParty" + ], + } + ) + else: + if "interests" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["interests"], list + ): + for interest in statement["recordDetails"]["interests"]: + if ( + "beneficialOwnershipOrControl" in interest + and interest["beneficialOwnershipOrControl"] is True + ): + if ( + not self._records[ + statement["recordDetails"]["interestedParty"] + ] + == "person" + ): + self._additional_check_results.append( + { + "type": "interest_beneficial_ownership_interested_party_not_person", + "statement_type": None, + "statement": statement.get("statementId"), + "interested_party": statement[ + "recordDetails" + ]["interestedParty"], + } + ) + + +class CheckAnnotationStatementPointerTarget(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_entity_statement_first_pass(self, statement): + if "annotations" in statement and isinstance(statement["annotations"], list): + for annotation in statement["annotations"]: + if "statementPointerTarget" in annotation: + try: + jsonpointer.resolve_pointer( + statement, annotation["statementPointerTarget"] + ) + except (jsonpointer.JsonPointerException, TypeError): + self._additional_check_results.append( + { + "type": "annotation_statement_pointer_target_invalid", + "statement_type": None, + "statement": statement.get("statementId"), + "pointer": annotation["statementPointerTarget"], + } + ) + + +class CheckStatementRelationshipInterests(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._records = {} + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if ( + "recordId" in statement + and "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + ): + record_type = statement.get("recordType") + if record_type == "entity": + record_type_type = statement["recordDetails"].get("entityType") + elif record_type == "person": + record_type_type = statement["recordDetails"].get("personType") + else: + record_type_type = None + self._records[statement["recordId"]] = (record_type, record_type_type) + + def check_ownership_or_control_statement_second_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + if "interests" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["interests"], list + ): + for interest in statement["recordDetails"]["interests"]: + if "type" in interest and interest["type"] in ( + "nominee", + "nominator", + ): + if "subject" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["subject"], str + ): + if ( + not self._records[ + statement["recordDetails"]["subject"] + ][0] + == "entity" + ): + self._additional_check_results.append( + { + "type": "relationship_interests_subject_should_be_entity_nomination_arrangement", + "statement_type": None, + "statement": statement.get("statementId"), + "subject_record_type": self._records[ + statement["recordDetails"]["subject"] + ][0], + "subject_record_subtype": self._records[ + statement["recordDetails"]["subject"] + ][1], + } + ) + else: + entity_type = self._records[ + statement["recordDetails"]["subject"] + ][1] + if ( + not entity_type + or not isinstance(statement["recordDetails"], dict) + or "type" not in entity_type + or not entity_type["type"] == "arrangement" + or "subtype" not in entity_type + or not entity_type["subtype"] == "nomination" + ): + self._additional_check_results.append( + { + "type": "relationship_interests_subject_should_be_entity_nomination_arrangement", + "statement_type": None, + "statement": statement.get("statementId"), + "subject_record_type": self._records[ + statement["recordDetails"]["subject"] + ][0], + "subject_record_subtype": self._records[ + statement["recordDetails"]["subject"] + ][1], + } + ) + elif "type" in interest and interest["type"] in ( + "settlor", + "trustee", + "protector", + ): + if "subject" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["subject"], str + ): + if ( + not self._records[ + statement["recordDetails"]["subject"] + ][0] + == "entity" + ): + self._additional_check_results.append( + { + "type": "relationship_interests_subject_should_be_entity_trust", + "statement_type": None, + "statement": statement.get("statementId"), + "subject_record_type": self._records[ + statement["recordDetails"]["subject"] + ][0], + "subject_record_subtype": self._records[ + statement["recordDetails"]["subject"] + ][1], + } + ) + else: + entity_type = self._records[ + statement["recordDetails"]["subject"] + ][1] + if ( + not entity_type + or not isinstance(statement["recordDetails"], dict) + or "subtype" not in entity_type + or not entity_type["subtype"] == "trust" + ): + self._additional_check_results.append( + { + "type": "relationship_interests_subject_should_be_entity_trust", + "statement_type": None, + "statement": statement.get("statementId"), + "subject_record_type": self._records[ + statement["recordDetails"]["subject"] + ][0], + "subject_record_subtype": self._records[ + statement["recordDetails"]["subject"] + ][1], + } + ) + + +class CheckStatementSerialisation(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._count = 0 + self._records = {} + self._components = {} + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_statement_first_pass(self, statement): + if "recordId" in statement: + self._count += 1 + if statement["recordId"] not in self._records: + self._records[statement["recordId"]] = self._count + + def check_ownership_or_control_statement_second_pass(self, statement): + if ( + "recordId" in statement + and "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + ): + if "subject" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["subject"], str + ): + if statement["recordDetails"]["subject"] in self._records: + if ( + self._records[statement["recordDetails"]["subject"]] + > self._records[statement["recordId"]] + ): + self._additional_check_results.append( + { + "type": "relationship_subject_not_before_relationship_in_dataset", + "statement_type": None, + "statement": statement.get("statementId"), + "subject_id": statement["recordDetails"]["subject"], + } + ) + if ( + "recordId" in statement + and "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + ): + if "interestedParty" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["interestedParty"], str + ): + if statement["recordDetails"]["interestedParty"] in self._records: + if ( + self._records[statement["recordDetails"]["interestedParty"]] + > self._records[statement["recordId"]] + ): + self._additional_check_results.append( + { + "type": "relationship_interested_party_not_before_relationship_in_dataset", + "statement_type": None, + "statement": statement.get("statementId"), + "interested_party_id": statement["recordDetails"][ + "interestedParty" + ], + } + ) + + +class CheckStatementPersonIdentifiersHaveCorrectScheme(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._count = 0 + self._records = {} + self._components = {} + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_person_statement_first_pass(self, statement): + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "identifiers" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["identifiers"], list) + ): + for identifier in statement["recordDetails"]["identifiers"]: + if not ( + "scheme" in identifier + and identifier["scheme"].count("-") == 1 + and len(identifier["scheme"].split("-")[0]) > 0 + and len(identifier["scheme"].split("-")[1]) > 0 + ): + self._additional_check_results.append( + { + "type": "person_identifiers_invalid_composition", + "statement_type": None, + "statement": statement.get("statementId"), + "scheme": identifier["scheme"] + if "scheme" in identifier + else None, + } + ) + else: + other_codes = ( + "BAH", + "D", + "EUE", + "GBD", + "GBN", + "GBO", + "GBP", + "GBS", + "UNA", + "UNK", + "UNO", + "XBA", + "XIM", + "XCC", + "XCO", + "XEC", + "XPO", + "XOM", + "XXA", + "XXB", + "XXC", + "XXX", + "ZIM", + ) + if ( + not pycountry.countries.get( + alpha_3=identifier["scheme"].split("-")[0] + ) + and identifier["scheme"].split("-")[0] not in other_codes + ): + self._additional_check_results.append( + { + "type": "person_identifiers_no_valid_iso_3166_1_alpha_3_code", + "statement_type": None, + "statement": statement.get("statementId"), + "scheme": identifier["scheme"], + } + ) + elif identifier["scheme"].split("-")[1] not in ( + "PASSPORT", + "TAXID", + "IDCARD", + ): + self._additional_check_results.append( + { + "type": "person_identifiers_not_passport_taxid_idcard", + "statement_type": None, + "statement": statement.get("statementId"), + "scheme": identifier["scheme"], + } + ) + + +class CheckStatementEntityIdentifiersHaveKnownScheme(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.orgids_prefixes = get_orgids_prefixes() + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def check_entity_statement_first_pass(self, statement): + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "identifiers" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["identifiers"], list) + ): + for identifier in statement["recordDetails"]["identifiers"]: + if ( + "scheme" in identifier + and not identifier["scheme"] in self.orgids_prefixes + ): + self._additional_check_results.append( + { + "type": "entity_identifiers_not_known_scheme", + "statement_type": None, + "statement": statement.get("statementId"), + "scheme": identifier["scheme"] + if "scheme" in identifier + else None, + } + ) diff --git a/libcovebods/tasks/statistics.py b/libcovebods/tasks/statistics.py index 090987d..43003b8 100644 --- a/libcovebods/tasks/statistics.py +++ b/libcovebods/tasks/statistics.py @@ -4,14 +4,13 @@ from libcovebods.utils import is_interest_current -class LegacyStatistics(AdditionalCheck): - """Before the AdditionalCheck system was implemented, all this code was together in one class. - As we work on statistics in this class, we should move them to seperate classes if possible.""" +class StatisticsCountEntityStatements(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_less_than("0.3") def __init__(self, lib_cove_bods_config, schema_object): super().__init__(lib_cove_bods_config, schema_object) - - # Entity self.count_entity_statements = 0 self.count_entity_statements_types = {} for value in schema_object.get_entity_statement_types_list(): @@ -22,36 +21,6 @@ def __init__(self, lib_cove_bods_config, schema_object): self.count_entity_statements_types_with_any_identifier_with_id_and_scheme = ( self.count_entity_statements_types.copy() ) - # People - self.count_person_statements = 0 - self.count_person_statements_types = {} - for value in schema_object.get_person_statement_types_list(): - self.count_person_statements_types[value] = 0 - # Ownership or control - self.count_ownership_or_control_statement = 0 - self.count_ownership_or_control_statement_interested_party_with_person = 0 - self.count_ownership_or_control_statement_interested_party_with_entity = 0 - self.count_ownership_or_control_statement_interested_party_with_unspecified = 0 - self.count_ownership_or_control_statement_interest_statement_types = {} - for ( - value - ) in ( - schema_object.get_ownership_or_control_statement_interest_statement_types_list() - ): - self.count_ownership_or_control_statement_interest_statement_types[ - value - ] = 0 - self.count_ownership_or_control_statement_by_year = defaultdict(int) - self.subject_statement_ids_by_year = defaultdict(set) - self.count_ownership_or_control_statement_interested_party_with_entity_by_year = defaultdict( - int - ) - self.count_ownership_or_control_statement_interested_party_with_person_by_year = defaultdict( - int - ) - self.count_ownership_or_control_statement_interested_party_with_unspecified_by_year = defaultdict( - int - ) def check_entity_statement_first_pass(self, statement): self.count_entity_statements += 1 @@ -88,6 +57,98 @@ def check_entity_statement_first_pass(self, statement): statement["entityType"] ] += 1 + def get_statistics(self): + data = { + "count_entity_statements": self.count_entity_statements, + "count_entity_statements_types": self.count_entity_statements_types, + "count_entity_statements_types_with_any_identifier": self.count_entity_statements_types_with_any_identifier, + "count_entity_statements_types_with_any_identifier_with_id_and_scheme": self.count_entity_statements_types_with_any_identifier_with_id_and_scheme, + } + return data + + +class StatisticsCountEntityRecordStatements(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.count_entity_statements = 0 + self.count_entity_statements_types = {} + for value in schema_object.get_entity_statement_types_list(): + self.count_entity_statements_types[value] = 0 + self.count_entity_statements_types_with_any_identifier = ( + self.count_entity_statements_types.copy() + ) + self.count_entity_statements_types_with_any_identifier_with_id_and_scheme = ( + self.count_entity_statements_types.copy() + ) + + def check_entity_statement_first_pass(self, statement): + self.count_entity_statements += 1 + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "entityType" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["entityType"], dict) + and "type" in statement["recordDetails"]["entityType"] + and isinstance(statement["recordDetails"]["entityType"]["type"], str) + and statement["recordDetails"]["entityType"]["type"] + in self.count_entity_statements_types + ): + self.count_entity_statements_types[ + statement["recordDetails"]["entityType"]["type"] + ] += 1 + if "identifiers" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["identifiers"], list + ): + has_ids = False + has_ids_with_id_and_scheme = False + for identifier in statement["recordDetails"]["identifiers"]: + if isinstance(identifier, dict): + has_ids = True + if ( + "scheme" in identifier + and isinstance(identifier["scheme"], str) + and identifier["scheme"] + and "id" in identifier + and isinstance(identifier["id"], str) + and identifier["id"] + ): + has_ids_with_id_and_scheme = True + + if has_ids: + self.count_entity_statements_types_with_any_identifier[ + statement["recordDetails"]["entityType"]["type"] + ] += 1 + if has_ids_with_id_and_scheme: + self.count_entity_statements_types_with_any_identifier_with_id_and_scheme[ + statement["recordDetails"]["entityType"]["type"] + ] += 1 + + def get_statistics(self): + data = { + "count_entity_statements": self.count_entity_statements, + "count_entity_statements_types": self.count_entity_statements_types, + "count_entity_statements_types_with_any_identifier": self.count_entity_statements_types_with_any_identifier, + "count_entity_statements_types_with_any_identifier_with_id_and_scheme": self.count_entity_statements_types_with_any_identifier_with_id_and_scheme, + } + return data + + +class StatisticsCountPersonStatements(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_less_than("0.3") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.count_person_statements = 0 + self.count_person_statements_types = {} + for value in schema_object.get_person_statement_types_list(): + self.count_person_statements_types[value] = 0 + def check_person_statement_first_pass(self, statement): self.count_person_statements += 1 if ( @@ -97,6 +158,80 @@ def check_person_statement_first_pass(self, statement): ): self.count_person_statements_types[statement["personType"]] += 1 + def get_statistics(self): + data = { + "count_person_statements": self.count_person_statements, + "count_person_statements_types": self.count_person_statements_types, + } + return data + + +class StatisticsCountPersonRecordStatements(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.count_person_statements = 0 + self.count_person_statements_types = {} + for value in schema_object.get_person_statement_types_list(): + self.count_person_statements_types[value] = 0 + + def check_person_statement_first_pass(self, statement): + self.count_person_statements += 1 + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "personType" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["personType"], str) + and statement["recordDetails"]["personType"] + in self.count_person_statements_types + ): + self.count_person_statements_types[ + statement["recordDetails"]["personType"] + ] += 1 + + def get_statistics(self): + data = { + "count_person_statements": self.count_person_statements, + "count_person_statements_types": self.count_person_statements_types, + } + return data + + +class StatisticsCountOwnershipOrControlStatements(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_less_than("0.3") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.count_ownership_or_control_statement = 0 + self.count_ownership_or_control_statement_interested_party_with_person = 0 + self.count_ownership_or_control_statement_interested_party_with_entity = 0 + self.count_ownership_or_control_statement_interested_party_with_unspecified = 0 + self.count_ownership_or_control_statement_interest_statement_types = {} + for ( + value + ) in ( + schema_object.get_ownership_or_control_statement_interest_statement_types_list() + ): + self.count_ownership_or_control_statement_interest_statement_types[ + value + ] = 0 + self.count_ownership_or_control_statement_by_year = defaultdict(int) + self.subject_statement_ids_by_year = defaultdict(set) + self.count_ownership_or_control_statement_interested_party_with_entity_by_year = defaultdict( + int + ) + self.count_ownership_or_control_statement_interested_party_with_person_by_year = defaultdict( + int + ) + self.count_ownership_or_control_statement_interested_party_with_unspecified_by_year = defaultdict( + int + ) + def check_ownership_or_control_statement_first_pass(self, statement): try: year = int(statement.get("statementDate", "").split("-")[0]) @@ -156,12 +291,6 @@ def check_ownership_or_control_statement_first_pass(self, statement): def get_statistics(self): data = { - "count_entity_statements": self.count_entity_statements, - "count_entity_statements_types": self.count_entity_statements_types, - "count_entity_statements_types_with_any_identifier": self.count_entity_statements_types_with_any_identifier, - "count_entity_statements_types_with_any_identifier_with_id_and_scheme": self.count_entity_statements_types_with_any_identifier_with_id_and_scheme, - "count_person_statements": self.count_person_statements, - "count_person_statements_types": self.count_person_statements_types, "count_ownership_or_control_statement": self.count_ownership_or_control_statement, "count_ownership_or_control_statement_interested_party_with_person": self.count_ownership_or_control_statement_interested_party_with_person, "count_ownership_or_control_statement_interested_party_with_entity": self.count_ownership_or_control_statement_interested_party_with_entity, @@ -179,9 +308,125 @@ def get_statistics(self): return data +class StatisticsCountOwnershipOrControlRecordStatements(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.entity_record_ids = [] + self.person_record_ids = [] + self.count_ownership_or_control_statement = 0 + self.count_ownership_or_control_statement_interested_party_with_person = 0 + self.count_ownership_or_control_statement_interested_party_with_entity = 0 + self.count_ownership_or_control_statement_interested_party_with_unspecified = 0 + self.count_ownership_or_control_statement_interested_party = 0 + self.count_ownership_or_control_statement_interest_statement_types = {} + for ( + value + ) in ( + schema_object.get_ownership_or_control_statement_interest_statement_types_list() + ): + self.count_ownership_or_control_statement_interest_statement_types[ + value + ] = 0 + self.count_ownership_or_control_statement_by_year = defaultdict(int) + self.subject_statement_ids_by_year = defaultdict(set) + self.count_ownership_or_control_statement_interested_party_by_year = ( + defaultdict(int) + ) + + def check_entity_statement_first_pass(self, statement): + if "recordId" in statement: + self.entity_record_ids.append(statement["recordId"]) + + def check_person_statement_first_pass(self, statement): + if "recordId" in statement: + self.person_record_ids.append(statement["recordId"]) + + def check_ownership_or_control_statement_first_pass(self, statement): + try: + year = int(statement.get("statementDate", "").split("-")[0]) + except (ValueError, AttributeError): + year = None + self.count_ownership_or_control_statement += 1 + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + interested_party = statement["recordDetails"].get("interestedParty") + if interested_party: + self.count_ownership_or_control_statement_interested_party += 1 + self.count_ownership_or_control_statement_interested_party_by_year[ + year + ] += 1 + if "interests" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["interests"], list + ): + for interest in statement["recordDetails"]["interests"]: + if isinstance(interest, dict): + if ( + "type" in interest + and isinstance(interest["type"], str) + and interest["type"] + in self.count_ownership_or_control_statement_interest_statement_types + ): + self.count_ownership_or_control_statement_interest_statement_types[ + interest["type"] + ] += 1 + if "subject" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["subject"], str + ): + self.subject_statement_ids_by_year[year].add( + statement["recordDetails"]["subject"] + ) + if "statementDate" in statement: + self.count_ownership_or_control_statement_by_year[year] += 1 + + def check_ownership_or_control_statement_second_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + interested_party = statement["recordDetails"].get("interestedParty") + if interested_party: + if interested_party in self.entity_record_ids: + self.count_ownership_or_control_statement_interested_party_with_entity += ( + 1 + ) + if interested_party in self.person_record_ids: + self.count_ownership_or_control_statement_interested_party_with_person += ( + 1 + ) + if isinstance(interested_party, dict): + self.count_ownership_or_control_statement_interested_party_with_unspecified += ( + 1 + ) + + def get_statistics(self): + data = { + "count_ownership_or_control_statement": self.count_ownership_or_control_statement, + "count_ownership_or_control_statement_interested_party_with_person": self.count_ownership_or_control_statement_interested_party_with_person, + "count_ownership_or_control_statement_interested_party_with_entity": self.count_ownership_or_control_statement_interested_party_with_entity, + "count_ownership_or_control_statement_interested_party_with_unspecified": self.count_ownership_or_control_statement_interested_party_with_unspecified, + "count_ownership_or_control_statement_interested_party": self.count_ownership_or_control_statement_interested_party, + "count_ownership_or_control_statement_interest_statement_types": self.count_ownership_or_control_statement_interest_statement_types, + "count_ownership_or_control_statement_by_year": self.count_ownership_or_control_statement_by_year, + "count_ownership_or_control_statement_subject_by_year": { + year: len(year_set) + for year, year_set in self.subject_statement_ids_by_year.items() + }, + "count_ownership_or_control_statement_interested_party_by_year": self.count_ownership_or_control_statement_interested_party_by_year, + } + return data + + class StatisticsCurrentOwnershipOrControlStatementsAndReplacesStatementsMissing( AdditionalCheck ): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_less_than("0.3") + def __init__(self, lib_cove_bods_config, schema_object): super().__init__(lib_cove_bods_config, schema_object) self.count_replaces_statements_missing = 0 @@ -218,6 +463,46 @@ def get_statistics(self): return data +class StatisticsStatementsRecordStatus(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.records = {} + self.missing_new_records = {} + self.current_records_count = 0 + self.missing_new_records_count = 0 + + def check_statement_first_pass(self, statement): + if ( + isinstance(statement.get("recordStatus"), str) + and isinstance(statement.get("recordId"), str) + and statement.get("recordStatus") in ("new", "updated", "closed") + ): + if not statement.get("recordId") in self.records: + if not statement.get("recordStatus") == "new": + self.missing_new_records[statement.get("recordId")] = statement.get( + "statementId" + ) + self.records[statement.get("recordId")] = statement.get("recordStatus") + + def final_checks(self): + for record_id in self.records: + if not self.records[record_id] == "closed": + self.current_records_count += 1 + for record_id in self.missing_new_records: + self.missing_new_records_count += 1 + + def get_statistics(self): + data = { + "count_records_current": self.current_records_count, + "count_new_records_missing": self.missing_new_records_count, + } + return data + + class StatisticAddress(AdditionalCheck): def __init__(self, lib_cove_bods_config, schema_object): super().__init__(lib_cove_bods_config, schema_object) @@ -323,3 +608,26 @@ def get_statistics(self): return { "count_ownership_or_control_statement_with_at_least_one_interest_beneficial": self.stat, } + + +class StatisticDeclarationSubjects(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._declaration_subjects = {} + + def check_statement_first_pass(self, statement): + if ( + "recordId" in statement + and "declarationSubject" in statement + and statement["recordId"] == statement["declarationSubject"] + ): + self._declaration_subjects[statement["recordId"]] = 1 + + def get_statistics(self): + return { + "count_declaration_subjects": len(self._declaration_subjects), + } diff --git a/libcovebods/utils.py b/libcovebods/utils.py index a5d25bd..19c6802 100644 --- a/libcovebods/utils.py +++ b/libcovebods/utils.py @@ -1,4 +1,5 @@ import datetime +import re from dateutil import parser from pytz import UTC @@ -23,3 +24,53 @@ def is_interest_current(interest): return False else: return True + + +def get_statement_type(statement, schema_object): + if schema_object.is_schema_version_equal_to_or_greater_than("0.4"): + record_type = statement.get("recordType") + if record_type: + if record_type == "relationship": + return "ownershipOrControlStatement" + else: + return f"{record_type}Statement" + else: + return None + else: + return statement.get("statementType") + + +def parse_date_field(date_str): + if not isinstance(date_str, str): + return None + elif "-" in date_str or len(date_str) == 4: + if date_str.count("-") < 2: + if re.match(r"^[0-9]{4}$", date_str): + return datetime.datetime.strptime(date_str, "%Y").date() + elif re.match(r"^[0-9]{4}-[0-9]{1,2}$", date_str): + return datetime.datetime.strptime(date_str, "%Y-%m").date() + else: + return datetime.datetime.fromisoformat( + date_str.replace("Z", "+00:00") + ).date() + else: + return None + + +def numeric_value(value): + try: + float(value) + return True + except ValueError: + return False + + +def sort_by_date(list_with_date, index): + out = [] + for item in list_with_date: + date = parse_date_field(item[index]) + if date: + new_item = item.copy() + new_item[index] = date + out.append(new_item) + return sorted(out, key=lambda x: x[index]) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2357282 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,11 @@ +[tool.ruff] +lint.select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "UP", # pyupgrade +] +line-length = 140 diff --git a/setup.py b/setup.py index d8a2669..a204aba 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="libcovebods", - version="0.15.0", + version="0.16.0", author="Open Data Services", author_email="code@opendataservices.coop", url="https://github.com/openownership/lib-cove-bods", @@ -12,18 +12,21 @@ python_requires=">=3.8", install_requires=[ "python-dateutil", - "libcove2", + "libcove2>=0.2.1", "packaging", # Jsonschema 4.10 breaks the message # 'missingPersonType' is a dependency of 'missingPersonReason' # in tests/fixtures/0.1/badfile_all_validation_errors.json - "jsonschema<4.10", + "jsonschema==4.23.0", + "jscc==0.2.4", "pytz", "ijson", # Required for jsonschema to validate URIs "rfc3987", # Required for jsonschema to validate date-time "rfc3339-validator", + "jsonpointer", + "pycountry", ], extras_require={"dev": ["pytest", "flake8", "black==22.3.0", "isort", "mypy"]}, classifiers=[ diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/api.py b/tests/api.py index f5a6ac8..105bb28 100644 --- a/tests/api.py +++ b/tests/api.py @@ -12,9 +12,12 @@ def bods_json_output( file_type=None, json_data=None, lib_cove_bods_config=None, + sample_mode=False, ): # Data Reader - data_reader = libcovebods.data_reader.DataReader(input_file_name) + data_reader = libcovebods.data_reader.DataReader( + input_file_name, sample_mode=sample_mode + ) # classes if not lib_cove_bods_config: diff --git a/tests/fixtures/0.3/has_public_listing_information_but_has_public_listing_is_false_1.json b/tests/fixtures/0.3/has_public_listing_information_but_has_public_listing_is_false_1.json index 4264148..36f99c9 100644 --- a/tests/fixtures/0.3/has_public_listing_information_but_has_public_listing_is_false_1.json +++ b/tests/fixtures/0.3/has_public_listing_information_but_has_public_listing_is_false_1.json @@ -99,4 +99,4 @@ } } } -] \ No newline at end of file +] diff --git a/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-1.json b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-1.json new file mode 100644 index 0000000..ea1be22 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-1.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "annotations":[ + { + "statementPointerTarget": "statementId", + "motivation": "correcting" + } + ], + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-2.json b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-2.json new file mode 100644 index 0000000..6f3bbca --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-2.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "annotations":[ + { + "statementPointerTarget":"/test", + "motivation": "commenting" + } + ], + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-3.json b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-3.json new file mode 100644 index 0000000..3a34d64 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-invalid-3.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "annotations":[ + { + "statementPointerTarget":"/recordDetails/entityType/subtype", + "motivation": "identifying" + } + ], + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-valid-1.json b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-valid-1.json new file mode 100644 index 0000000..fcca510 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-valid-1.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "annotations":[ + { + "statementPointerTarget":"", + "motivation": "commenting" + } + ], + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-valid-2.json b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-valid-2.json new file mode 100644 index 0000000..c0076c7 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/annotiation_statement_pointer_target-valid-2.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "annotations":[ + { + "statementPointerTarget": "/statementId", + "motivation": "correcting" + } + ], + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-invalid-1.json b/tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-invalid-1.json new file mode 100644 index 0000000..264832e --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-invalid-1.json @@ -0,0 +1,45 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "beneficialOwnershipOrControl": true + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-valid-1.json b/tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-valid-1.json new file mode 100644 index 0000000..a9d179c --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-valid-1.json @@ -0,0 +1,43 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "beneficialOwnershipOrControl": true + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-valid-2.json b/tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-valid-2.json new file mode 100644 index 0000000..ed0da59 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/interested_party_person_with_beneficial_ownership_or_control-valid-2.json @@ -0,0 +1,45 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "beneficialOwnershipOrControl": false + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-1.json b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-1.json new file mode 100644 index 0000000..4d9cd32 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-1.json @@ -0,0 +1,43 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "legalEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "trustee" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-2.json b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-2.json new file mode 100644 index 0000000..7633c91 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-2.json @@ -0,0 +1,43 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "settlor" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-3.json b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-3.json new file mode 100644 index 0000000..37a50f9 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-invalid-3.json @@ -0,0 +1,43 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "protector" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-1.json b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-1.json new file mode 100644 index 0000000..810dc02 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-1.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement", + "subtype": "trust" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "settlor" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-2.json b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-2.json new file mode 100644 index 0000000..a274d23 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-2.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "legalEntity", + "subtype": "trust" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "protector" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-3.json b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-3.json new file mode 100644 index 0000000..6738b68 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_for_trusts-valid-3.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "legalEntity", + "subtype": "trust" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "trustee" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-invalid-1.json b/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-invalid-1.json new file mode 100644 index 0000000..24a472d --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-invalid-1.json @@ -0,0 +1,43 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "legalEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "nominee" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-invalid-2.json b/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-invalid-2.json new file mode 100644 index 0000000..d67a46d --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-invalid-2.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement", + "subtype": "trust" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "nominee" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-valid-1.json b/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-valid-1.json new file mode 100644 index 0000000..2308f61 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-valid-1.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement", + "subtype": "nomination" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "nominee" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-valid-2.json b/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-valid-2.json new file mode 100644 index 0000000..1372e07 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/relationship_interest_nominee_or_nominator-valid-2.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement", + "subtype": "nomination" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "type": "nominator" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-invalid-1.json b/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-invalid-1.json new file mode 100644 index 0000000..179962f --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-invalid-1.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "source": { + "retrievedAt": "2099-01-02" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-invalid-2.json b/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-invalid-2.json new file mode 100644 index 0000000..a7f645e --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-invalid-2.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "source": { + "retrievedAt": "2084-01-02T01:01:00Z" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-valid-1.json b/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-valid-1.json new file mode 100644 index 0000000..0e51c0d --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-valid-1.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "source": { + "retrievedAt": "2023-01-02" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-valid-2.json b/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-valid-2.json new file mode 100644 index 0000000..21d1e10 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/retrievedat_not_future_date-valid-2.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "source": { + "retrievedAt": "2017-01-02T01:01:00Z" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-invalid-1.json new file mode 100644 index 0000000..6c4ea22 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-invalid-1.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "annotations":[ + { + "statementPointerTarget":"", + "motivation": "commenting", + "creationDate": "2200-11-02" + } + ], + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-invalid-2.json new file mode 100644 index 0000000..f039b2b --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-invalid-2.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "annotations":[ + { + "statementPointerTarget":"", + "motivation": "commenting", + "creationDate": "2100-11-02T00:00:00Z" + } + ], + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-valid-1.json new file mode 100644 index 0000000..3542afb --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_annotation_creation_date_future_date-valid-1.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "annotations":[ + { + "statementPointerTarget":"", + "motivation": "commenting", + "creationDate": "2022-11-02" + } + ], + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_date_not_future_date-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_date_not_future_date-invalid-1.json new file mode 100644 index 0000000..36245b8 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_date_not_future_date-invalid-1.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2099-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_date_not_future_date-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_date_not_future_date-invalid-2.json new file mode 100644 index 0000000..3b8c66f --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_date_not_future_date-invalid-2.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2099-03-04T12:12:13Z", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_date_not_future_date-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_date_not_future_date-valid-1.json new file mode 100644 index 0000000..c63b767 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_date_not_future_date-valid-1.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_declaration_subject-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_declaration_subject-invalid-1.json new file mode 100644 index 0000000..919929d --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_declaration_subject-invalid-1.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "d123jtcd2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_declaration_subject-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_declaration_subject-invalid-2.json new file mode 100644 index 0000000..aac42f6 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_declaration_subject-invalid-2.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "93b53022ae6a", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_declaration_subject-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_declaration_subject-valid-1.json new file mode 100644 index 0000000..0a8d9df --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_declaration_subject-valid-1.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-invalid-1.json new file mode 100644 index 0000000..f23d9bf --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-invalid-1.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-invalid-2.json new file mode 100644 index 0000000..710cee5 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-invalid-2.json @@ -0,0 +1,51 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-valid-1.json new file mode 100644 index 0000000..0a8d9df --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_duplicate_statement_id-valid-1.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-invalid-1.json new file mode 100644 index 0000000..5c421a8 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-invalid-1.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "foundingDate": "1990-08-21", + "dissolutionDate": "1990-08-01" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-valid-1.json new file mode 100644 index 0000000..fa62ef0 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-valid-1.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "foundingDate": "1990-08-21", + "dissolutionDate": "2010-07-01" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-valid-2.json new file mode 100644 index 0000000..f7b3209 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_foundation_dissolution_dates-valid-2.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "foundingDate": "1990-08-21", + "dissolutionDate": "1990-08-21" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-invalid-1.json new file mode 100644 index 0000000..c6057c2 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-invalid-1.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "identifiers": [ + { + "scheme": "ME-BCE", + "id": "0521.749.43" + } + ] + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-invalid-2.json new file mode 100644 index 0000000..6f94f30 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-invalid-2.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "identifiers": [ + { + "scheme": "", + "id": "0521.749.43" + } + ] + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-valid-1.json new file mode 100644 index 0000000..775a2c9 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_identifier_scheme_known-valid-1.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "identifiers": [ + { + "scheme": "BE-BCE_KBO", + "id": "0521.749.43" + } + ] + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_is_component-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_entity_is_component-invalid-1.json new file mode 100644 index 0000000..e63c245 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_is_component-invalid-1.json @@ -0,0 +1,85 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "4cf2837bd01f", + "05e81af035e4" + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_is_component-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_entity_is_component-invalid-2.json new file mode 100644 index 0000000..01a9f86 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_is_component-invalid-2.json @@ -0,0 +1,86 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "d4ab89ea169a", + "4cf2837bd01f", + "05e81af035e4" + ] + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_is_component-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_entity_is_component-valid-1.json new file mode 100644 index 0000000..26ee2ff --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_is_component-valid-1.json @@ -0,0 +1,86 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "d4ab89ea169a", + "4cf2837bd01f", + "05e81af035e4" + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-invalid-1.json new file mode 100644 index 0000000..19e6ea7 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-invalid-1.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": false, + "securitiesListings": [ + { + "stockExchangeJurisdiction": "GB", + "stockExchangeName": "London stock exchange", + "security":{ + "ticker": "123" + } + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-1.json new file mode 100644 index 0000000..69e575f --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-1.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": false + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-2.json new file mode 100644 index 0000000..ee36222 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-2.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": false, + "securitiesListings": [ + ] + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-3.json b/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-3.json new file mode 100644 index 0000000..50e62c1 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_entity_securities_listings_haspubliclisting_not_false-valid-3.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity", + "publicListing": { + "hasPublicListing": true, + "securitiesListings": [ + { + "stockExchangeJurisdiction": "GB", + "stockExchangeName": "London stock exchange", + "security":{ + "ticker": "123" + } + } + ] + } + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-1.json new file mode 100644 index 0000000..f23d9bf --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-1.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-2.json new file mode 100644 index 0000000..710cee5 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-2.json @@ -0,0 +1,51 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-3.json b/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-3.json new file mode 100644 index 0000000..f69c70e --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-invalid-3.json @@ -0,0 +1,51 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-04-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "legalEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-valid-1.json new file mode 100644 index 0000000..0a8d9df --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_must_have_unique_statement_identifier-valid-1.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-1.json new file mode 100644 index 0000000..b0594ef --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-1.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "2099-01-01" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-2.json new file mode 100644 index 0000000..24e6868 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-2.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "2200" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-3.json b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-3.json new file mode 100644 index 0000000..b77b701 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-3.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1700" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-4.json b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-4.json new file mode 100644 index 0000000..6592906 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-invalid-4.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1685-01" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-valid-1.json new file mode 100644 index 0000000..4f43bd6 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-valid-1.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1997" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-valid-2.json new file mode 100644 index 0000000..9dde259 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_birth_date_sensible-valid-2.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1980-01-02" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-1.json new file mode 100644 index 0000000..eefcac9 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-1.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1992-01-01", + "deathDate":"1990-07" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-2.json new file mode 100644 index 0000000..00ee2d3 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-2.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1800", + "deathDate":"1990-05-01" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-3.json b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-3.json new file mode 100644 index 0000000..43f7bd6 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-3.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "deathDate":"2099-05-01" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-4.json b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-4.json new file mode 100644 index 0000000..8cc450b --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-invalid-4.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "deathDate":"1700" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-valid-1.json new file mode 100644 index 0000000..2d00e1e --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-valid-1.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1992-01-01", + "deathDate":"2024-07" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-valid-2.json new file mode 100644 index 0000000..e05f586 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_date_of_death_sane-valid-2.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "deathDate":"2012-09-01" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-invalid-1.json new file mode 100644 index 0000000..37d1a70 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-invalid-1.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + }, + "identifiers":{ + "id": "test", + "scheme": "GBR--PASSPORT" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-invalid-2.json new file mode 100644 index 0000000..e7e2c34 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-invalid-2.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + }, + "identifiers":{ + "id": "test", + "scheme": "GBRPASSPORT" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-valid-1.json new file mode 100644 index 0000000..09fa6d3 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-valid-1.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + }, + "identifiers":{ + "id": "test", + "scheme": "GBR-TAXID" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-valid-2.json new file mode 100644 index 0000000..83c93d3 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_correct_scheme-valid-2.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + }, + "identifiers":{ + "id": "test", + "scheme": "D-PASSPORT" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-1.json new file mode 100644 index 0000000..8d6ca71 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-1.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [{ + "id": "test", + "scheme": "GBR--PASSPORT" + }] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-2.json new file mode 100644 index 0000000..db9ffa8 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-2.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [{ + "id": "test", + "scheme": "GBRPASSPORT" + }] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-3.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-3.json new file mode 100644 index 0000000..0be2d8e --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-3.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers":[{ + "id": "test", + "scheme": "-PASSPORT" + }] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-4.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-4.json new file mode 100644 index 0000000..637475b --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-4.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [{ + "id": "test", + "scheme": "GB-PASSPORT" + }] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-5.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-5.json new file mode 100644 index 0000000..c63ac5d --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-5.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [{ + "id": "test", + "scheme": "AAA-PASSPORT" + }] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-6.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-6.json new file mode 100644 index 0000000..29e92f6 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-invalid-6.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [{ + "id": "test", + "scheme": "GBR-ID" + }] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-valid-1.json new file mode 100644 index 0000000..78824f3 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-valid-1.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [{ + "id": "test", + "scheme": "GBR-TAXID" + }] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-valid-2.json new file mode 100644 index 0000000..2bfa50f --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_identifiers_have_correct_scheme-valid-2.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [{ + "id": "test", + "scheme": "D-PASSPORT" + }] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_is_component-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_is_component-invalid-1.json new file mode 100644 index 0000000..12ee54b --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_is_component-invalid-1.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "ad3f6c2fcc9e" + ] + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": true, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_is_component-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_person_is_component-invalid-2.json new file mode 100644 index 0000000..6052888 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_is_component-invalid-2.json @@ -0,0 +1,43 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": true, + "personType": "knownPerson" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_is_component-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_is_component-valid-1.json new file mode 100644 index 0000000..ab4d4df --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_is_component-valid-1.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": true, + "personType": "knownPerson" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "c25d4d612c2c" + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_person_sensible_birth_date-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_person_sensible_birth_date-valid-1.json new file mode 100644 index 0000000..93285ba --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_person_sensible_birth_date-valid-1.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1997" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-invalid-1.json new file mode 100644 index 0000000..025203a --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-invalid-1.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "publicationDetails": { + "publicationDate": "2099-01-01", + "bodsVersion": "0.4", + "publisher":{ + "name": "test" + } + }, + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-invalid-2.json new file mode 100644 index 0000000..e79172a --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-invalid-2.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "publicationDetails":{ + "publicationDate": "2110-01-01T12:00:00Z", + "bodsVersion": "0.4", + "publisher":{ + "name": "test" + } + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-valid-1.json new file mode 100644 index 0000000..c13e0c7 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-valid-1.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "publicationDetails": { + "publicationDate": "2023-01-01", + "bodsVersion": "0.4", + "publisher":{ + "name": "test" + } + }, + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-valid-2.json new file mode 100644 index 0000000..7d70388 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_publication_date_future_date-valid-2.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "publicationDetails":{ + "publicationDate": "2021-01-01T12:00:00Z", + "bodsVersion": "0.4", + "publisher":{ + "name": "test" + } + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-invalid-1.json new file mode 100644 index 0000000..38b7f18 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-invalid-1.json @@ -0,0 +1,86 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "860155d1-a4fb-4742-9735-7a7deb899075", + "4cf2837bd01f", + "05e81af035e4" + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-invalid-2.json new file mode 100644 index 0000000..bd33852 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-invalid-2.json @@ -0,0 +1,86 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "d4ab89ea169a", + "123", + "05e81af035e4" + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-valid-1.json new file mode 100644 index 0000000..26ee2ff --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_component_records_are_record_ids-valid-1.json @@ -0,0 +1,86 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "d4ab89ea169a", + "4cf2837bd01f", + "05e81af035e4" + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-invalid-1.json new file mode 100644 index 0000000..31a2232 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-invalid-1.json @@ -0,0 +1,45 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "123", + "interests":[ + { + "beneficialOwnershipOrControl": true + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-invalid-2.json new file mode 100644 index 0000000..a49e8c9 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-invalid-2.json @@ -0,0 +1,63 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "beneficialOwnershipOrControl": true + } + ] + } + }, + { + "statementId": "cd4c52633f6761962e98e1dd9dbf7da7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "93b53022ae6a", + "interests":[ + { + "beneficialOwnershipOrControl": true + } + ] + } + } +] + diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-valid-1.json new file mode 100644 index 0000000..a9d179c --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-valid-1.json @@ -0,0 +1,43 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "beneficialOwnershipOrControl": true + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-valid-2.json new file mode 100644 index 0000000..ed0da59 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interested_party_entity_or_person-valid-2.json @@ -0,0 +1,45 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "beneficialOwnershipOrControl": false + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-1.json new file mode 100644 index 0000000..1396316 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-1.json @@ -0,0 +1,47 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "exact": 88, + "exclusiveMinimum": 12, + "exclusiveMaximum": 95 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-2.json new file mode 100644 index 0000000..55af7de --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-2.json @@ -0,0 +1,47 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "exact": 88, + "minimum": 12, + "maximum": 100 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-3.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-3.json new file mode 100644 index 0000000..55af7de --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-3.json @@ -0,0 +1,47 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "exact": 88, + "minimum": 12, + "maximum": 100 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-4.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-4.json new file mode 100644 index 0000000..338924e --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-4.json @@ -0,0 +1,47 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "minimum": 88, + "exclusiveMaximum":99, + "maximum": 98 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-5.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-5.json new file mode 100644 index 0000000..c79d467 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-5.json @@ -0,0 +1,46 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "minimum": 99, + "maximum": 1 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-6.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-6.json new file mode 100644 index 0000000..7b50351 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-6.json @@ -0,0 +1,46 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "exclusiveMinimum": 99, + "exclusiveMaximum": 1 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-7.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-7.json new file mode 100644 index 0000000..dfa1646 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-7.json @@ -0,0 +1,46 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "minimum": 50, + "exclusiveMaximum": 50 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-8.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-8.json new file mode 100644 index 0000000..e28e3ae --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-invalid-8.json @@ -0,0 +1,46 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "exclusiveMinimum": 50, + "maximum": 50 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-1.json new file mode 100644 index 0000000..c672775 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-1.json @@ -0,0 +1,45 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "exact": 88 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-2.json new file mode 100644 index 0000000..97bab38 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-2.json @@ -0,0 +1,46 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "minimum": 88, + "exclusiveMaximum":99 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-3.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-3.json new file mode 100644 index 0000000..7c2622a --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_share_values-valid-3.json @@ -0,0 +1,46 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "share":{ + "exclusiveMinimum": 88, + "maximum":99 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-invalid-1.json new file mode 100644 index 0000000..d334c65 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-invalid-1.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "startDate": "2020-01-01", + "endDate": "2019-01-01" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-valid-1.json new file mode 100644 index 0000000..c486fd6 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-valid-1.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "startDate": "2019-01-01", + "endDate": "2020-01-01" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-valid-2.json new file mode 100644 index 0000000..4ff1a18 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_interests_start_end_dates-valid-2.json @@ -0,0 +1,44 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests":[ + { + "startDate": "2019-01-01", + "endDate": "2019-01-01" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_is_component-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_is_component-invalid-1.json new file mode 100644 index 0000000..1c98fb9 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_is_component-invalid-1.json @@ -0,0 +1,85 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "d4ab89ea169a", + "05e81af035e4" + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_is_component-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_relationship_is_component-invalid-2.json new file mode 100644 index 0000000..9bd67c2 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_is_component-invalid-2.json @@ -0,0 +1,86 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "d4ab89ea169a", + "4cf2837bd01f", + "05e81af035e4" + ] + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_is_component-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_is_component-valid-1.json new file mode 100644 index 0000000..26ee2ff --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_is_component-valid-1.json @@ -0,0 +1,86 @@ +[ + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "d4ab89ea169a", + "4cf2837bd01f", + "05e81af035e4" + ] + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-invalid-1.json new file mode 100644 index 0000000..e1fc374 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-invalid-1.json @@ -0,0 +1,36 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-invalid-2.json new file mode 100644 index 0000000..2984b66 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-invalid-2.json @@ -0,0 +1,39 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "123", + "interestedParty": "10478c6cf6de" + } + } +] + diff --git a/tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-valid-1.json new file mode 100644 index 0000000..0a8d9df --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_relationship_subject_refers_to_entity_statement-valid-1.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-1.json new file mode 100644 index 0000000..124934c --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-1.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-2.json new file mode 100644 index 0000000..0921fae --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-2.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + }, + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-3.json b/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-3.json new file mode 100644 index 0000000..29b3dfd --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-3.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "10478c6cf6de", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-4.json b/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-4.json new file mode 100644 index 0000000..f5d5fa1 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_serialisation-invalid-4.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_serialisation-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_serialisation-valid-1.json new file mode 100644 index 0000000..0a8d9df --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_serialisation-valid-1.json @@ -0,0 +1,38 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "93b53022ae6a", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_series-invalid-1.json b/tests/fixtures/0.4/additional-checks/statement_series-invalid-1.json new file mode 100644 index 0000000..8415be5 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_series-invalid-1.json @@ -0,0 +1,68 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "afca12b4-b44a-4c74-8ad1-2110e263946f", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-04-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "46c5218d-2e48-4858-adaf-a596848c1de3", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "closed", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "ecdff7a6-e231-42dc-bfcd-7c124c33cd6a", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_series-invalid-2.json b/tests/fixtures/0.4/additional-checks/statement_series-invalid-2.json new file mode 100644 index 0000000..85b7091 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_series-invalid-2.json @@ -0,0 +1,68 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "afca12b4-b44a-4c74-8ad1-2110e263946f", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-04-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "46c5218d-2e48-4858-adaf-a596848c1de3", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "closed", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2022-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "ecdff7a6-e231-42dc-bfcd-7c124c33cd6a", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_series-invalid-3.json b/tests/fixtures/0.4/additional-checks/statement_series-invalid-3.json new file mode 100644 index 0000000..c14c06b --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_series-invalid-3.json @@ -0,0 +1,68 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "afca12b4-b44a-4c74-8ad1-2110e263946f", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-04-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "closed", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "46c5218d-2e48-4858-adaf-a596848c1de3", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "closed", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "ecdff7a6-e231-42dc-bfcd-7c124c33cd6a", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_series-invalid-4.json b/tests/fixtures/0.4/additional-checks/statement_series-invalid-4.json new file mode 100644 index 0000000..0504532 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_series-invalid-4.json @@ -0,0 +1,68 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "afca12b4-b44a-4c74-8ad1-2110e263946f", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-04-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "46c5218d-2e48-4858-adaf-a596848c1de3", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-04-01", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "closed", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "ecdff7a6-e231-42dc-bfcd-7c124c33cd6a", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_series-invalid-5.json b/tests/fixtures/0.4/additional-checks/statement_series-invalid-5.json new file mode 100644 index 0000000..6a32ee3 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_series-invalid-5.json @@ -0,0 +1,26 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "c359f58d2977", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_series-valid-1.json b/tests/fixtures/0.4/additional-checks/statement_series-valid-1.json new file mode 100644 index 0000000..b11cd96 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_series-valid-1.json @@ -0,0 +1,68 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "afca12b4-b44a-4c74-8ad1-2110e263946f", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-04-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "46c5218d-2e48-4858-adaf-a596848c1de3", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "closed", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "ecdff7a6-e231-42dc-bfcd-7c124c33cd6a", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional-checks/statement_series-valid-2.json b/tests/fixtures/0.4/additional-checks/statement_series-valid-2.json new file mode 100644 index 0000000..22eb1d7 --- /dev/null +++ b/tests/fixtures/0.4/additional-checks/statement_series-valid-2.json @@ -0,0 +1,63 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "afca12b4-b44a-4c74-8ad1-2110e263946f", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-04-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "46c5218d-2e48-4858-adaf-a596848c1de3", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "ecdff7a6-e231-42dc-bfcd-7c124c33cd6a", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/additional_fields_1.json b/tests/fixtures/0.4/additional_fields_1.json new file mode 100644 index 0000000..60c42c7 --- /dev/null +++ b/tests/fixtures/0.4/additional_fields_1.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "extratestfield1": "test", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "extratestfield2": "test", + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/additional_fields_2.json b/tests/fixtures/0.4/additional_fields_2.json new file mode 100644 index 0000000..c2dec31 --- /dev/null +++ b/tests/fixtures/0.4/additional_fields_2.json @@ -0,0 +1,34 @@ +[ + { + "statementId": "GB-COH-00844529-noBeneficialOwners-20240918", + "statementDate": "2024-09-18", + "publicationDetails": { + "publicationDate": "2024-09-18", + "bodsVersion": "0.4", + "license": "https://creativecommons.org/publicdomain/zero/1.0/", + "publisher": { + "name": "Open Ownership", + "url": "https://www.openownership.org/" + } + }, + "recordId": "00844529", + "recordType": "relationship", + "recordStatus": "new", + "source": { + "type": [ + "officialRegister" + ], + "url": "https://link-to-source.org/", + "retrievedAt": "2024-09-18" + }, + "declarationSubject": "00844529", + "recordDetails": { + "isComponent": false, + "subject": "00844529", + "interestedParty": { + "reason": "noBeneficialOwners", + "description": "no-individual-or-entity-with-signficant-control" + } + } + } +] diff --git a/tests/fixtures/0.4/basic_1.json b/tests/fixtures/0.4/basic_1.json new file mode 100644 index 0000000..adec741 --- /dev/null +++ b/tests/fixtures/0.4/basic_1.json @@ -0,0 +1,111 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "c359f58d2977", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "10478c6cf6de", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "fbfd0547-d0c6-4a00-b559-5c5e91c34f5c", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "93b53022ae6a", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c359f58d2977", + "interestedParty": "10478c6cf6de", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/basic_with_correct_mic_codes_1.json b/tests/fixtures/0.4/basic_with_correct_mic_codes_1.json new file mode 100644 index 0000000..0134b19 --- /dev/null +++ b/tests/fixtures/0.4/basic_with_correct_mic_codes_1.json @@ -0,0 +1,29 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "marketIdentifierCode": "MIC code", + "operatingMarketIdentifierCode": "MIC code", + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/basic_with_operating_mic_code_missing_1.json b/tests/fixtures/0.4/basic_with_operating_mic_code_missing_1.json new file mode 100644 index 0000000..76c7ce8 --- /dev/null +++ b/tests/fixtures/0.4/basic_with_operating_mic_code_missing_1.json @@ -0,0 +1,28 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "marketIdentifierCode": "MIC code", + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/entity_sub_type_does_align_1.json b/tests/fixtures/0.4/entity_sub_type_does_align_1.json new file mode 100644 index 0000000..f43e9b3 --- /dev/null +++ b/tests/fixtures/0.4/entity_sub_type_does_align_1.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2022-01-08", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement", + "subtype": "trust" + } + } + } +] diff --git a/tests/fixtures/0.4/entity_sub_type_does_not_align_1.json b/tests/fixtures/0.4/entity_sub_type_does_not_align_1.json new file mode 100644 index 0000000..3156f2a --- /dev/null +++ b/tests/fixtures/0.4/entity_sub_type_does_not_align_1.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2022-01-08", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity", + "subtype": "trust" + } + } + } +] diff --git a/tests/fixtures/0.4/entity_type_trust_arrangement.json b/tests/fixtures/0.4/entity_type_trust_arrangement.json new file mode 100644 index 0000000..f43e9b3 --- /dev/null +++ b/tests/fixtures/0.4/entity_type_trust_arrangement.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2022-01-08", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement", + "subtype": "trust" + } + } + } +] diff --git a/tests/fixtures/0.4/entity_type_trust_registeredentity.json b/tests/fixtures/0.4/entity_type_trust_registeredentity.json new file mode 100644 index 0000000..3156f2a --- /dev/null +++ b/tests/fixtures/0.4/entity_type_trust_registeredentity.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2022-01-08", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity", + "subtype": "trust" + } + } + } +] diff --git a/tests/fixtures/0.4/has_public_listing_information_but_has_public_listing_is_false_1.json b/tests/fixtures/0.4/has_public_listing_information_but_has_public_listing_is_false_1.json new file mode 100644 index 0000000..19e6ea7 --- /dev/null +++ b/tests/fixtures/0.4/has_public_listing_information_but_has_public_listing_is_false_1.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": false, + "securitiesListings": [ + { + "stockExchangeJurisdiction": "GB", + "stockExchangeName": "London stock exchange", + "security":{ + "ticker": "123" + } + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_addressType_placeOfBirth.json b/tests/fixtures/0.4/invalid-schema/entity_addressType_placeOfBirth.json new file mode 100644 index 0000000..955e415 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_addressType_placeOfBirth.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "xyz", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "placeOfBirth", + "address": "23 Regent St, London", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_address_country_code_1chars.json b/tests/fixtures/0.4/invalid-schema/entity_address_country_code_1chars.json new file mode 100644 index 0000000..d911432 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_address_country_code_1chars.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "xyz", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "registered", + "address": "23 Regent St, London", + "country": { + "name": "United Kingdon", + "code": "G" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_address_country_code_3chars.json b/tests/fixtures/0.4/invalid-schema/entity_address_country_code_3chars.json new file mode 100644 index 0000000..41416ea --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_address_country_code_3chars.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "xyz", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "registered", + "address": "23 Regent St, London", + "country": { + "name": "United Kingdon", + "code": "GBR" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_address_country_name_not_string.json b/tests/fixtures/0.4/invalid-schema/entity_address_country_name_not_string.json new file mode 100644 index 0000000..a08672e --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_address_country_name_not_string.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "xyz", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "registered", + "address": "23 Regent St, London", + "country": { + "name": false, + "code": "GB" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_address_country_no_name.json b/tests/fixtures/0.4/invalid-schema/entity_address_country_no_name.json new file mode 100644 index 0000000..52a1afe --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_address_country_no_name.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "registered", + "address": "53 Killard, Kilteragh, Dooradoyle, Co. Limerick ", + "postCode": "V94 V3VT", + "country": { + "code": "IE" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_address_country_no_object.json b/tests/fixtures/0.4/invalid-schema/entity_address_country_no_object.json new file mode 100644 index 0000000..e4250ef --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_address_country_no_object.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "registered", + "address": "53 Killard, Kilteragh, Dooradoyle, Co. Limerick ", + "postCode": "V94 V3VT", + "country": "IE" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_address_not_string.json b/tests/fixtures/0.4/invalid-schema/entity_address_not_string.json new file mode 100644 index 0000000..f331a01 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_address_not_string.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "registered", + "address": 98745672435 + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_addresses_not_array.json b/tests/fixtures/0.4/invalid-schema/entity_addresses_not_array.json new file mode 100644 index 0000000..f2dc55a --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_addresses_not_array.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses":{ + "type": "business", + "address": "23 Regent St, London" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_addresses_not_object.json b/tests/fixtures/0.4/invalid-schema/entity_addresses_not_object.json new file mode 100644 index 0000000..54dc4bf --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_addresses_not_object.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + "23 Regent St, London" + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_addresses_type.json b/tests/fixtures/0.4/invalid-schema/entity_addresses_type.json new file mode 100644 index 0000000..c2b8a7e --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_addresses_type.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "nonsense", + "address": "23 Regent St, London" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_alternate_names_not_array.json b/tests/fixtures/0.4/invalid-schema/entity_alternate_names_not_array.json new file mode 100644 index 0000000..dc37769 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_alternate_names_not_array.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "alternateNames": "Fermentcat Ltd" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_alternate_names_not_strings.json b/tests/fixtures/0.4/invalid-schema/entity_alternate_names_not_strings.json new file mode 100644 index 0000000..9272663 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_alternate_names_not_strings.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "alternateNames": [ + 11 + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_dissolution_date_number.json b/tests/fixtures/0.4/invalid-schema/entity_dissolution_date_number.json new file mode 100644 index 0000000..b3bef52 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_dissolution_date_number.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "dissolutionDate": 2019 + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_dissolution_date_string.json b/tests/fixtures/0.4/invalid-schema/entity_dissolution_date_string.json new file mode 100644 index 0000000..f7428e0 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_dissolution_date_string.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "dissolutionDate": "not a date" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_date_number.json b/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_date_number.json new file mode 100644 index 0000000..cb31165 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_date_number.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody" + }, + "formedByStatute": { + "date": 2019 + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_date_year_only.json b/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_date_year_only.json new file mode 100644 index 0000000..887b9fe --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_date_year_only.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody" + }, + "formedByStatute": { + "date": "2019" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_name_number.json b/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_name_number.json new file mode 100644 index 0000000..53beabd --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_name_number.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody" + }, + "formedByStatute": { + "name": 123 + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_string.json b/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_string.json new file mode 100644 index 0000000..eeba576 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_formed_by_statute_string.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody" + }, + "formedByStatute": "statute 123" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_founding_date_not_date.json b/tests/fixtures/0.4/invalid-schema/entity_founding_date_not_date.json new file mode 100644 index 0000000..8ae75d7 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_founding_date_not_date.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "foundingDate": "2019" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_founding_date_not_string.json b/tests/fixtures/0.4/invalid-schema/entity_founding_date_not_string.json new file mode 100644 index 0000000..0515b1c --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_founding_date_not_string.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "foundingDate": 2019 + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_identifiers_id_number.json b/tests/fixtures/0.4/invalid-schema/entity_identifiers_id_number.json new file mode 100644 index 0000000..61a7430 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_identifiers_id_number.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "eyh3827439", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "identifiers": [ + { + "schemeName": "Company register, Atlantis", + "id": 2475625 + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_identifiers_no_scheme_info.json b/tests/fixtures/0.4/invalid-schema/entity_identifiers_no_scheme_info.json new file mode 100644 index 0000000..c433a0a --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_identifiers_no_scheme_info.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "eyh3827439", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "identifiers": [ + { + "schemeNam": "Company register, Atlantis", + "id": "2475625" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_identifiers_not_array.json b/tests/fixtures/0.4/invalid-schema/entity_identifiers_not_array.json new file mode 100644 index 0000000..fc0256d --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_identifiers_not_array.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "identifiers": { + "id": "434151", + "scheme": "IE-BAU" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_identifiers_not_objects.json b/tests/fixtures/0.4/invalid-schema/entity_identifiers_not_objects.json new file mode 100644 index 0000000..7587704 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_identifiers_not_objects.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "identifiers": [ + "id" + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_identifiers_schemeName_number.json b/tests/fixtures/0.4/invalid-schema/entity_identifiers_schemeName_number.json new file mode 100644 index 0000000..a184a0f --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_identifiers_schemeName_number.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "eyh3827439", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "identifiers": [ + { + "schemeName": 64732, + "id": "2475625" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_identifiers_uri_format.json b/tests/fixtures/0.4/invalid-schema/entity_identifiers_uri_format.json new file mode 100644 index 0000000..5ae704b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_identifiers_uri_format.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "eyh3827439", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "identifiers": [ + { + "schemeName": "64732", + "id": "2475625", + "uri": "http//www.wrongurl.com" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_isComponent_missing.json b/tests/fixtures/0.4/invalid-schema/entity_isComponent_missing.json new file mode 100644 index 0000000..c2761cf --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_isComponent_missing.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_isComponent_not_boolean.json b/tests/fixtures/0.4/invalid-schema/entity_isComponent_not_boolean.json new file mode 100644 index 0000000..99ecd0c --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_isComponent_not_boolean.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": "false", + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_code_1char.json b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_code_1char.json new file mode 100644 index 0000000..96ed07d --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_code_1char.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "eyh3827439", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "jurisdiction": { + "code": "G", + "name": "United Kingdom" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_code_3chars.json b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_code_3chars.json new file mode 100644 index 0000000..bf55ff8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_code_3chars.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "eyh3827439", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "jurisdiction": { + "code": "GB-SCOTLAND", + "name": "United Kingdom" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_missing_name.json b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_missing_name.json new file mode 100644 index 0000000..11d9273 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_missing_name.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "eyh3827439", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "jurisdiction": { + "code": "GB" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_name_number.json b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_name_number.json new file mode 100644 index 0000000..3a2750c --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_name_number.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "eyh3827439", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "jurisdiction": { + "code": "GB", + "name": 7463 + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_not_object.json b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_not_object.json new file mode 100644 index 0000000..ec75843 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_jurisdiction_not_object.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "jurisdiction": "Ireland" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_missing_declarationSubject.json b/tests/fixtures/0.4/invalid-schema/entity_missing_declarationSubject.json new file mode 100644 index 0000000..35a59dd --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_missing_declarationSubject.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_name_not_string.json b/tests/fixtures/0.4/invalid-schema/entity_name_not_string.json new file mode 100644 index 0000000..a2de7f8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_name_not_string.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": 12 + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_postcode_not_string.json b/tests/fixtures/0.4/invalid-schema/entity_postcode_not_string.json new file mode 100644 index 0000000..91ca229 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_postcode_not_string.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "registered", + "postCode": 98745672435 + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_array.json b/tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_array.json new file mode 100644 index 0000000..2dee9aa --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_array.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": false, + "companyFilingsURLs": "https://www.test.org" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_string.json b/tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_string.json new file mode 100644 index 0000000..98a000d --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_string.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": false, + "companyFilingsURLs": [ + 11 + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_uri.json b/tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_uri.json new file mode 100644 index 0000000..417eea8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_public_listing_company_filings_not_uri.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": false, + "companyFilingsURLs": [ + "www.test.org" + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_public_listing_has_public_listing_missing.json b/tests/fixtures/0.4/invalid-schema/entity_public_listing_has_public_listing_missing.json new file mode 100644 index 0000000..ed920f3 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_public_listing_has_public_listing_missing.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "companyFilingsURLs": [ + "http://www.test.com" + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_public_listing_has_public_listing_not_bool.json b/tests/fixtures/0.4/invalid-schema/entity_public_listing_has_public_listing_not_bool.json new file mode 100644 index 0000000..0aa7ee9 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_public_listing_has_public_listing_not_bool.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": 12 + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_public_listing_not_object.json b/tests/fixtures/0.4/invalid-schema/entity_public_listing_not_object.json new file mode 100644 index 0000000..cab16b9 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_public_listing_not_object.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": true + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_recordDetails_missing_isComponent.json b/tests/fixtures/0.4/invalid-schema/entity_recordDetails_missing_isComponent.json new file mode 100644 index 0000000..385ca46 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_recordDetails_missing_isComponent.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "declarationSubject": "xyz", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_MIC_string.json b/tests/fixtures/0.4/invalid-schema/entity_security_MIC_string.json new file mode 100644 index 0000000..668fc01 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_MIC_string.json @@ -0,0 +1,28 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "marketIdentifierCode": 11, + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_OMIC_string.json b/tests/fixtures/0.4/invalid-schema/entity_security_OMIC_string.json new file mode 100644 index 0000000..3bd0b2c --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_OMIC_string.json @@ -0,0 +1,28 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "operatingMarketIdentifierCode": 11, + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_id_number.json b/tests/fixtures/0.4/invalid-schema/entity_security_id_number.json new file mode 100644 index 0000000..7cab0f8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_id_number.json @@ -0,0 +1,28 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT", + "id": 12345 + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_idscheme_wrong_code.json b/tests/fixtures/0.4/invalid-schema/entity_security_idscheme_wrong_code.json new file mode 100644 index 0000000..c0d63af --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_idscheme_wrong_code.json @@ -0,0 +1,28 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT", + "idScheme": "siin" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_jurisdiction.json b/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_jurisdiction.json new file mode 100644 index 0000000..4e1f49b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_jurisdiction.json @@ -0,0 +1,26 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_security.json b/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_security.json new file mode 100644 index 0000000..9ee2796 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_security.json @@ -0,0 +1,24 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_stock_exchange.json b/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_stock_exchange.json new file mode 100644 index 0000000..29ca09e --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_stock_exchange.json @@ -0,0 +1,26 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT" + }, + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_ticker.json b/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_ticker.json new file mode 100644 index 0000000..f5c63de --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_listing_no_ticker.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "name": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_listing_not_array.json b/tests/fixtures/0.4/invalid-schema/entity_security_listing_not_array.json new file mode 100644 index 0000000..ce4c21d --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_listing_not_array.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": { + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_listing_string.json b/tests/fixtures/0.4/invalid-schema/entity_security_listing_string.json new file mode 100644 index 0000000..9685f57 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_listing_string.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": "FMT", + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_not_string.json b/tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_not_string.json new file mode 100644 index 0000000..a3cc9b1 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_not_string.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": 123 + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_too_long.json b/tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_too_long.json new file mode 100644 index 0000000..dd20d6e --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_too_long.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "1234567" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_too_short.json b/tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_too_short.json new file mode 100644 index 0000000..3a18736 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_stock_jurisdiction_too_short.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "I" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_stock_name_string.json b/tests/fixtures/0.4/invalid-schema/entity_security_stock_name_string.json new file mode 100644 index 0000000..aa15e9b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_stock_name_string.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :true, + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_security_ticker_number.json b/tests/fixtures/0.4/invalid-schema/entity_security_ticker_number.json new file mode 100644 index 0000000..329b08a --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_security_ticker_number.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": 12 + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_statementDate_format.json b/tests/fixtures/0.4/invalid-schema/entity_statementDate_format.json new file mode 100644 index 0000000..0280006 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_statementDate_format.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2020", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_statementDate_missing.json b/tests/fixtures/0.4/invalid-schema/entity_statementDate_missing.json new file mode 100644 index 0000000..2027573 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_statementDate_missing.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_details_number.json b/tests/fixtures/0.4/invalid-schema/entity_type_details_number.json new file mode 100644 index 0000000..81bfa0b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_details_number.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-01-01", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody", + "details": 12 + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_governmentDepartment_arrangement.json b/tests/fixtures/0.4/invalid-schema/entity_type_governmentDepartment_arrangement.json new file mode 100644 index 0000000..2ce7666 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_governmentDepartment_arrangement.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-01-01", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement", + "subtype": "governmentDepartment" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_no_entity_type.json b/tests/fixtures/0.4/invalid-schema/entity_type_no_entity_type.json new file mode 100644 index 0000000..c70add3 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_no_entity_type.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2022-01-08", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_nomination_unknown.json b/tests/fixtures/0.4/invalid-schema/entity_type_nomination_unknown.json new file mode 100644 index 0000000..08f37fa --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_nomination_unknown.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2018-09-01", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "unknownEntity", + "subtype": "nomination" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_not_object.json b/tests/fixtures/0.4/invalid-schema/entity_type_not_object.json new file mode 100644 index 0000000..5e8e58b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_not_object.json @@ -0,0 +1,13 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": "registeredEntity", + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_notype.json b/tests/fixtures/0.4/invalid-schema/entity_type_notype.json new file mode 100644 index 0000000..8c563b5 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_notype.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2022-01-08", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_state_stateAgency.json b/tests/fixtures/0.4/invalid-schema/entity_type_state_stateAgency.json new file mode 100644 index 0000000..c348282 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_state_stateAgency.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-01-01", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "state", + "subtype": "stateAgency" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_subtype_not_codelist.json b/tests/fixtures/0.4/invalid-schema/entity_type_subtype_not_codelist.json new file mode 100644 index 0000000..39ed5df --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_subtype_not_codelist.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity", + "subtype": "listedCompany" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_trust_registeredentity.json b/tests/fixtures/0.4/invalid-schema/entity_type_trust_registeredentity.json new file mode 100644 index 0000000..3156f2a --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_trust_registeredentity.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2022-01-08", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity", + "subtype": "trust" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_type_type_not_codelist.json b/tests/fixtures/0.4/invalid-schema/entity_type_type_not_codelist.json new file mode 100644 index 0000000..ab2e4f3 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_type_type_not_codelist.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "listedCompany" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_description_not_string.json b/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_description_not_string.json new file mode 100644 index 0000000..0fdd0d2 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_description_not_string.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "unknownEntity" + }, + "unspecifiedEntityDetails": { + "reason": "noBeneficialOwners", + "description": true + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_details_not_object.json b/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_details_not_object.json new file mode 100644 index 0000000..ffda607 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_details_not_object.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "unknownEntity" + }, + "unspecifiedEntityDetails": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_no_reason.json b/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_no_reason.json new file mode 100644 index 0000000..b9b8370 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_no_reason.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "unknownEntity" + }, + "unspecifiedEntityDetails": { + "description": "no shareholders with over 10% of shares" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_reason_not_codelist.json b/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_reason_not_codelist.json new file mode 100644 index 0000000..1b91dba --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_unspecified_entity_reason_not_codelist.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "unknownEntity" + }, + "unspecifiedEntityDetails": { + "reason": "noBOs", + "description": "no shareholders with over 10% of shares" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_uri_format.json b/tests/fixtures/0.4/invalid-schema/entity_uri_format.json new file mode 100644 index 0000000..b9fadb3 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_uri_format.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "uri": "example.com/index.html" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/entity_uri_string.json b/tests/fixtures/0.4/invalid-schema/entity_uri_string.json new file mode 100644 index 0000000..602a7a5 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/entity_uri_string.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "uri": true + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/expected_errors.csv b/tests/fixtures/0.4/invalid-schema/expected_errors.csv new file mode 100644 index 0000000..bb954f8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/expected_errors.csv @@ -0,0 +1,192 @@ +entity_missing_declarationSubject.json,required,$[0],declarationSubject +entity_recordDetails_missing_isComponent.json,required,$[0].recordDetails,isComponent +entity_addressType_placeOfBirth.json,enum,$[0].recordDetails.addresses[0].type,type +entity_address_country_no_name.json,required,$[0].recordDetails.addresses[0].country,name +person_addresses_type.json,enum,$[0].recordDetails.addresses[0].type,type +entity_statementDate_format.json,anyOf,$[0].statementDate,statementDate +entity_address_country_no_object.json,type,$[0].recordDetails.addresses[0].country,country +entity_statementDate_missing.json,required,$[0],statementDate +person_addresses_birthplace.json,enum,$[0].recordDetails.addresses[0].type,type +entity_addresses_type.json,enum,$[0].recordDetails.addresses[0].type,type +person_names_patronymic.json,type,$[0].recordDetails.names[0].patronymicName,patronymicName +person_death_date_number.json,type,$[0].recordDetails.deathDate,deathDate +person_birth_date_number.json,type,$[0].recordDetails.birthDate,birthDate +person_names_fullName_missing.json,required,$[0].recordDetails.names[0],fullName +person_taxResidencies_no_object.json,type,$[0].recordDetails.taxResidencies,taxResidencies +person_addresses_no_array.json,type,$[0].recordDetails.addresses,addresses +statement_annotations_statementPointerTarget_type.json,type,$[0].annotations[0].statementPointerTarget,statementPointerTarget +entity_address_not_string.json,type,$[0].recordDetails.addresses[0].address,address +entity_postcode_not_string.json,type,$[0].recordDetails.addresses[0].postCode,postCode +entity_address_country_name_not_string.json,type,$[0].recordDetails.addresses[0].country.name,name +entity_address_country_code_3chars.json,maxLength,$[0].recordDetails.addresses[0].country.code,code +entity_address_country_code_1chars.json,minLength,$[0].recordDetails.addresses[0].country.code,code +entity_jurisdiction_missing_name.json,required,$[0].recordDetails.jurisdiction,name +entity_jurisdiction_name_number.json,type,$[0].recordDetails.jurisdiction.name,name +entity_jurisdiction_code_1char.json,minLength,$[0].recordDetails.jurisdiction.code,code +entity_jurisdiction_code_3chars.json,maxLength,$[0].recordDetails.jurisdiction.code,code +entity_identifiers_id_number.json,type,$[0].recordDetails.identifiers[0].id,id +entity_identifiers_no_scheme_info.json,anyOf,$[0].recordDetails.identifiers[0],scheme +entity_identifiers_schemeName_number.json,type,$[0].recordDetails.identifiers[0].schemeName,schemeName +entity_identifiers_uri_format.json,format,$[0].recordDetails.identifiers[0].uri,uri +statement_annotations_creationDate.json,type,$[0].annotations[0].creationDate,creationDate +statement_annotations_createdBy_no_object.json,type,$[0].annotations[0].createdBy,createdBy +statement_annotations_createdBy_name_string.json,type,$[0].annotations[0].createdBy.name,name +statement_annotations_createdBy_uri.json,format,$[0].annotations[0].createdBy.uri,uri +entity_unspecified_entity_details_not_object.json,type,$[0].recordDetails.unspecifiedEntityDetails,unspecifiedEntityDetails +entity_alternate_names_not_array.json,type,$[0].recordDetails.alternateNames,alternateNames +entity_alternate_names_not_strings.json,type,$[0].recordDetails.alternateNames[0],alternateNames +statement_annotations_motivation_code.json,enum,$[0].annotations[0].motivation,motivation +statement_annotations_description_not_string.json,type,$[0].annotations[0].description,description +statement_annotations_transformedContent_not_string.json,type,$[0].annotations[0].transformedContent,transformedContent +statement_annotations_url_format.json,format,$[0].annotations[0].url,url +statement_annotations_url_linking_missing.json,required,$[0].annotations[0],url +statement_annotations.statementPointerTarget_missing.json,required,$[0].annotations[0],statementPointerTarget +statement_annotations_motivation_missing.json,required,$[0].annotations[0],motivation +person_PepStatusDetails_reason.json,type,$[0].recordDetails.politicalExposure.details[0].reason,reason +person_PepStatusDetails_missingInfoReason_string.json,type,$[0].recordDetails.politicalExposure.details[0].missingInfoReason,missingInfoReason +person_PepStatusDetails_jurisdiction_no_object.json,type,$[0].recordDetails.politicalExposure.details[0].jurisdiction,jurisdiction +person_PepStatusDetails_startDate_string.json,type,$[0].recordDetails.politicalExposure.details[0].startDate,startDate +person_PepStatusDetails_endDate_string.json,type,$[0].recordDetails.politicalExposure.details[0].endDate,endDate +person_PepStatusDetails_source_no_object.json,type,$[0].recordDetails.politicalExposure.details[0].source,source +relationship_interests_exclusive_min_negative.json,minimum,$[0].recordDetails.interests[0].share.exclusiveMinimum,exclusiveMinimum +relationship_interests_exclusive_min_too_big.json,maximum,$[0].recordDetails.interests[0].share.exclusiveMinimum,exclusiveMinimum +relationship_interests_exclusive_max_too_big.json,maximum,$[0].recordDetails.interests[0].share.exclusiveMaximum,exclusiveMaximum +relationship_interests_exclusive_max_negative.json,minimum,$[0].recordDetails.interests[0].share.exclusiveMaximum,exclusiveMaximum +statement_source_type_not_array.json,type,$[0].source.type,type +statement_source_type_code.json,enum,$[0].source.type[0],type +statement_source_description_string.json,type,$[0].source.description,description +statement_source_url.json,format,$[0].source.url,url +statement_source_retrievedAt_date.json,type,$[0].source.retrievedAt,retrievedAt +statement_source_assertedBy_not_array.json,type,$[0].source.assertedBy,assertedBy +statement_source_assertedBy_name_string.json,type,$[0].source.assertedBy[0].name,name +statement_source_assertedBy_uri.json,format,$[0].source.assertedBy[0].uri,uri +entity_dissolution_date_number.json,type,$[0].recordDetails.dissolutionDate,dissolutionDate +entity_dissolution_date_string.json,format,$[0].recordDetails.dissolutionDate,dissolutionDate +entity_type_details_number.json,type,$[0].recordDetails.entityType.details,details +entity_formed_by_statute_string.json,type,$[0].recordDetails.formedByStatute,formedByStatute +entity_formed_by_statute_name_number.json,type,$[0].recordDetails.formedByStatute.name,name +entity_formed_by_statute_date_year_only.json,format,$[0].recordDetails.formedByStatute.date,date +entity_formed_by_statute_date_number.json,type,$[0].recordDetails.formedByStatute.date,date +person_politicalExposure_no_object.json,type,$[0].recordDetails.politicalExposure,politicalExposure +person_politicalExposure_no_status.json,required,$[0].recordDetails.politicalExposure,status +person_politicalExposure_status_code.json,enum,$[0].recordDetails.politicalExposure.status,status +person_politicalExposure_details_not_array.json,type,$[0].recordDetails.politicalExposure.details,details +entity_security_listing_no_jurisdiction.json,required,$[0].recordDetails.publicListing.securitiesListings[0],stockExchangeJurisdiction +entity_security_listing_no_security.json,required,$[0].recordDetails.publicListing.securitiesListings[0],security +entity_security_listing_no_stock_exchange.json,required,$[0].recordDetails.publicListing.securitiesListings[0],stockExchangeName +entity_security_listing_string.json,type,$[0].recordDetails.publicListing.securitiesListings[0].security,security +entity_security_listing_no_ticker.json,required,$[0].recordDetails.publicListing.securitiesListings[0].security,ticker +entity_security_idscheme_wrong_code.json,enum,$[0].recordDetails.publicListing.securitiesListings[0].security.idScheme,idScheme +entity_security_id_number.json,type,$[0].recordDetails.publicListing.securitiesListings[0].security.id,id +entity_security_ticker_number.json,type,$[0].recordDetails.publicListing.securitiesListings[0].security.ticker,ticker +entity_security_MIC_string.json,type,$[0].recordDetails.publicListing.securitiesListings[0].marketIdentifierCode,marketIdentifierCode +entity_security_OMIC_string.json,type,$[0].recordDetails.publicListing.securitiesListings[0].operatingMarketIdentifierCode,operatingMarketIdentifierCode +entity_security_stock_jurisdiction_too_short.json,minLength,$[0].recordDetails.publicListing.securitiesListings[0].stockExchangeJurisdiction,stockExchangeJurisdiction +entity_security_stock_jurisdiction_too_long.json,maxLength,$[0].recordDetails.publicListing.securitiesListings[0].stockExchangeJurisdiction,stockExchangeJurisdiction +entity_security_stock_jurisdiction_not_string.json,type,$[0].recordDetails.publicListing.securitiesListings[0].stockExchangeJurisdiction,stockExchangeJurisdiction +entity_security_stock_name_string.json,type,$[0].recordDetails.publicListing.securitiesListings[0].stockExchangeName,stockExchangeName +statement_statementId_not_string.json,type,$[0].statementId,statementId +statement_statementId_too_short.json,minLength,$[0].statementId,statementId +statement_statementId_too_long.json,maxLength,$[0].statementId,statementId +statement_statementDate_not_string.json,type,$[0].statementDate,statementDate +statement_statementDate_not_date_string.json,anyOf,$[0].statementDate,statementDate +statement_annotations_not_array.json,type,$[0].annotations,annotations +statement_annotations_not_object.json,type,$[0].annotations[0],annotations +publication_details_not_object.json,type,$[0].publicationDetails,publicationDetails +publication_details_date_not_date.json,anyOf,$[0].publicationDetails.publicationDate,publicationDate +publication_details_date_not_string.json,type,$[0].publicationDetails.publicationDate,publicationDate +publication_details_version_not_string.json,type,$[0].publicationDetails.bodsVersion,bodsVersion +publication_details_version_not_version.json,pattern,$[0].publicationDetails.bodsVersion,bodsVersion +publication_details_license_not_string.json,type,$[0].publicationDetails.license,license +publication_details_license_not_uri.json,format,$[0].publicationDetails.license,license +publication_details_publisher_not_object.json,type,$[0].publicationDetails.publisher,publisher +publication_details_publisher_name_not_string.json,type,$[0].publicationDetails.publisher.name,name +publication_details_publisher_url_not_string.json,type,$[0].publicationDetails.publisher.url,url +publication_details_publisher_url_not_uri.json,format,$[0].publicationDetails.publisher.url,url +publication_details_publisher_no_name_url.json,anyOf,$[0].publicationDetails.publisher,publisher +publication_details_publisher_no_publication_date.json,required,$[0].publicationDetails,publicationDate +publication_details_publisher_no_bods_version.json,required,$[0].publicationDetails,bodsVersion +publication_details_publisher_no_publisher.json,required,$[0].publicationDetails,publisher +statement_declaration_not_string.json,type,$[0].declaration,declaration +statement_recordType_code.json,enum,$[0].recordType,recordType +statement_recordStatus_code.json,enum,$[0].recordStatus,recordStatus +statement_recordDetails_no_object.json,type,$[0].recordDetails,recordDetails +statement_statementId_missing.json,required,$[0],statementId +statement_statementDate_missing.json,required,$[0],statementDate +statement_declarationSubject_missing.json,required,$[0],declarationSubject +statement_recordId_missing.json,required,$[0],recordId +statement_recordDetails_missing.json,required,$[0],recordDetails +statement_declarationSubject_string.json,type,$[0].declarationSubject,declarationSubject +statement_recordId_string.json,type,$[0].recordId,recordId +statement_source_no_object.json,type,$[0].source,source +entity_type_trust_registeredentity.json,enum,$[0].recordDetails.entityType.subtype,subtype +entity_type_nomination_unknown.json,enum,$[0].recordDetails.entityType.subtype,subtype +entity_type_state_stateAgency.json,enum,$[0].recordDetails.entityType.subtype,subtype +entity_type_governmentDepartment_arrangement.json,enum,$[0].recordDetails.entityType.subtype,subtype +entity_type_notype.json,required,$[0].recordDetails.entityType,type +entity_type_no_entity_type.json,required,$[0].recordDetails,entityType +entity_name_not_string.json,type,$[0].recordDetails.name,name +entity_jurisdiction_not_object.json,type,$[0].recordDetails.jurisdiction,jurisdiction +entity_identifiers_not_array.json,type,$[0].recordDetails.identifiers,identifiers +entity_identifiers_not_objects.json,type,$[0].recordDetails.identifiers[0],identifiers +entity_founding_date_not_string.json,type,$[0].recordDetails.foundingDate,foundingDate +entity_founding_date_not_date.json,format,$[0].recordDetails.foundingDate,foundingDate +entity_addresses_not_array.json,type,$[0].recordDetails.addresses,addresses +entity_addresses_not_object.json,type,$[0].recordDetails.addresses[0],addresses +entity_public_listing_not_object.json,type,$[0].recordDetails.publicListing,publicListing +entity_type_not_object.json,type,$[0].recordDetails.entityType,entityType +entity_type_type_not_codelist.json,enum,$[0].recordDetails.entityType.type,type +entity_type_subtype_not_codelist.json,enum,$[0].recordDetails.entityType.subtype,subtype +entity_isComponent_missing.json,required,$[0].recordDetails,isComponent +entity_public_listing_has_public_listing_missing.json,required,$[0].recordDetails.publicListing,hasPublicListing +entity_public_listing_has_public_listing_not_bool.json,type,$[0].recordDetails.publicListing.hasPublicListing,hasPublicListing +entity_public_listing_company_filings_not_array.json,type,$[0].recordDetails.publicListing.companyFilingsURLs,companyFilingsURLs +entity_public_listing_company_filings_not_uri.json,format,$[0].recordDetails.publicListing.companyFilingsURLs[0],companyFilingsURLs +entity_public_listing_company_filings_not_string.json,type,$[0].recordDetails.publicListing.companyFilingsURLs[0],companyFilingsURLs +entity_security_listing_not_array.json,type,$[0].recordDetails.publicListing.securitiesListings,securitiesListings +relationship_interests_end_date_string.json,type,$[0].recordDetails.interests[0].endDate,endDate +relationship_interests_end_date_dateformat.json,format,$[0].recordDetails.interests[0].endDate,endDate +relationship_interests_details_string.json,type,$[0].recordDetails.interests[0].details,details +entity_uri_format.json,format,$[0].recordDetails.uri,uri +entity_uri_string.json,type,$[0].recordDetails.uri,uri +entity_unspecified_entity_no_reason.json,required,$[0].recordDetails.unspecifiedEntityDetails,reason +entity_unspecified_entity_reason_not_codelist.json,enum,$[0].recordDetails.unspecifiedEntityDetails.reason,reason +entity_unspecified_entity_description_not_string.json,type,$[0].recordDetails.unspecifiedEntityDetails.description,description +person_iscomponent_not_bool.json,type,$[0].recordDetails.isComponent,isComponent +person_type_not_codelist.json,enum,$[0].recordDetails.personType,personType +person_unspecified_person_details_not_object.json,type,$[0].recordDetails.unspecifiedPersonDetails,unspecifiedPersonDetails +person_names_not_array.json,type,$[0].recordDetails.names,names +person_names_not_objects.json,type,$[0].recordDetails.names[0],names +person_identifiers_not_array.json,type,$[0].recordDetails.identifiers,identifiers +person_identifiers_not_object.json,type,$[0].recordDetails.identifiers[0],identifiers +person_birth_place_not_object.json,type,$[0].recordDetails.placeOfBirth,placeOfBirth +person_type_missing.json,required,$[0].recordDetails,personType +person_isComponent_missing.json,required,$[0].recordDetails,isComponent +person_names_type_code.json,enum,$[0].recordDetails.names[0].type,type +person_names_fullName_string.json,type,$[0].recordDetails.names[0].fullName,fullName +person_names_familyName_string.json,type,$[0].recordDetails.names[0].familyName,familyName +person_names_givenName_string.json,type,$[0].recordDetails.names[0].givenName,givenName +statements_not_array.json,type,$, +entity_isComponent_not_boolean.json,type,$[0].recordDetails.isComponent,isComponent +relationship_isComponent_not_boolean.json,type,$[0].recordDetails.isComponent,isComponent +relationship_interests_no_array.json,type,$[0].recordDetails.interests,interests +relationship_isComponent_missing.json,required,$[0].recordDetails,isComponent +relationship_subject_missing.json,required,$[0].recordDetails,subject +relationship_interestedParty_missing.json,required,$[0].recordDetails,interestedParty +relationship_interests_type_code.json,enum,$[0].recordDetails.interests[0].type,type +relationship_interests_direct_indirect_code.json,enum,$[0].recordDetails.interests[0].directOrIndirect,directOrIndirect +relationship_interests_beneficialOwnershipOrControl_not_boolean.json,type,$[0].recordDetails.interests[0].beneficialOwnershipOrControl,beneficialOwnershipOrControl +relationship_interests_share_not_object.json,type,$[0].recordDetails.interests[0].share,share +relationship_interests_share_startDate_format.json,type,$[0].recordDetails.interests[0].startDate,startDate +relationship_interests_share_exact_too_small.json,minimum,$[0].recordDetails.interests[0].share.exact,exact +relationship_interests_share_exact_too_big.json,maximum,$[0].recordDetails.interests[0].share.exact,exact +relationship_interests_share_maximum_too_small.json,minimum,$[0].recordDetails.interests[0].share.maximum,maximum +relationship_interests_share_maximum_too_big.json,maximum,$[0].recordDetails.interests[0].share.maximum,maximum +relationship_interests_share_minimum_too_small.json,minimum,$[0].recordDetails.interests[0].share.minimum,minimum +relationship_interests_share_minimum_too_big.json,maximum,$[0].recordDetails.interests[0].share.minimum,minimum +relationship_component_records_not_array.json,type,$[0].recordDetails.componentRecords,componentRecords +relationship_component_records_not_string.json,type,$[0].recordDetails.componentRecords[0],componentRecords +relationship_interested_party_invalid_type.json,oneOf,$[0].recordDetails.interestedParty,interestedParty +relationship_subject_invalid_type.json,oneOf,$[0].recordDetails.subject,subject +statement_annotations_transformedContent_wrong_motivation.json,const,$[0].annotations[0].transformedContent,transformedContent +relationship_component_records_true.json,const,$[0].recordDetails.componentRecords,componentRecords diff --git a/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_endDate_string.json b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_endDate_string.json new file mode 100644 index 0000000..21be9a3 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_endDate_string.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "endDate": 2020 + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_jurisdiction_no_object.json b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_jurisdiction_no_object.json new file mode 100644 index 0000000..1f8f269 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_jurisdiction_no_object.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "jurisdiction": "gb" + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_missingInfoReason_string.json b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_missingInfoReason_string.json new file mode 100644 index 0000000..bca7814 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_missingInfoReason_string.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "unknown", + "details": [ + { + "missingInfoReason": true + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_reason.json b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_reason.json new file mode 100644 index 0000000..04b370d --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_reason.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "reason": true + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_source_no_object.json b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_source_no_object.json new file mode 100644 index 0000000..cd3ab1d --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_source_no_object.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "source": "selfDeclaration" + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_startDate_string.json b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_startDate_string.json new file mode 100644 index 0000000..2cf8cf8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_PepStatusDetails_startDate_string.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "startDate": 2020 + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_addresses_birthplace.json b/tests/fixtures/0.4/invalid-schema/person_addresses_birthplace.json new file mode 100644 index 0000000..b81ce62 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_addresses_birthplace.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "person", + "recordDetails": { + "personType": "knownPerson", + "isComponent": false, + "addresses": [ + { + "type":"placeOfBirth", + "address": "23 Regent St, London" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_addresses_no_array.json b/tests/fixtures/0.4/invalid-schema/person_addresses_no_array.json new file mode 100644 index 0000000..2cc62d9 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_addresses_no_array.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "person", + "recordDetails": { + "personType": "knownPerson", + "isComponent": false, + "addresses": { + "type": "residence", + "address": "23 Regent St, London", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_addresses_type.json b/tests/fixtures/0.4/invalid-schema/person_addresses_type.json new file mode 100644 index 0000000..163f9a3 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_addresses_type.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "person", + "recordDetails": { + "personType": "knownPerson", + "isComponent": false, + "addresses": [ + { + "type":"business", + "address": "23 Regent St, London" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_birth_date_number.json b/tests/fixtures/0.4/invalid-schema/person_birth_date_number.json new file mode 100644 index 0000000..9131e4e --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_birth_date_number.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": 1990 + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_birth_place_not_object.json b/tests/fixtures/0.4/invalid-schema/person_birth_place_not_object.json new file mode 100644 index 0000000..b8a9dd2 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_birth_place_not_object.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "placeOfBirth": "Ireland" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_death_date_number.json b/tests/fixtures/0.4/invalid-schema/person_death_date_number.json new file mode 100644 index 0000000..067fed2 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_death_date_number.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "deathDate": 2001 + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_identifiers_not_array.json b/tests/fixtures/0.4/invalid-schema/person_identifiers_not_array.json new file mode 100644 index 0000000..1a50283 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_identifiers_not_array.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": { + "id": "7700225VH", + "scheme": "IRL-TAXID" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_identifiers_not_object.json b/tests/fixtures/0.4/invalid-schema/person_identifiers_not_object.json new file mode 100644 index 0000000..357debc --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_identifiers_not_object.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [ + "7700225VH" + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_isComponent_missing.json b/tests/fixtures/0.4/invalid-schema/person_isComponent_missing.json new file mode 100644 index 0000000..4da6134 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_isComponent_missing.json @@ -0,0 +1,12 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_iscomponent_not_bool.json b/tests/fixtures/0.4/invalid-schema/person_iscomponent_not_bool.json new file mode 100644 index 0000000..26537e2 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_iscomponent_not_bool.json @@ -0,0 +1,13 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": "false", + "personType": "knownPerson" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_names_familyName_string.json b/tests/fixtures/0.4/invalid-schema/person_names_familyName_string.json new file mode 100644 index 0000000..de341af --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_names_familyName_string.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "familyName": 123, + "fullName": "Riyadh Byrne-Amin" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_names_fullName_missing.json b/tests/fixtures/0.4/invalid-schema/person_names_fullName_missing.json new file mode 100644 index 0000000..b3af4a8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_names_fullName_missing.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "patronymicName": "Sergeyevich" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_names_fullName_string.json b/tests/fixtures/0.4/invalid-schema/person_names_fullName_string.json new file mode 100644 index 0000000..e81e000 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_names_fullName_string.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "fullName": 123 + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_names_givenName_string.json b/tests/fixtures/0.4/invalid-schema/person_names_givenName_string.json new file mode 100644 index 0000000..ed20677 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_names_givenName_string.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "givenName": 123, + "fullName": "Riyadh Byrne-Amin" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_names_not_array.json b/tests/fixtures/0.4/invalid-schema/person_names_not_array.json new file mode 100644 index 0000000..b4924b5 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_names_not_array.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": { + "type": "legal", + "fullName": "Riyadh Byrne-Amin" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_names_not_objects.json b/tests/fixtures/0.4/invalid-schema/person_names_not_objects.json new file mode 100644 index 0000000..e991229 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_names_not_objects.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + "Riyadh Byrne-Amin" + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_names_patronymic.json b/tests/fixtures/0.4/invalid-schema/person_names_patronymic.json new file mode 100644 index 0000000..ec2e551 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_names_patronymic.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "patronymicName": true, + "fullName": "Yuri Sergeyevich" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_names_type_code.json b/tests/fixtures/0.4/invalid-schema/person_names_type_code.json new file mode 100644 index 0000000..fcc8027 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_names_type_code.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "type": "person", + "fullName": "Riyadh Byrne-Amin" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_politicalExposure_details_not_array.json b/tests/fixtures/0.4/invalid-schema/person_politicalExposure_details_not_array.json new file mode 100644 index 0000000..87a26a5 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_politicalExposure_details_not_array.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": { + "startDate": "2016-10-15" + } + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_politicalExposure_no_object.json b/tests/fixtures/0.4/invalid-schema/person_politicalExposure_no_object.json new file mode 100644 index 0000000..1c3f6a7 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_politicalExposure_no_object.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": "isPep" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_politicalExposure_no_status.json b/tests/fixtures/0.4/invalid-schema/person_politicalExposure_no_status.json new file mode 100644 index 0000000..8e72331 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_politicalExposure_no_status.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": {} + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_politicalExposure_status_code.json b/tests/fixtures/0.4/invalid-schema/person_politicalExposure_status_code.json new file mode 100644 index 0000000..1a0e286 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_politicalExposure_status_code.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "yes" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_taxResidencies_no_object.json b/tests/fixtures/0.4/invalid-schema/person_taxResidencies_no_object.json new file mode 100644 index 0000000..08dc4e9 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_taxResidencies_no_object.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "taxResidencies": "Ireland" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_type_missing.json b/tests/fixtures/0.4/invalid-schema/person_type_missing.json new file mode 100644 index 0000000..18ce059 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_type_missing.json @@ -0,0 +1,12 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "person", + "recordDetails": { + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/person_type_not_codelist.json b/tests/fixtures/0.4/invalid-schema/person_type_not_codelist.json new file mode 100644 index 0000000..d03ed00 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_type_not_codelist.json @@ -0,0 +1,13 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "declarationSubject": "xyz", + "recordId": "123", + "recordType": "person", + "recordDetails": { + "personType": "person", + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/person_unspecified_person_details_not_object.json b/tests/fixtures/0.4/invalid-schema/person_unspecified_person_details_not_object.json new file mode 100644 index 0000000..e7b2e7b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/person_unspecified_person_details_not_object.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "unknownPerson", + "unspecifiedPersonDetails": "unknown" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_date_not_date.json b/tests/fixtures/0.4/invalid-schema/publication_details_date_not_date.json new file mode 100644 index 0000000..8dbca6f --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_date_not_date.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "bodsVersion": "0.4", + "publisher": { + "name": "Test Publisher" + }, + "publicationDate": "2021" + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_date_not_string.json b/tests/fixtures/0.4/invalid-schema/publication_details_date_not_string.json new file mode 100644 index 0000000..4d94eff --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_date_not_string.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "bodsVersion": "0.4", + "publisher": { + "name": "Test Publisher" + }, + "publicationDate": 2021 + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_license_not_string.json b/tests/fixtures/0.4/invalid-schema/publication_details_license_not_string.json new file mode 100644 index 0000000..6f9c5d8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_license_not_string.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "name": "Test Publisher" + }, + "license": true + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_license_not_uri.json b/tests/fixtures/0.4/invalid-schema/publication_details_license_not_uri.json new file mode 100644 index 0000000..44bf3d6 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_license_not_uri.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "name": "Test Publisher" + }, + "license": "opendefinition.org/licenses/cc-zero" + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_not_object.json b/tests/fixtures/0.4/invalid-schema/publication_details_not_object.json new file mode 100644 index 0000000..ba4fa66 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_not_object.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": true, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_publisher_name_not_string.json b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_name_not_string.json new file mode 100644 index 0000000..ae4eaa4 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_name_not_string.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "name": true + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_bods_version.json b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_bods_version.json new file mode 100644 index 0000000..b306bf6 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_bods_version.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "publisher": { + "name": "test" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_name_url.json b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_name_url.json new file mode 100644 index 0000000..03e7479 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_name_url.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "other": "string" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_publication_date.json b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_publication_date.json new file mode 100644 index 0000000..92bb204 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_publication_date.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "bodsVersion": "0.4", + "publisher": { + "name": "test" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_publisher.json b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_publisher.json new file mode 100644 index 0000000..dcfe28a --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_no_publisher.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4" + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_publisher_not_object.json b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_not_object.json new file mode 100644 index 0000000..a4bd743 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_not_object.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": "Irish Business Authority" + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_publisher_url_not_string.json b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_url_not_string.json new file mode 100644 index 0000000..11cea44 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_url_not_string.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "url": 11 + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_publisher_url_not_uri.json b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_url_not_uri.json new file mode 100644 index 0000000..f5d6268 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_publisher_url_not_uri.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "url": "test.org" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_version_not_string.json b/tests/fixtures/0.4/invalid-schema/publication_details_version_not_string.json new file mode 100644 index 0000000..28a830c --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_version_not_string.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "publisher": { + "name": "Test Publisher" + }, + "bodsVersion": 0.4 + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/publication_details_version_not_version.json b/tests/fixtures/0.4/invalid-schema/publication_details_version_not_version.json new file mode 100644 index 0000000..7eaddc9 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/publication_details_version_not_version.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "publisher": { + "name": "Test Publisher" + }, + "bodsVersion": "4.2.1" + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_component_records_not_array.json b/tests/fixtures/0.4/invalid-schema/relationship_component_records_not_array.json new file mode 100644 index 0000000..43f0a26 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_component_records_not_array.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "componentRecords": "per-1234", + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_component_records_not_string.json b/tests/fixtures/0.4/invalid-schema/relationship_component_records_not_string.json new file mode 100644 index 0000000..0c52678 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_component_records_not_string.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "componentRecords": [ + 1234 + ], + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_component_records_true.json b/tests/fixtures/0.4/invalid-schema/relationship_component_records_true.json new file mode 100644 index 0000000..d80d3f8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_component_records_true.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": true, + "componentRecords": [ + "per-1234", + "ent-5678", + "rel-7890" + ], + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interestedParty_missing.json b/tests/fixtures/0.4/invalid-schema/relationship_interestedParty_missing.json new file mode 100644 index 0000000..2ebeba6 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interestedParty_missing.json @@ -0,0 +1,13 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interested_party_invalid_type.json b/tests/fixtures/0.4/invalid-schema/relationship_interested_party_invalid_type.json new file mode 100644 index 0000000..e33bd4e --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interested_party_invalid_type.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f88", + "interestedParty": 1 + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_beneficialOwnershipOrControl_not_boolean.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_beneficialOwnershipOrControl_not_boolean.json new file mode 100644 index 0000000..94e7f46 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_beneficialOwnershipOrControl_not_boolean.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "beneficialOwnershipOrControl": "true" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_details_string.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_details_string.json new file mode 100644 index 0000000..fe56b5b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_details_string.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "details": true + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_direct_indirect_code.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_direct_indirect_code.json new file mode 100644 index 0000000..939d071 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_direct_indirect_code.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "directOrIndirect": "partly" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_end_date_dateformat.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_end_date_dateformat.json new file mode 100644 index 0000000..a56f986 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_end_date_dateformat.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "endDate": "2019" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_end_date_string.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_end_date_string.json new file mode 100644 index 0000000..fc9c161 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_end_date_string.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "endDate": 1 + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_max_negative.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_max_negative.json new file mode 100644 index 0000000..0545265 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_max_negative.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "exclusiveMaximum": -5 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_max_too_big.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_max_too_big.json new file mode 100644 index 0000000..0338699 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_max_too_big.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "exclusiveMaximum": 105 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_min_negative.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_min_negative.json new file mode 100644 index 0000000..bdf077b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_min_negative.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "exclusiveMinimum": -5 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_min_too_big.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_min_too_big.json new file mode 100644 index 0000000..5dc62ca --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_exclusive_min_too_big.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "exclusiveMinimum": 105 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_no_array.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_no_array.json new file mode 100644 index 0000000..d799271 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_no_array.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": { + "details": "details about interest" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_share_exact_too_big.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_exact_too_big.json new file mode 100644 index 0000000..6512c8e --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_exact_too_big.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "exact": 500 + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_share_exact_too_small.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_exact_too_small.json new file mode 100644 index 0000000..c6ce87c --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_exact_too_small.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "exact": -5 + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_share_maximum_too_big.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_maximum_too_big.json new file mode 100644 index 0000000..2be03b3 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_maximum_too_big.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "maximum": 500 + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_share_maximum_too_small.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_maximum_too_small.json new file mode 100644 index 0000000..8a27957 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_maximum_too_small.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "maximum": -5 + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_share_minimum_too_big.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_minimum_too_big.json new file mode 100644 index 0000000..b7dd264 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_minimum_too_big.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "minimum":500 + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_share_minimum_too_small.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_minimum_too_small.json new file mode 100644 index 0000000..d76bc0b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_minimum_too_small.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "minimum": -5 + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_share_not_object.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_not_object.json new file mode 100644 index 0000000..8f28912 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_not_object.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": 50 + } + ] + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_share_startDate_format.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_startDate_format.json new file mode 100644 index 0000000..f7f46e6 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_share_startDate_format.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "startDate": 2019 + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_interests_type_code.json b/tests/fixtures/0.4/invalid-schema/relationship_interests_type_code.json new file mode 100644 index 0000000..d8aa3af --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_interests_type_code.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "type": "share" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_isComponent_missing.json b/tests/fixtures/0.4/invalid-schema/relationship_isComponent_missing.json new file mode 100644 index 0000000..bc54227 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_isComponent_missing.json @@ -0,0 +1,13 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_isComponent_not_boolean.json b/tests/fixtures/0.4/invalid-schema/relationship_isComponent_not_boolean.json new file mode 100644 index 0000000..fe63d16 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_isComponent_not_boolean.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": "false", + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/relationship_subject_invalid_type.json b/tests/fixtures/0.4/invalid-schema/relationship_subject_invalid_type.json new file mode 100644 index 0000000..f2333a8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_subject_invalid_type.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": true, + "interestedParty": "ent-93c75c87ab28f88" + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/relationship_subject_missing.json b/tests/fixtures/0.4/invalid-schema/relationship_subject_missing.json new file mode 100644 index 0000000..49d01cd --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/relationship_subject_missing.json @@ -0,0 +1,13 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "interestedParty": "per-5faa4103dee78621" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations.statementPointerTarget_missing.json b/tests/fixtures/0.4/invalid-schema/statement_annotations.statementPointerTarget_missing.json new file mode 100644 index 0000000..6a0b20c --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations.statementPointerTarget_missing.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "motivation": "identifying" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_name_string.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_name_string.json new file mode 100644 index 0000000..690d34c --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_name_string.json @@ -0,0 +1,24 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "createdBy": { + "name": 2020 + } + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_no_object.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_no_object.json new file mode 100644 index 0000000..ebfb867 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_no_object.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "createdBy": "Joe Harris" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_uri.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_uri.json new file mode 100644 index 0000000..72e8c8f --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_createdBy_uri.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "createdBy": { + "name": "Joe Harris", + "uri": "example.com/index.html" + } + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_creationDate.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_creationDate.json new file mode 100644 index 0000000..3384a73 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_creationDate.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "creationDate": 2017 + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_description_not_string.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_description_not_string.json new file mode 100644 index 0000000..c910f51 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_description_not_string.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "description": 2020 + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_motivation_code.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_motivation_code.json new file mode 100644 index 0000000..c858c59 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_motivation_code.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "note" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_motivation_missing.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_motivation_missing.json new file mode 100644 index 0000000..8e7ad96 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_motivation_missing.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "url": "https://www.example.com/index.html" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_not_array.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_not_array.json new file mode 100644 index 0000000..30d0fba --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_not_array.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "url": "example.com/index.html" + }, + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_not_object.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_not_object.json new file mode 100644 index 0000000..bc560df --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_not_object.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + "/recordDetails/interestedParty" + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_statementPointerTarget_type.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_statementPointerTarget_type.json new file mode 100644 index 0000000..ea31d3a --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_statementPointerTarget_type.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": true, + "motivation": "identifying" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_transformedContent_not_string.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_transformedContent_not_string.json new file mode 100644 index 0000000..bbd4217 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_transformedContent_not_string.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/statementDate", + "motivation": "transformation", + "transformedContent": true + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_transformedContent_wrong_motivation.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_transformedContent_wrong_motivation.json new file mode 100644 index 0000000..cbfaea3 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_transformedContent_wrong_motivation.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/statementDate", + "motivation": "correcting", + "transformedContent": "12-31-2020" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_url_format.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_url_format.json new file mode 100644 index 0000000..1859adb --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_url_format.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "url": "example.com/index.html" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_annotations_url_linking_missing.json b/tests/fixtures/0.4/invalid-schema/statement_annotations_url_linking_missing.json new file mode 100644 index 0000000..799d43b --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_annotations_url_linking_missing.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "linking" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type":"unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_declarationSubject_missing.json b/tests/fixtures/0.4/invalid-schema/statement_declarationSubject_missing.json new file mode 100644 index 0000000..5dea469 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_declarationSubject_missing.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_declarationSubject_string.json b/tests/fixtures/0.4/invalid-schema/statement_declarationSubject_string.json new file mode 100644 index 0000000..27cfa56 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_declarationSubject_string.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": 93758728889, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_declaration_not_string.json b/tests/fixtures/0.4/invalid-schema/statement_declaration_not_string.json new file mode 100644 index 0000000..389ad18 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_declaration_not_string.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "declaration": 123, + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_recordDetails_missing.json b/tests/fixtures/0.4/invalid-schema/statement_recordDetails_missing.json new file mode 100644 index 0000000..a08ffde --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_recordDetails_missing.json @@ -0,0 +1,10 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "isComponent": false + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_recordDetails_no_object.json b/tests/fixtures/0.4/invalid-schema/statement_recordDetails_no_object.json new file mode 100644 index 0000000..6ba67a6 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_recordDetails_no_object.json @@ -0,0 +1,11 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "recordDetails": true, + "isComponent": false + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_recordId_missing.json b/tests/fixtures/0.4/invalid-schema/statement_recordId_missing.json new file mode 100644 index 0000000..f75bf86 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_recordId_missing.json @@ -0,0 +1,13 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordType": "person", + "recordStatus": "new", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_recordId_string.json b/tests/fixtures/0.4/invalid-schema/statement_recordId_string.json new file mode 100644 index 0000000..11c2ace --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_recordId_string.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "ent-93c75c87ab28f889", + "recordId": 93758728889, + "recordType": "entity", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_recordStatus_code.json b/tests/fixtures/0.4/invalid-schema/statement_recordStatus_code.json new file mode 100644 index 0000000..3ae2432 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_recordStatus_code.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "recordStatus": "live", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_recordType_code.json b/tests/fixtures/0.4/invalid-schema/statement_recordType_code.json new file mode 100644 index 0000000..137c263 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_recordType_code.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "company", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_name_string.json b/tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_name_string.json new file mode 100644 index 0000000..5ae2d6e --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_name_string.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "assertedBy": [ + { + "name": true + } + ] + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_not_array.json b/tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_not_array.json new file mode 100644 index 0000000..c11fb3a --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_not_array.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "assertedBy": { + "name": "Mary Walsh" + } + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_uri.json b/tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_uri.json new file mode 100644 index 0000000..bdbee51 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_source_assertedBy_uri.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "assertedBy": [ + { + "uri": "example.com/index.html" + } + ] + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_source_description_string.json b/tests/fixtures/0.4/invalid-schema/statement_source_description_string.json new file mode 100644 index 0000000..c348307 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_source_description_string.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "description": 2017 + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_source_no_object.json b/tests/fixtures/0.4/invalid-schema/statement_source_no_object.json new file mode 100644 index 0000000..df81568 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_source_no_object.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": "https://www.example.com/index.html", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_source_retrievedAt_date.json b/tests/fixtures/0.4/invalid-schema/statement_source_retrievedAt_date.json new file mode 100644 index 0000000..fb9cefd --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_source_retrievedAt_date.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "retrievedAt": 2017 + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_source_type_code.json b/tests/fixtures/0.4/invalid-schema/statement_source_type_code.json new file mode 100644 index 0000000..f0c8d6d --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_source_type_code.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "type": [ + "self" + ] + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_source_type_not_array.json b/tests/fixtures/0.4/invalid-schema/statement_source_type_not_array.json new file mode 100644 index 0000000..b76cf7a --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_source_type_not_array.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "type": "selfDeclaration" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_source_url.json b/tests/fixtures/0.4/invalid-schema/statement_source_url.json new file mode 100644 index 0000000..ab800a5 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_source_url.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "url": "example.com/index.html" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/invalid-schema/statement_statementDate_missing.json b/tests/fixtures/0.4/invalid-schema/statement_statementDate_missing.json new file mode 100644 index 0000000..13d11d8 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_statementDate_missing.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "123456789012345678901234567890123", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_statementDate_not_date_string.json b/tests/fixtures/0.4/invalid-schema/statement_statementDate_not_date_string.json new file mode 100644 index 0000000..bd3519f --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_statementDate_not_date_string.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "123456789012345678901234567890123", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_statementDate_not_string.json b/tests/fixtures/0.4/invalid-schema/statement_statementDate_not_string.json new file mode 100644 index 0000000..4a9fc07 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_statementDate_not_string.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "123456789012345678901234567890123", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": 2017, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_statementId_missing.json b/tests/fixtures/0.4/invalid-schema/statement_statementId_missing.json new file mode 100644 index 0000000..64db411 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_statementId_missing.json @@ -0,0 +1,14 @@ +[ + { + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_statementId_not_string.json b/tests/fixtures/0.4/invalid-schema/statement_statementId_not_string.json new file mode 100644 index 0000000..a1522e1 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_statementId_not_string.json @@ -0,0 +1,15 @@ +[ + { + "statementId": 123456789012345678901234567890123, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_statementId_too_long.json b/tests/fixtures/0.4/invalid-schema/statement_statementId_too_long.json new file mode 100644 index 0000000..d4408fd --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_statementId_too_long.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "NhQk1exCaQZIDZKOEPtouC4lyjXVhew6TCI20SiKTr7sRbftCajzpg3oXt8WnfdB3PxObVbJcaMxK11l", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statement_statementId_too_short.json b/tests/fixtures/0.4/invalid-schema/statement_statementId_too_short.json new file mode 100644 index 0000000..5450286 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statement_statementId_too_short.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "12345", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/invalid-schema/statements_not_array.json b/tests/fixtures/0.4/invalid-schema/statements_not_array.json new file mode 100644 index 0000000..16d9b60 --- /dev/null +++ b/tests/fixtures/0.4/invalid-schema/statements_not_array.json @@ -0,0 +1,13 @@ +{ + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } +} \ No newline at end of file diff --git a/tests/fixtures/0.4/sample_300_statements.json b/tests/fixtures/0.4/sample_300_statements.json new file mode 100644 index 0000000..c38cb33 --- /dev/null +++ b/tests/fixtures/0.4/sample_300_statements.json @@ -0,0 +1,10902 @@ +[ + { + "statementId": "ff940630-6c25-4108-bdaf-932f3cfa3469", + "declarationSubject": "afd20d6d732c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "afd20d6d732c", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "1a6a52ca-023d-40c2-b791-99c8b1bee622", + "declarationSubject": "afd20d6d732c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e7207941d426", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "e8b27726-3564-4b98-99f4-24552c087229", + "declarationSubject": "afd20d6d732c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e39a21bd0c25", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "afd20d6d732c", + "interestedParty": "e7207941d426", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "33859f99-b8d6-44f2-835f-ce72a94715ee", + "declarationSubject": "829784300fc2", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "829784300fc2", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "f9bd9322-c07c-4fa3-89ed-e9f4b7c48887", + "declarationSubject": "829784300fc2", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "0c6c882fca53", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "1f3af228-ec04-4b5f-be17-9ffe7b225ad5", + "declarationSubject": "829784300fc2", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "c43f6da0cf99", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "829784300fc2", + "interestedParty": "0c6c882fca53", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "6afd01df-5638-439f-a5dc-b00df5e6f896", + "declarationSubject": "55a8f366e5d3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "55a8f366e5d3", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "97241493-2a11-410b-8d16-0134cf352918", + "declarationSubject": "55a8f366e5d3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "01404b40ff53", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "a6e88edb-e8e2-432a-9232-2ade6f65b06d", + "declarationSubject": "55a8f366e5d3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ba2665da0c44", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "55a8f366e5d3", + "interestedParty": "01404b40ff53", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "2045a7ae-8253-481b-9bbe-3069d7227825", + "declarationSubject": "926f2e63cc01", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "926f2e63cc01", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "ce0134b3-084a-4efb-bcf8-546b53976469", + "declarationSubject": "926f2e63cc01", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e2cf050d408d", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "0b3a8429-d7d5-4c7d-b02e-9445eb306cd7", + "declarationSubject": "926f2e63cc01", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f497f2a94ea9", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "926f2e63cc01", + "interestedParty": "e2cf050d408d", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "cc0bd453-c720-4c75-937e-0a923d1276c6", + "declarationSubject": "f8617b2256bd", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f8617b2256bd", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "c6219b58-3cdd-4187-adf1-80ecd8068818", + "declarationSubject": "f8617b2256bd", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "c27d7c3f3c40", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "dfdd63ad-69bf-4688-b165-e7e47d2c4b2d", + "declarationSubject": "f8617b2256bd", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b72f8fbad4bd", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "f8617b2256bd", + "interestedParty": "c27d7c3f3c40", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "e6b4a679-4a07-4bc7-bf4b-27f40c33ea05", + "declarationSubject": "ef7bafcb7f6a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ef7bafcb7f6a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "8e17c844-ffe9-4527-a6a5-1330222f26c7", + "declarationSubject": "ef7bafcb7f6a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9df0d16294e9", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "bb3db1cc-3f09-4c9e-be49-93228f1a548f", + "declarationSubject": "ef7bafcb7f6a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "4b60c1fd8ee9", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ef7bafcb7f6a", + "interestedParty": "9df0d16294e9", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "5cc1e963-18c0-4fde-9dfc-56e0e51112db", + "declarationSubject": "10a8ca0f7cdf", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "10a8ca0f7cdf", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "e7d9e1c0-5c67-404b-992f-c025079870ab", + "declarationSubject": "10a8ca0f7cdf", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8bac0ff53b51", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "225c3395-b972-4d46-89c2-2d0f7ae9dc6e", + "declarationSubject": "10a8ca0f7cdf", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "bdb8fc9f3b77", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "10a8ca0f7cdf", + "interestedParty": "8bac0ff53b51", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "ae180d61-cefc-4af9-bef3-34b147fe4ce9", + "declarationSubject": "3273e00ed205", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "3273e00ed205", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "c47db2f9-77c4-453e-8bb8-8d0f9e4c55c5", + "declarationSubject": "3273e00ed205", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "276610e8ff89", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "f8adbbf9-9d00-483b-9435-9dda97d9fcd2", + "declarationSubject": "3273e00ed205", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "29b176a7a11b", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "3273e00ed205", + "interestedParty": "276610e8ff89", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "df4bc7c0-ae71-45b8-b0f2-568fb6ef052e", + "declarationSubject": "92a8ab41ccea", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "92a8ab41ccea", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "db4c120f-01e8-486d-854e-945161cb0ad2", + "declarationSubject": "92a8ab41ccea", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "bbaeb0b4ec00", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "3b49e6e4-2d36-4416-8dcd-a805726f5c00", + "declarationSubject": "92a8ab41ccea", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "0b8e3363458f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "92a8ab41ccea", + "interestedParty": "bbaeb0b4ec00", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "9e5ff4d1-0d2e-42ef-84da-825147eb9507", + "declarationSubject": "07710badcd19", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "07710badcd19", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "4a737647-c2a6-4deb-804e-37ed4f10cfd2", + "declarationSubject": "07710badcd19", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "96956667003d", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "e3011651-2005-4a34-909b-bcdc1e34f15f", + "declarationSubject": "07710badcd19", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "677f9257ba4a", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "07710badcd19", + "interestedParty": "96956667003d", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "df6e93f3-59fb-4154-8db1-4fd8cb8e6b41", + "declarationSubject": "ba038eeb1e8d", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ba038eeb1e8d", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "1918fb2d-98a4-4ff1-85f8-25c2c093e598", + "declarationSubject": "ba038eeb1e8d", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "aab8da1ff6a4", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "a1ae6474-18fe-48eb-ad07-e24d58b5715a", + "declarationSubject": "ba038eeb1e8d", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "bed2b7f876b5", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ba038eeb1e8d", + "interestedParty": "aab8da1ff6a4", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "b51fac3d-cae8-475f-a44f-44bd29f30e8f", + "declarationSubject": "859c14416733", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "859c14416733", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "8603431b-4655-4e89-a7ef-81913aaad452", + "declarationSubject": "859c14416733", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6e164bf958f6", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "885c71b3-7408-40a5-a7e1-d251a6eda64e", + "declarationSubject": "859c14416733", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "32dcfaad2916", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "859c14416733", + "interestedParty": "6e164bf958f6", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "4336caea-1e2c-4341-a7d4-78df65d4a0dd", + "declarationSubject": "6a9f333a07be", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6a9f333a07be", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "bb4e597a-6c46-4d76-8131-c35cb2d1e220", + "declarationSubject": "6a9f333a07be", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "98461230376f", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "9976ded9-2394-4f43-8dd0-682daf52b942", + "declarationSubject": "6a9f333a07be", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8577d7b54bd2", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "6a9f333a07be", + "interestedParty": "98461230376f", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "08f2d32d-26c8-4f9e-88ed-b22aa6124946", + "declarationSubject": "8d5c09eae6c6", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8d5c09eae6c6", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "beeedc5c-1395-4e97-9260-b1874dae54ac", + "declarationSubject": "8d5c09eae6c6", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "27815db07207", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "bc0e9035-6acc-47ac-a203-cfa11b3890f9", + "declarationSubject": "8d5c09eae6c6", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "5fbd3f179f24", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "8d5c09eae6c6", + "interestedParty": "27815db07207", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "cfae1ff9-bac0-48a6-9e19-b1189a1cae04", + "declarationSubject": "decccf5fc7fa", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "decccf5fc7fa", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "eb18db6a-76d1-44a4-b420-d24c8105e388", + "declarationSubject": "decccf5fc7fa", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "fc6c96aea72e", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "70336a8f-c978-49c4-95db-effd9399959b", + "declarationSubject": "decccf5fc7fa", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f13eaea144ac", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "decccf5fc7fa", + "interestedParty": "fc6c96aea72e", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "c3375aa0-ef20-420b-b461-363576c426a6", + "declarationSubject": "454bcd17bf4e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "454bcd17bf4e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "687e7ce3-11ac-4b97-9b14-aac122dbf68a", + "declarationSubject": "454bcd17bf4e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2307a0058972", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "61263ed1-26c1-4b79-add9-f3a92e0885d3", + "declarationSubject": "454bcd17bf4e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "d2d22825aa80", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "454bcd17bf4e", + "interestedParty": "2307a0058972", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "dcdc6b71-d713-40de-bf02-448bceea864f", + "declarationSubject": "9d09983b4ae3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9d09983b4ae3", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "4ff88003-335f-4bb8-ad5c-7501effa1791", + "declarationSubject": "9d09983b4ae3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f03c9f98a185", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "044f09cf-03c6-4476-bb97-6ebc570573d3", + "declarationSubject": "9d09983b4ae3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e2b03413cf10", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "9d09983b4ae3", + "interestedParty": "f03c9f98a185", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "5bcb6323-8c4b-4db7-aa69-f3beb43f3a68", + "declarationSubject": "186e4fb10db1", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "186e4fb10db1", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "5052493d-448b-44ed-bd1b-3f63c902df37", + "declarationSubject": "186e4fb10db1", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ebd46b022c8e", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "5e170f6d-ef05-420e-9c6d-0b57e971c2d3", + "declarationSubject": "186e4fb10db1", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "7860bcbff889", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "186e4fb10db1", + "interestedParty": "ebd46b022c8e", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "0d66b782-fb52-4bc9-a815-f8e2025d1b9e", + "declarationSubject": "916ae43cb096", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "916ae43cb096", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "06bf94ca-a66e-4dc3-8921-a71977d104bd", + "declarationSubject": "916ae43cb096", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "a25803080738", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "0931f49b-e17f-46b5-bcfb-76b07f95fd41", + "declarationSubject": "916ae43cb096", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "0ebc04d98365", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "916ae43cb096", + "interestedParty": "a25803080738", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "5b9f631e-a70e-4810-a69f-243f8cc0bbc5", + "declarationSubject": "7c4e825c560d", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "7c4e825c560d", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "de87c0a0-5a25-427c-8494-6b76f5d22f5a", + "declarationSubject": "7c4e825c560d", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "4d3a7618c251", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "c74d37b7-0b52-43f4-b496-64201dd1ce93", + "declarationSubject": "7c4e825c560d", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "541fb280308b", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "7c4e825c560d", + "interestedParty": "4d3a7618c251", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "5b69d26c-4130-4bf7-ba6c-a6e2b99ed2e9", + "declarationSubject": "f79e2f512923", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f79e2f512923", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "04a41bf6-f568-4ac7-b2e7-9ca2398f2139", + "declarationSubject": "f79e2f512923", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6a9800054568", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "8ce002df-3293-4b46-b364-cf4a07f5089c", + "declarationSubject": "f79e2f512923", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "5356428725bb", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "f79e2f512923", + "interestedParty": "6a9800054568", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "8b22b54a-b5a6-4111-9322-aad4f7b30580", + "declarationSubject": "e524d1dfeb9b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e524d1dfeb9b", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "504750b6-a2ac-4ac6-b6b4-8abef53ab7d6", + "declarationSubject": "e524d1dfeb9b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "660203e1078d", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "df9e258e-d229-4e38-9ac1-ccfc5d1bbb90", + "declarationSubject": "e524d1dfeb9b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "a40421ba3626", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "e524d1dfeb9b", + "interestedParty": "660203e1078d", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "d4b6b929-0135-4582-8124-d0782359b138", + "declarationSubject": "bbfaf348c980", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "bbfaf348c980", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "fbf93ded-6e19-46c4-8e28-336efecaba13", + "declarationSubject": "bbfaf348c980", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e339557f0bde", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "b911dfea-1a79-4c88-bf7c-41ddc391e570", + "declarationSubject": "bbfaf348c980", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "986a06ca9003", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "bbfaf348c980", + "interestedParty": "e339557f0bde", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "22c499f6-8230-4ab6-99f2-23680e9fa7bc", + "declarationSubject": "fcfb7b7b2af2", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "fcfb7b7b2af2", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "cfeae3e0-8d41-4741-a9c5-1bc92390bd84", + "declarationSubject": "fcfb7b7b2af2", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "df56230a41a4", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "6a22da20-9eb5-4ce4-bb10-0eaa56707ecb", + "declarationSubject": "fcfb7b7b2af2", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9c421f2cbabc", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "fcfb7b7b2af2", + "interestedParty": "df56230a41a4", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "3cfee76d-2abe-462d-93f0-6ef00197795d", + "declarationSubject": "525b27852757", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "525b27852757", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "6b11a638-a7be-4f09-80cf-312edfd2484e", + "declarationSubject": "525b27852757", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f899659e493c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "9ac9c911-bc18-44b8-b332-c0a81b22f9c5", + "declarationSubject": "525b27852757", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "daaaab90d84c", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "525b27852757", + "interestedParty": "f899659e493c", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "cae9c670-db86-40ef-8096-56b1c306d42e", + "declarationSubject": "c2e4e818d7ab", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "c2e4e818d7ab", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "7d105a5a-7ed5-44be-ab9f-443fc3da4041", + "declarationSubject": "c2e4e818d7ab", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "907390afd23f", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "446299c8-dc39-46a9-aa31-4720137222ef", + "declarationSubject": "c2e4e818d7ab", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ca7c0902cccb", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "c2e4e818d7ab", + "interestedParty": "907390afd23f", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "4020e1c3-da15-48ae-8d45-4b865e22ad1e", + "declarationSubject": "d0bd14375490", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "d0bd14375490", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "8253bea9-5546-4f25-abe5-594b410ad26d", + "declarationSubject": "d0bd14375490", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f5ff5900d4c7", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "4eaf43cc-eeec-47fe-9de8-dd719b8479c7", + "declarationSubject": "d0bd14375490", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "66064b4dd9e3", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "d0bd14375490", + "interestedParty": "f5ff5900d4c7", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "01a8cefc-23ab-49bc-9674-1f1c1e3fc142", + "declarationSubject": "6e783848cccf", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6e783848cccf", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "99123a25-e3ae-42ff-96ee-87157e10d677", + "declarationSubject": "6e783848cccf", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "346bb1bb8773", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "ee53d597-2014-4b11-a461-db2c55c7d996", + "declarationSubject": "6e783848cccf", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "29ef48846f8e", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "6e783848cccf", + "interestedParty": "346bb1bb8773", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "ec1b8c40-55c6-4182-8ccd-87d87c7400d3", + "declarationSubject": "cc3cfdde0370", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "cc3cfdde0370", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "6d3273ca-fb58-49b0-851f-8f9d013d2a07", + "declarationSubject": "cc3cfdde0370", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "a59b18dfbde3", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "a084942e-e3f8-44da-becf-8d9d85d8c36b", + "declarationSubject": "cc3cfdde0370", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8e15a5fc4ef7", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "cc3cfdde0370", + "interestedParty": "a59b18dfbde3", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "a6af0bd3-ec4b-466f-8858-33c441235b78", + "declarationSubject": "fdb0d46e75dd", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "fdb0d46e75dd", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "42a91047-9ea1-45f4-985a-5d6a271759da", + "declarationSubject": "fdb0d46e75dd", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "90bb7e4e1a07", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "54b14781-62ca-4f00-9e2b-749fad02ae9f", + "declarationSubject": "fdb0d46e75dd", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6f99271a38b4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "fdb0d46e75dd", + "interestedParty": "90bb7e4e1a07", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "8c26c3d2-b474-41ed-950f-3580231926b6", + "declarationSubject": "5c0bc98f078a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "5c0bc98f078a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "24582893-c28e-4b18-8d06-9b192a775eb5", + "declarationSubject": "5c0bc98f078a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8da881b2dc2f", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "406f6d6b-b8c1-4329-9bbb-3cb28b9e64be", + "declarationSubject": "5c0bc98f078a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1aae387e4277", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "5c0bc98f078a", + "interestedParty": "8da881b2dc2f", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "ab3c59e3-1eec-49b2-a643-40167eb13f1b", + "declarationSubject": "8b15c3b57f58", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8b15c3b57f58", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "8f55d2af-5260-4c54-8811-e09bc5c210fc", + "declarationSubject": "8b15c3b57f58", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8b159beb7974", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "a14d5e6d-ac1e-444a-a7ac-299f0d5b89c5", + "declarationSubject": "8b15c3b57f58", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f34953659975", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "8b15c3b57f58", + "interestedParty": "8b159beb7974", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "b41229e8-c656-4e0d-bdbf-959913b706c1", + "declarationSubject": "72069dcadc23", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "72069dcadc23", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "05613ffe-6c99-470e-99e9-81f877778a23", + "declarationSubject": "72069dcadc23", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b65c8da3da8a", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "3baeb723-2d45-46ba-9120-90986c14c71d", + "declarationSubject": "72069dcadc23", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1f7402d32df9", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "72069dcadc23", + "interestedParty": "b65c8da3da8a", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "6de254eb-0e06-416f-8d4b-570f7072afea", + "declarationSubject": "1a7936bdca4e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1a7936bdca4e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "ce45c531-da14-45d2-85c8-b01b9a4c25c4", + "declarationSubject": "1a7936bdca4e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "591c3a152c69", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "744aa9c8-0dfc-44ab-9d81-9673997f1a3f", + "declarationSubject": "1a7936bdca4e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "cbb45a1bc014", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "1a7936bdca4e", + "interestedParty": "591c3a152c69", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "65fa9acf-2fa6-4ed5-9477-ad72e51fe0f4", + "declarationSubject": "22bc88e1f1ba", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "22bc88e1f1ba", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "2cc26600-1876-410c-ae0a-5e231c104364", + "declarationSubject": "22bc88e1f1ba", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "7820f0238708", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "7a4d574b-94ac-46cb-8b57-5476ff388f81", + "declarationSubject": "22bc88e1f1ba", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "d23672968492", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "22bc88e1f1ba", + "interestedParty": "7820f0238708", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "e169e105-3715-48a0-8152-1b63f0a8ef28", + "declarationSubject": "529383904772", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "529383904772", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "56a80b08-2abf-4a83-9b54-583bfba74d59", + "declarationSubject": "529383904772", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "60e3821afe94", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "bfc4b17d-3b2e-4487-b59d-f753ed2eb68c", + "declarationSubject": "529383904772", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f0d162cfdfa6", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "529383904772", + "interestedParty": "60e3821afe94", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "5abb8778-baf9-4a4b-8bf5-416da4fa73c9", + "declarationSubject": "ac038f1408f0", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ac038f1408f0", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "e44dc007-5699-4493-8545-0d247efc52e4", + "declarationSubject": "ac038f1408f0", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "07cbe2687164", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "8665c701-6bf2-4129-9c33-1439e263716b", + "declarationSubject": "ac038f1408f0", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8af42aa41516", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ac038f1408f0", + "interestedParty": "07cbe2687164", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "5aa6710c-51ee-4e4a-973f-361de21af3f5", + "declarationSubject": "32275779cda1", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "32275779cda1", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "0ff4afc3-2647-4279-a895-6adad6de5072", + "declarationSubject": "32275779cda1", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "07f9c2f934a1", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "19612b3a-b0f1-4cf1-9f03-17ec5dfcb606", + "declarationSubject": "32275779cda1", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "5cf1be9f354e", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "32275779cda1", + "interestedParty": "07f9c2f934a1", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "47a57967-6792-4400-ad77-7ba255d0c04c", + "declarationSubject": "ab92049b4450", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ab92049b4450", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "35114466-7097-4b34-a491-c5c99d484b3b", + "declarationSubject": "ab92049b4450", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "63d47c5fbbb7", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "f5bbea62-48dc-4955-9153-6fe889082901", + "declarationSubject": "ab92049b4450", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "c345bb4cbef2", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ab92049b4450", + "interestedParty": "63d47c5fbbb7", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "2921176d-ae74-49a7-8efe-4282bba239eb", + "declarationSubject": "dd4180363b5b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "dd4180363b5b", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "3a52350a-374e-4602-8d70-666d5c550e72", + "declarationSubject": "dd4180363b5b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "93dd8630fe98", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "d4666a1f-40b4-458e-8edf-de6034897943", + "declarationSubject": "dd4180363b5b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8d0eeb45c6da", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "dd4180363b5b", + "interestedParty": "93dd8630fe98", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "7a34c001-4f49-40eb-8d6d-f6864b5bf477", + "declarationSubject": "3a0f0b66e87a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "3a0f0b66e87a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "17aeb8e6-03d1-4f15-beff-08f4da739515", + "declarationSubject": "3a0f0b66e87a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "49659e5c2212", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "edd5e9b9-4a4a-498c-9e7d-a7e161f71636", + "declarationSubject": "3a0f0b66e87a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2a805cd16872", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "3a0f0b66e87a", + "interestedParty": "49659e5c2212", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "c47159b7-092f-4698-9dba-d8f54fe12ec7", + "declarationSubject": "bdc85ea0e6d3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "bdc85ea0e6d3", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "c7668b46-a3ce-4205-8a21-a5b141fdeee1", + "declarationSubject": "bdc85ea0e6d3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9c4491267d0d", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "a7db7363-670a-471c-9a03-4fc6531bc676", + "declarationSubject": "bdc85ea0e6d3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b52dc4f09a84", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "bdc85ea0e6d3", + "interestedParty": "9c4491267d0d", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "99c4c6f6-7778-43c7-89aa-a9c77dc2ed07", + "declarationSubject": "0fa508dd0b9e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "0fa508dd0b9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "f892fc8c-4d26-49a4-84ff-3cc225ccfd73", + "declarationSubject": "0fa508dd0b9e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1bf784246dd4", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "30cb781c-6fbe-47a4-9a0c-4b1a535f9692", + "declarationSubject": "0fa508dd0b9e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ab58c718477b", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "0fa508dd0b9e", + "interestedParty": "1bf784246dd4", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "e6e538c9-ef71-4625-81b9-7be5eff4540b", + "declarationSubject": "70aadd7a97f9", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "70aadd7a97f9", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "275bb3c4-95b7-44b1-a19b-368613be812e", + "declarationSubject": "70aadd7a97f9", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "fa8f35f8042a", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "49e6d1c4-b709-40cf-bfc3-db05c78262ae", + "declarationSubject": "70aadd7a97f9", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1fc832231354", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "70aadd7a97f9", + "interestedParty": "fa8f35f8042a", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "e40d81f3-7e53-4142-8a80-624eb154e9a2", + "declarationSubject": "28e8be03802b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "28e8be03802b", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "efb72e83-e2b8-4f7a-9c27-f593f9989178", + "declarationSubject": "28e8be03802b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "021a4214f6db", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "7e070111-72f4-490c-b5cf-794fc8bc2d7f", + "declarationSubject": "28e8be03802b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "387d593e0bda", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "28e8be03802b", + "interestedParty": "021a4214f6db", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "dde53b90-197f-48a5-ad66-2e4ea093936e", + "declarationSubject": "7dc163897531", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "7dc163897531", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "48c89e4b-3883-438d-b072-572db8943c22", + "declarationSubject": "7dc163897531", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2a77e1730756", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "551681f8-a0fc-43d2-99d1-2f048373b994", + "declarationSubject": "7dc163897531", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "044fcbb5eada", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "7dc163897531", + "interestedParty": "2a77e1730756", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "44b79eca-5333-4b5d-b7e4-81f6e78ae5d3", + "declarationSubject": "f71512f3e024", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f71512f3e024", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "24483653-934b-4786-8526-5f6c2705328b", + "declarationSubject": "f71512f3e024", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1702ea67965f", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "b13e3c45-a481-442a-9369-24b3c89be6af", + "declarationSubject": "f71512f3e024", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "87b0da0fccf6", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "f71512f3e024", + "interestedParty": "1702ea67965f", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "237a2730-8b20-4762-83e8-96343989de7d", + "declarationSubject": "6523c74e992c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6523c74e992c", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "2e24f54b-45e9-4d4e-8bb3-0b28e089d07e", + "declarationSubject": "6523c74e992c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "87ca1f7df83f", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "44ae4dcb-878c-4a06-b3ed-914937f881c7", + "declarationSubject": "6523c74e992c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "186fa90b3529", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "6523c74e992c", + "interestedParty": "87ca1f7df83f", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "209b1922-3959-4db9-a12b-75f01a528bdc", + "declarationSubject": "eebb8e357295", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "eebb8e357295", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "f4efa72c-31d1-40a1-b08c-ec0236ce8e5f", + "declarationSubject": "eebb8e357295", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2c22a9559376", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "ecc7ad00-f6d2-4965-bd09-8b1262be301b", + "declarationSubject": "eebb8e357295", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "dcc437ffa40d", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "eebb8e357295", + "interestedParty": "2c22a9559376", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "f8912df6-755c-4252-88d1-7974f56302b3", + "declarationSubject": "943928f7363c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "943928f7363c", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "3f536566-b3a2-4ad0-adce-2ec25a16b45a", + "declarationSubject": "943928f7363c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2be7ce09f0ab", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "ad717275-2fd7-47da-a31f-927d4152e119", + "declarationSubject": "943928f7363c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6579a7072a46", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "943928f7363c", + "interestedParty": "2be7ce09f0ab", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "ac909db1-285f-47a1-a736-e95e12572166", + "declarationSubject": "b1847044938b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b1847044938b", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "cd698511-69fc-4370-935f-ef3dec9a56f6", + "declarationSubject": "b1847044938b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "451906a68dee", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "237e0baf-c380-4da1-8ecb-84ba120e8ec6", + "declarationSubject": "b1847044938b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f7f7918bf02e", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "b1847044938b", + "interestedParty": "451906a68dee", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "9ddfc36a-dbec-4a9c-9393-e218be78bc28", + "declarationSubject": "172da17451f0", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "172da17451f0", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "adba2e24-277d-428f-ade9-cac4525ea5c8", + "declarationSubject": "172da17451f0", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2480ae082d36", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "3a59b74d-aeb9-4e9a-a2f6-ab1d60cb4288", + "declarationSubject": "172da17451f0", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "a05a36426083", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "172da17451f0", + "interestedParty": "2480ae082d36", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "4cb78248-c41c-4c8d-b850-ddaa35562208", + "declarationSubject": "0429584c35c6", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "0429584c35c6", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "5af5aba6-a17c-4fd7-be57-d4a0ebfc2fcb", + "declarationSubject": "0429584c35c6", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "96a7296cb9ae", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "77a31e9d-c42e-4222-8089-9c1f602ce962", + "declarationSubject": "0429584c35c6", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "aac5c62cc0db", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "0429584c35c6", + "interestedParty": "96a7296cb9ae", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "a49dabd0-f59b-459d-a569-9146d899901d", + "declarationSubject": "0b2ed7e8864b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "0b2ed7e8864b", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "3bb311e8-df1d-46a9-ae51-45632c86a658", + "declarationSubject": "0b2ed7e8864b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2b9490e5780c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "5855d844-d7c8-4a51-adc2-ba9033777ffa", + "declarationSubject": "0b2ed7e8864b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8132d7de9d09", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "0b2ed7e8864b", + "interestedParty": "2b9490e5780c", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "019a380b-e0b6-49c1-9685-87233231afe7", + "declarationSubject": "cfd653ae8d93", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "cfd653ae8d93", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "b6765274-cf34-4b25-a792-579ed486a007", + "declarationSubject": "cfd653ae8d93", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "7f3d9dc45689", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "a895b7b3-0954-46e6-87b8-4e86ccdcd5b9", + "declarationSubject": "cfd653ae8d93", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "28818963edc8", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "cfd653ae8d93", + "interestedParty": "7f3d9dc45689", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "fe7a4795-55d4-43ea-b330-2611f6315fdd", + "declarationSubject": "b3ed6cd353a7", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b3ed6cd353a7", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "3beba063-1fba-48e9-83d6-bfc79a98b637", + "declarationSubject": "b3ed6cd353a7", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "fd5562dfb91a", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "88a745c5-df84-4d2b-817a-1a635c4b0fe1", + "declarationSubject": "b3ed6cd353a7", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "94f61ccf7926", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "b3ed6cd353a7", + "interestedParty": "fd5562dfb91a", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "c71679c7-1abc-40ad-b47e-7257558f2a62", + "declarationSubject": "bdecf7f2f1b0", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "bdecf7f2f1b0", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "9f5dc9e0-9fc7-435f-b409-a926329c7312", + "declarationSubject": "bdecf7f2f1b0", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "11919cd5c809", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "48695f84-fc67-41a6-a02a-c875fed972b6", + "declarationSubject": "bdecf7f2f1b0", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "625ede147f84", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "bdecf7f2f1b0", + "interestedParty": "11919cd5c809", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "49b10821-1d14-4088-8b91-0bcc3f042ad4", + "declarationSubject": "9522f4ed4f4e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9522f4ed4f4e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "516271b4-60cb-4b9f-ab6f-0bceb23be5e9", + "declarationSubject": "9522f4ed4f4e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "7d024e2f9680", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "9baf260c-923a-4f0a-b447-f00edc300db2", + "declarationSubject": "9522f4ed4f4e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6cf2da2571e0", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "9522f4ed4f4e", + "interestedParty": "7d024e2f9680", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "20115a50-0498-40f0-a177-de5e659407f8", + "declarationSubject": "5eed260fea98", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "5eed260fea98", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "27f0769e-998b-4942-a4ac-1280a59a53f4", + "declarationSubject": "5eed260fea98", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9ae8219aa0b3", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "b7656e3c-b3eb-47e6-8d59-d1fddc99339f", + "declarationSubject": "5eed260fea98", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "36e8d83bc459", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "5eed260fea98", + "interestedParty": "9ae8219aa0b3", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "1c7444b3-4a7e-4496-bc40-4733011ac30a", + "declarationSubject": "ac5966d3058a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ac5966d3058a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "30322f10-b048-4549-8c0f-8d5cba16578a", + "declarationSubject": "ac5966d3058a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "98eb707d8f6a", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "fc72e597-e592-407d-b790-d925c12ef8b9", + "declarationSubject": "ac5966d3058a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "753c0ba305cc", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ac5966d3058a", + "interestedParty": "98eb707d8f6a", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "f91a1d64-61c4-443e-b69a-bdc71a6c2014", + "declarationSubject": "a15ea4dc8250", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "a15ea4dc8250", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "e958eb83-6a10-47c9-b2a0-03f41ff897b0", + "declarationSubject": "a15ea4dc8250", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "43eb80ff0576", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "371609d6-2a34-454e-9189-ca36baff4c82", + "declarationSubject": "a15ea4dc8250", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "76a7af69441e", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "a15ea4dc8250", + "interestedParty": "43eb80ff0576", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "7e2e660d-e4db-4525-87ca-112e2a861990", + "declarationSubject": "b7fc53d22415", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b7fc53d22415", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "3880f239-56a3-4116-ada5-01f93ae95f55", + "declarationSubject": "b7fc53d22415", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "335f19ce4d8d", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "77c41ed1-3f8b-43ec-a7e0-6078c911adf8", + "declarationSubject": "b7fc53d22415", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "eaf73c9fa550", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "b7fc53d22415", + "interestedParty": "335f19ce4d8d", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "66a4a650-20c1-4b94-8a59-835d6252f851", + "declarationSubject": "b97b81d7472a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b97b81d7472a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "79f489c9-a48b-484a-a83e-12e1ed662503", + "declarationSubject": "b97b81d7472a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "eced91fe4677", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "23a23dc0-1e54-4dbd-a7d3-0aeeccbc3f0e", + "declarationSubject": "b97b81d7472a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "343d68942c30", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "b97b81d7472a", + "interestedParty": "eced91fe4677", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "307dc844-93bd-438b-b41c-80cb4ed66b64", + "declarationSubject": "1b7e3d6938f5", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1b7e3d6938f5", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "d68ed660-d4d6-4643-a69e-0eeed9721977", + "declarationSubject": "1b7e3d6938f5", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "11e847a65f81", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "7955bdad-c7b0-4132-b11b-d2d208fb1ac1", + "declarationSubject": "1b7e3d6938f5", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "7d83582849de", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "1b7e3d6938f5", + "interestedParty": "11e847a65f81", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "6ddc35fc-772b-45dc-8149-775d5154b5fa", + "declarationSubject": "f147c62dc6c9", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f147c62dc6c9", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "5cbf2919-f221-4075-80da-0b04ef4a6382", + "declarationSubject": "f147c62dc6c9", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "652d22d12eed", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "fb11abbc-d5bd-4d57-bc7c-7201920f22fa", + "declarationSubject": "f147c62dc6c9", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b46cbed70e1f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "f147c62dc6c9", + "interestedParty": "652d22d12eed", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "3f814950-dbfc-4d10-a34c-3852d5394bc9", + "declarationSubject": "8bc490d6529c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8bc490d6529c", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "e96d1aa2-4840-48bd-baa0-f33d7c27fc95", + "declarationSubject": "8bc490d6529c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6616a858f89b", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "dd018aed-1f2c-483b-ab91-7197bf0950eb", + "declarationSubject": "8bc490d6529c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "195a30d49a3c", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "8bc490d6529c", + "interestedParty": "6616a858f89b", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "0ba86737-1f21-441d-88db-10105e9fc2fa", + "declarationSubject": "6e385df79850", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6e385df79850", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "09093309-e589-432d-9a5b-3cf3b149b33f", + "declarationSubject": "6e385df79850", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ec7f9b34196d", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "5ed5d42d-4c6c-4cf9-97e1-6d56a861061c", + "declarationSubject": "6e385df79850", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1fb703c83054", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "6e385df79850", + "interestedParty": "ec7f9b34196d", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "0d96528d-e2bb-4363-a624-0a2f86af98d5", + "declarationSubject": "cb7bd02033fa", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "cb7bd02033fa", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "69ebb15d-9347-46c3-a839-b99c390b6837", + "declarationSubject": "cb7bd02033fa", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ab279c3635d5", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "bdeabd17-756e-4487-9e14-c9cd47b971b3", + "declarationSubject": "cb7bd02033fa", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e43e0c5e0ee3", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "cb7bd02033fa", + "interestedParty": "ab279c3635d5", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "49655d85-f106-4ebd-b54b-b8a2db23a6e3", + "declarationSubject": "3bb9e8ee95b9", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "3bb9e8ee95b9", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "5a4f49b7-488f-4350-b3ef-31da84cebded", + "declarationSubject": "3bb9e8ee95b9", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "cfcea4d38eb9", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "8a3b93fc-543e-4dad-8a5b-f090f8f850c4", + "declarationSubject": "3bb9e8ee95b9", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1b09bdb04993", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "3bb9e8ee95b9", + "interestedParty": "cfcea4d38eb9", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "6f25a1b3-4a25-4c8b-834b-baad7887944f", + "declarationSubject": "afce353d77eb", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "afce353d77eb", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "f1e731e1-fe4f-4c86-97a4-7185a92d2a7f", + "declarationSubject": "afce353d77eb", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "4d1d7463affa", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "f9d16722-5c80-4f7a-b83a-21c281fc8b8e", + "declarationSubject": "afce353d77eb", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "4e269a5eeab2", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "afce353d77eb", + "interestedParty": "4d1d7463affa", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "5bbf497e-8f9b-41e3-950e-0fee8c21dc4c", + "declarationSubject": "79cc4a6f9859", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "79cc4a6f9859", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "f8c85d0c-bb5c-4dcc-a81d-0cef92839788", + "declarationSubject": "79cc4a6f9859", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "168beb08eb11", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "e52da5b3-5026-4a09-8d5a-cfe0715d45ad", + "declarationSubject": "79cc4a6f9859", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "3efbf8e767fc", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "79cc4a6f9859", + "interestedParty": "168beb08eb11", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "c61e87eb-9994-4c53-ac6c-372ae66f4999", + "declarationSubject": "d862cbc6c5ae", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "d862cbc6c5ae", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "8d711e37-3de7-4662-b8d0-d7d12fb09e3e", + "declarationSubject": "d862cbc6c5ae", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "01576025b5c6", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "94fc7032-6462-4c5c-a837-d0d5083fa69f", + "declarationSubject": "d862cbc6c5ae", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "379513bd7035", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "d862cbc6c5ae", + "interestedParty": "01576025b5c6", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "ea3dcfc4-b926-4436-a809-eb22fbea3f28", + "declarationSubject": "5ca4d7793a4a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "5ca4d7793a4a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "a796b4c3-73ae-4190-9117-5ebf4b666a1f", + "declarationSubject": "5ca4d7793a4a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "aa0e0553ba45", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "30cc214a-ed6b-42a3-b7c0-67b266465444", + "declarationSubject": "5ca4d7793a4a", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ca3f798501f5", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "5ca4d7793a4a", + "interestedParty": "aa0e0553ba45", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "94a6a6e6-3551-48b9-8333-0c71c71deeae", + "declarationSubject": "329e52e937c2", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "329e52e937c2", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "c34f3dc7-e633-44da-b9f5-e77a656d0e0e", + "declarationSubject": "329e52e937c2", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "0b54fb572826", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "2a3a28a8-b141-4529-82da-74cd4dff3321", + "declarationSubject": "329e52e937c2", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f4999ac47090", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "329e52e937c2", + "interestedParty": "0b54fb572826", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "2ecc2315-4c79-44dc-add0-596935a8b5d5", + "declarationSubject": "4ab4b34fc916", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "4ab4b34fc916", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "dcd14b55-9f7d-49f9-b319-431918c3afc2", + "declarationSubject": "4ab4b34fc916", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "0c638ee09e0e", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "878658c6-6392-4be1-a984-5f3bbb6b0a97", + "declarationSubject": "4ab4b34fc916", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "071bd271861e", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "4ab4b34fc916", + "interestedParty": "0c638ee09e0e", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "acdfa889-5cfa-4b6c-9e36-832e3c840085", + "declarationSubject": "4f1c8c3c032c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "4f1c8c3c032c", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "35fe45e7-b405-4422-be24-fab49c0475cf", + "declarationSubject": "4f1c8c3c032c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "619ba0ba425d", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "e56f8ee5-b16e-4042-b363-27b37c80ab60", + "declarationSubject": "4f1c8c3c032c", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "0345c2365681", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "4f1c8c3c032c", + "interestedParty": "619ba0ba425d", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "75cc915c-d46b-44fc-99ff-2453b6f54a71", + "declarationSubject": "70f341f83306", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "70f341f83306", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "547015b7-16af-4e53-80d2-527ba9b3a602", + "declarationSubject": "70f341f83306", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1684fa0256b9", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "32823ac2-53fb-4a67-9817-cfecc596281d", + "declarationSubject": "70f341f83306", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "7f3fe2c5d418", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "70f341f83306", + "interestedParty": "1684fa0256b9", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "5ed0bac1-94ef-4b61-8b6d-f177cedf3aac", + "declarationSubject": "abc11495946f", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "abc11495946f", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "c507df0d-bce1-4793-b067-8e670575fd9c", + "declarationSubject": "abc11495946f", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "198b59ca2d30", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "610605d8-064f-469e-b2fe-c0ed109bc490", + "declarationSubject": "abc11495946f", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "5fd56417897e", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "abc11495946f", + "interestedParty": "198b59ca2d30", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "a3c103a9-76aa-482f-bd25-43a3c28d6e7a", + "declarationSubject": "b26f77c6019e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b26f77c6019e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "85b58429-cd97-471b-bb05-f18f0d685dc9", + "declarationSubject": "b26f77c6019e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "d705d96b67bd", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "f63d4eb7-a52b-4e62-a995-5c6e5c05bd29", + "declarationSubject": "b26f77c6019e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "11ad834c3792", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "b26f77c6019e", + "interestedParty": "d705d96b67bd", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "acc16843-9320-4e51-991b-fb0693628715", + "declarationSubject": "509b19e95cfd", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "509b19e95cfd", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "4d8a7537-8060-4b86-bd08-c1727edaa52a", + "declarationSubject": "509b19e95cfd", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ab6e41a8a1b0", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "e5014715-5e6d-4db6-b551-f55398998e45", + "declarationSubject": "509b19e95cfd", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "434cddce24fc", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "509b19e95cfd", + "interestedParty": "ab6e41a8a1b0", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "c0fd8e25-f64b-4669-85d6-2a0528c3d16b", + "declarationSubject": "e93798c125d3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e93798c125d3", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "ad726b32-060a-4915-8ad6-74956d2955b2", + "declarationSubject": "e93798c125d3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "94e64ecc9d2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "d16998b6-295d-4688-b1da-ffe13a5bf853", + "declarationSubject": "e93798c125d3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "eeb64793afb1", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "e93798c125d3", + "interestedParty": "94e64ecc9d2c", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "7cd31b8d-6c07-4430-9c02-2e20965d8e64", + "declarationSubject": "2881741d3b8b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2881741d3b8b", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "fdda932a-5649-4356-9552-5f70ff4e3de2", + "declarationSubject": "2881741d3b8b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "82a6fe6524ec", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "af7eecbb-22dd-4f23-97dd-a907a91793e0", + "declarationSubject": "2881741d3b8b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ab2065d385af", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "2881741d3b8b", + "interestedParty": "82a6fe6524ec", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "996d1ec0-b98d-45b0-a99e-6bc30e79f22f", + "declarationSubject": "2ffb7e5cdf52", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2ffb7e5cdf52", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "8a6aae35-0fca-41aa-af02-2e758f79d0df", + "declarationSubject": "2ffb7e5cdf52", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "03cc9f3fbb4a", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "e9009888-8f2e-4e66-bfb6-2acde7ca636b", + "declarationSubject": "2ffb7e5cdf52", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "d94db2f8d887", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "2ffb7e5cdf52", + "interestedParty": "03cc9f3fbb4a", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "3309c9b4-d14e-4715-b214-127334cf71e7", + "declarationSubject": "5d20a2967c68", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "5d20a2967c68", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "52e6d4d7-5a56-40b4-a5f4-83f6be78f176", + "declarationSubject": "5d20a2967c68", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8cc88003c1a9", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "96d22f56-a49a-4737-8c7f-3f3872c13123", + "declarationSubject": "5d20a2967c68", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "d2711c6b4e3d", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "5d20a2967c68", + "interestedParty": "8cc88003c1a9", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "ff1392dd-d27d-4153-833b-0bd2d3bfc00e", + "declarationSubject": "642f337b03e7", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "642f337b03e7", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "f15109db-8966-45b8-abdf-4ddbe4b21688", + "declarationSubject": "642f337b03e7", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "fccfeb5b1844", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "deed77ac-0e08-4bcd-9cfa-7ae493a626b3", + "declarationSubject": "642f337b03e7", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "3023f3d82325", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "642f337b03e7", + "interestedParty": "fccfeb5b1844", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "09bfcf1b-080e-44a7-bff7-a3162ac5b799", + "declarationSubject": "42c77d6a353e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "42c77d6a353e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "04aab453-3fc0-4241-919c-79cc6c56f10e", + "declarationSubject": "42c77d6a353e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "842a21a5e116", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "b8897721-3022-4c60-94ae-f0691482da04", + "declarationSubject": "42c77d6a353e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "884a40fca9ce", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "42c77d6a353e", + "interestedParty": "842a21a5e116", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "ed02a984-65e3-41c9-a66d-f7bf608884d5", + "declarationSubject": "434938b67c01", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "434938b67c01", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "e58d7981-47bb-4db5-ab27-871eb1fd2b92", + "declarationSubject": "434938b67c01", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "7792f8926e85", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "42723b28-9a82-4b04-9475-978e10b79954", + "declarationSubject": "434938b67c01", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "94d5e28b8296", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "434938b67c01", + "interestedParty": "7792f8926e85", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "1a1c56c6-8432-4969-8eb6-279fe4c549e1", + "declarationSubject": "798275370b5b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "798275370b5b", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "a46dffea-2deb-4c15-b82b-b9eb590f91bb", + "declarationSubject": "798275370b5b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9b97f2172a70", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "73b35715-905e-45ed-b7a0-4d7ff82fb24d", + "declarationSubject": "798275370b5b", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ad06a2c48d0a", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "798275370b5b", + "interestedParty": "9b97f2172a70", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "9393d0fc-e6a8-42d7-a12d-9f811b422f66", + "declarationSubject": "ce3179970934", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ce3179970934", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "571115e7-e1fc-4c57-9d66-f7918c8f1334", + "declarationSubject": "ce3179970934", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "134b24bb2f5f", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "743ab969-8899-4836-af77-4953d20b3cb4", + "declarationSubject": "ce3179970934", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "3273b2297961", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ce3179970934", + "interestedParty": "134b24bb2f5f", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "603949d1-fa26-4d5f-a7da-e14f2c23e99a", + "declarationSubject": "553af1ab1001", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "553af1ab1001", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "58c0b7e9-cdbf-4426-a17e-2c9885710ed8", + "declarationSubject": "553af1ab1001", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "a0d78f00651e", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "df4afc82-9202-4624-aeb9-f2c8e7d13027", + "declarationSubject": "553af1ab1001", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "f20c2f61efa1", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "553af1ab1001", + "interestedParty": "a0d78f00651e", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "7d950e4a-d20e-4643-8b8f-c381ae6a2cb0", + "declarationSubject": "01937b834e3e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "01937b834e3e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "b3ae9976-cde0-4fa5-8149-e3fcc9103f25", + "declarationSubject": "01937b834e3e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "dd033dc5cd2f", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "959e8001-d18a-479a-93da-46ec190f3c06", + "declarationSubject": "01937b834e3e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "b9f2328a1db4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "01937b834e3e", + "interestedParty": "dd033dc5cd2f", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "8ccd4352-372b-48a2-ad7a-cafea340768c", + "declarationSubject": "e994bb2e0ab6", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e994bb2e0ab6", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "f2361d4a-448c-4cb0-b476-4585f5555687", + "declarationSubject": "e994bb2e0ab6", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "48149c211427", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "c28e0e25-74df-4b0a-8962-ab9047833eaf", + "declarationSubject": "e994bb2e0ab6", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "2dc2f28b2dcf", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "e994bb2e0ab6", + "interestedParty": "48149c211427", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "cb48855a-85c7-4c34-a320-1bc65b298701", + "declarationSubject": "8e1c8b9f9537", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "8e1c8b9f9537", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "f1c000ac-5c0e-4428-91ca-f15d87966077", + "declarationSubject": "8e1c8b9f9537", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "e1468b7c9ad8", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "6047e7ae-fa0e-4a3b-9ae9-91e17577cbfa", + "declarationSubject": "8e1c8b9f9537", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "451c49e53068", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "8e1c8b9f9537", + "interestedParty": "e1468b7c9ad8", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "70860792-c3d3-410b-8d72-9c6e4013970e", + "declarationSubject": "9cb5d1284aad", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9cb5d1284aad", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "439c0ad3-8ae5-4014-adba-4a1645bb8532", + "declarationSubject": "9cb5d1284aad", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9c3d894be75b", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "2c47b19b-f6a5-4303-93e2-96c07f402b31", + "declarationSubject": "9cb5d1284aad", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "3e1d328b1437", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "9cb5d1284aad", + "interestedParty": "9c3d894be75b", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "06a885a8-7794-4aa4-bf33-ada8f9f4f055", + "declarationSubject": "5ddfcc83589e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "5ddfcc83589e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "80e676de-f788-4474-97a0-9097b47c2e91", + "declarationSubject": "5ddfcc83589e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "91a4e81509bc", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "edb64fca-a59d-4059-91a7-5136bb33865d", + "declarationSubject": "5ddfcc83589e", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "ca28513c6eac", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "5ddfcc83589e", + "interestedParty": "91a4e81509bc", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "ab1aeab0-38ea-4cac-8d1e-ad80fab00c4d", + "declarationSubject": "fec937a3240f", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "fec937a3240f", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "2681913a-3f29-448a-af23-51591ac70053", + "declarationSubject": "fec937a3240f", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1dbd6ee5b694", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "5741df8e-7ce9-4d60-85b7-49af94301c8f", + "declarationSubject": "fec937a3240f", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "134866c88446", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "fec937a3240f", + "interestedParty": "1dbd6ee5b694", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "bc95c5a5-b691-4125-9bd9-d58758748d87", + "declarationSubject": "cf10c8bd4060", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "cf10c8bd4060", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "80bf307d-da6e-4a47-96ad-4833061887d4", + "declarationSubject": "cf10c8bd4060", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "d91334b376ff", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "eb7d4745-8246-4114-ac86-b2e881eb857f", + "declarationSubject": "cf10c8bd4060", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "919cb7971ad4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "cf10c8bd4060", + "interestedParty": "d91334b376ff", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "c3eb48cc-54e4-40c2-82f2-6c25b7bf81e7", + "declarationSubject": "d41f3ee64ed1", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "d41f3ee64ed1", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "8abcdea2-c8e6-48ee-93cb-74fb3b5cfbd2", + "declarationSubject": "d41f3ee64ed1", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "a64db057ce23", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "3fe7feef-ea04-4751-9c47-a3319b73e630", + "declarationSubject": "d41f3ee64ed1", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "fd36bc8d1813", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "d41f3ee64ed1", + "interestedParty": "a64db057ce23", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "c19be8b8-6395-41b0-938a-1a7a6f4e0827", + "declarationSubject": "6f847de52834", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "6f847de52834", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "9fec0d51-07d5-4cb0-a997-715c40678f4d", + "declarationSubject": "6f847de52834", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "1b45a5faf2ae", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "8181ffd5-a419-4111-a8b0-e2a0ca9bbdaa", + "declarationSubject": "6f847de52834", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "9cbc470ddc45", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "6f847de52834", + "interestedParty": "1b45a5faf2ae", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + }, + { + "statementId": "9cff670d-afeb-4b86-b564-6c1248994a27", + "declarationSubject": "104e4bdcf9a3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "104e4bdcf9a3", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Profitech Ltd", + "foundingDate": "2019-09-03", + "identifiers": [ + { + "scheme": "GB-COH", + "id": "2063384560" + } + ] + } + }, + { + "statementId": "1f3124ec-b5da-4242-9502-54f8fade8196", + "declarationSubject": "104e4bdcf9a3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "34c043de1546", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + ], + "names": [ + { + "type": "legal", + "fullName": "Jennifer Hewitson-Smith", + "givenName": "Jennifer", + "familyName": "Hewitson-Smith" + }, + { + "type": "alternative", + "fullName": "Jenny Hewitson-Smith" + } + ], + "birthDate": "1978-07", + "addresses": [ + { + "type": "service", + "address": "76 York Road Bournemouth", + "postCode": "BH81 3LO", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + }, + { + "statementId": "23b3396a-1f91-48dc-b4c8-161f38c60fe3", + "declarationSubject": "104e4bdcf9a3", + "statementDate": "2020-03-04", + "publicationDetails": { + "publicationDate": "2020-03-04", + "bodsVersion": "0.4", + "publisher": { + "name": "Profitech Ltd" + } + }, + "recordId": "95f69e87f352", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "104e4bdcf9a3", + "interestedParty": "34c043de1546", + "interests": [ + { + "type": "shareholding", + "beneficialOwnershipOrControl": true, + "directOrIndirect": "direct", + "startDate": "2016-04-06", + "share": { + "exact": 100 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/statistic_count_declaration_subjects.json b/tests/fixtures/0.4/statistic_count_declaration_subjects.json new file mode 100644 index 0000000..1cc6e40 --- /dev/null +++ b/tests/fixtures/0.4/statistic_count_declaration_subjects.json @@ -0,0 +1,152 @@ +[ + { + "statementId": "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "afca12b4-b44a-4c74-8ad1-2110e263946f", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-04-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "46c5218d-2e48-4858-adaf-a596848c1de3", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "c359f58d2977", + "recordType": "entity", + "recordStatus": "closed", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "019a93f1-e470-42e9-957b-03559861b2e2", + "declarationSubject": "c359f58d2977", + "statementDate": "2020-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "new", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "ecdff7a6-e231-42dc-bfcd-7c124c33cd6a", + "declarationSubject": "c359f58d2977", + "statementDate": "2021-03-04", + "recordId": "10478c6cf6de", + "recordType": "person", + "recordStatus": "updated", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "8729fec1-eb01-4866-ba40-dd5525d43db8", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "ad3f6c2fcc9e", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "e2bbe3ce-f5b4-42d0-bb68-9b405e8fd6a0", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d4ab89ea169a", + "recordStatus": "new", + "recordType": "entity", + "recordDetails": { + "isComponent": true, + "entityType": { + "type": "registeredEntity" + } + } + }, + { + "statementId": "6b9cfb52-505a-49cb-ab02-cc856a4e5c66", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "c25d4d612c2c", + "recordStatus": "new", + "recordType": "person", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + }, + { + "statementId": "7fff3986-233f-413f-bec8-3b28c62a4a51", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "4cf2837bd01f", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "ad3f6c2fcc9e", + "interestedParty": "d4ab89ea169a" + } + }, + { + "statementId": "860155d1-a4fb-4742-9735-7a7deb899075", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "05e81af035e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": true, + "subject": "d4ab89ea169a", + "interestedParty": "c25d4d612c2c" + } + }, + { + "statementId": "cdb6acc7-426e-4a7a-9410-895d556fd329", + "declarationSubject": "ad3f6c2fcc9e", + "statementDate": "2018-12-17", + "recordId": "d8d75ccf40e4", + "recordStatus": "new", + "recordType": "relationship", + "recordDetails": { + "isComponent": false, + "subject": "ad3f6c2fcc9e", + "interestedParty": "c25d4d612c2c", + "componentRecords": [ + "d4ab89ea169a", + "4cf2837bd01f", + "05e81af035e4" + ] + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity.json b/tests/fixtures/0.4/valid-schema/entity.json new file mode 100644 index 0000000..9661e54 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity.json @@ -0,0 +1,58 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2021-09-11T16:15:08Z", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "license": "http://opendefinition.org/licenses/cc-zero", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "recordStatus": "updated", + "declarationSubject": "ent-93c75c87ab28f889", + "source": { + "assertedBy": [ + { + "name": "Mary Walsh" + } + ] + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Fermentcat Ltd", + "jurisdiction": { + "code": "IE", + "name": "Ireland" + }, + "foundingDate": "2019-09-11", + "publicListing": { + "hasPublicListing": false + }, + "identifiers": [ + { + "id": "434151", + "scheme": "IE-BAU", + "schemeName": "Irish Business Authority " + } + ], + "addresses": [ + { + "type": "registered", + "address": "53 Killard, Kilteragh, Dooradoyle, Co. Limerick ", + "postCode": "V94 V3VT", + "country": { + "name": "Ireland", + "code": "IE" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_2.json b/tests/fixtures/0.4/valid-schema/entity_2.json new file mode 100644 index 0000000..84a58df --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_2.json @@ -0,0 +1,47 @@ +[ + { + "statementId": "crxpru319949212398855320030147004728", + "statementDate": "2019-01-20", + "publicationDetails": { + "publicationDate": "2019-01-31", + "bodsVersion": "0.4", + "license": "http://opendefinition.org/licenses/cc-zero", + "publisher": { + "name": "Company Register, Delaware" + } + }, + "recordId": "01B68D7633", + "recordType": "entity", + "recordStatus": "new", + "source": { + "type": [ + "selfDeclaration" + ], + "assertedBy": [ + { + "name": "Maria Esteves" + } + ] + }, + "declaration": "bo-jtc-8755982746", + "declarationSubject": "01B68D7633", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Tecido Ltd", + "jurisdiction": { + "name": "Delaware", + "code": "US-DE" + }, + "foundingDate": "2002-03-09", + "identifiers": [ + { + "id": "758355", + "schemeName": "Company Registry, Delaware. Company number" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_address_address.json b/tests/fixtures/0.4/valid-schema/entity_address_address.json new file mode 100644 index 0000000..6da7160 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_address_address.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "addresses": [ + { + "address": "53 Killard, Kilteragh, Dooradoyle, Co. Limerick " + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_address_country.json b/tests/fixtures/0.4/valid-schema/entity_address_country.json new file mode 100644 index 0000000..5bcb601 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_address_country.json @@ -0,0 +1,26 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "registered", + "address": "53 Killard, Kilteragh, Dooradoyle, Co. Limerick ", + "postCode": "V94 V3VT", + "country": { + "name": "Ireland", + "code": "IE" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_address_country_2.json b/tests/fixtures/0.4/valid-schema/entity_address_country_2.json new file mode 100644 index 0000000..3bff3c6 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_address_country_2.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "addresses": [ + { + "country": { + "name": "Ireland", + "code": "IE" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_address_country_no_code.json b/tests/fixtures/0.4/valid-schema/entity_address_country_no_code.json new file mode 100644 index 0000000..203d375 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_address_country_no_code.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "registered", + "address": "53 Killard, Kilteragh, Dooradoyle, Co. Limerick ", + "postCode": "V94 V3VT", + "country": { + "name": "Ireland" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_address_postcode.json b/tests/fixtures/0.4/valid-schema/entity_address_postcode.json new file mode 100644 index 0000000..2fea138 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_address_postcode.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "addresses": [ + { + "postCode": "V94 V3VT" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_address_type.json b/tests/fixtures/0.4/valid-schema/entity_address_type.json new file mode 100644 index 0000000..ce02aab --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_address_type.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "addresses": [ + { + "type": "registered" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_addresses_type.json b/tests/fixtures/0.4/valid-schema/entity_addresses_type.json new file mode 100644 index 0000000..a76f67c --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_addresses_type.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "addresses": [ + { + "type": "business", + "address": "23 Regent St, London", + "country": { + "name": "United Kingdom", + "code": "GB" + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_alternate_names.json b/tests/fixtures/0.4/valid-schema/entity_alternate_names.json new file mode 100644 index 0000000..2d52a89 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_alternate_names.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "alternateNames": [ + "Fermentcat Ltd" + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_dissolution_date.json b/tests/fixtures/0.4/valid-schema/entity_dissolution_date.json new file mode 100644 index 0000000..4ef06bc --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_dissolution_date.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "dissolutionDate": "2019-09-11" + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_formed_by_statute.json b/tests/fixtures/0.4/valid-schema/entity_formed_by_statute.json new file mode 100644 index 0000000..8c3e654 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_formed_by_statute.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody" + }, + "formedByStatute": { + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_formed_by_statute_date.json b/tests/fixtures/0.4/valid-schema/entity_formed_by_statute_date.json new file mode 100644 index 0000000..b13bc4a --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_formed_by_statute_date.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody" + }, + "formedByStatute": { + "date": "2019-03-04" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_formed_by_statute_name.json b/tests/fixtures/0.4/valid-schema/entity_formed_by_statute_name.json new file mode 100644 index 0000000..284294e --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_formed_by_statute_name.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody" + }, + "formedByStatute": { + "name": "statute 123" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_founding_date.json b/tests/fixtures/0.4/valid-schema/entity_founding_date.json new file mode 100644 index 0000000..3f954ac --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_founding_date.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "foundingDate": "2019-09-11" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_government_body.json b/tests/fixtures/0.4/valid-schema/entity_government_body.json new file mode 100644 index 0000000..ce10123 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_government_body.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-01-01", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody", + "subtype": "governmentDepartment" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_identifiers_id.json b/tests/fixtures/0.4/valid-schema/entity_identifiers_id.json new file mode 100644 index 0000000..8c5f9ed --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_identifiers_id.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "identifiers": [ + { + "id": "434151", + "scheme": "IE-BAU" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_identifiers_scheme.json b/tests/fixtures/0.4/valid-schema/entity_identifiers_scheme.json new file mode 100644 index 0000000..ac33867 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_identifiers_scheme.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "identifiers": [ + { + "scheme": "IE-BAU" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_identifiers_scheme_name.json b/tests/fixtures/0.4/valid-schema/entity_identifiers_scheme_name.json new file mode 100644 index 0000000..7ce8421 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_identifiers_scheme_name.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "identifiers": [ + { + "schemeName": "Irish Business Authority " + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_identifiers_uri.json b/tests/fixtures/0.4/valid-schema/entity_identifiers_uri.json new file mode 100644 index 0000000..46ba3e5 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_identifiers_uri.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "declarationSubject": "eyh3827439", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false, + "identifiers": [ + { + "schemeName": "64732", + "id": "2475625", + "uri": "http://www.righturl.com" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_jurisdiction_code.json b/tests/fixtures/0.4/valid-schema/entity_jurisdiction_code.json new file mode 100644 index 0000000..94a55ca --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_jurisdiction_code.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "jurisdiction": { + "name": "Ireland", + "code": "IE" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_jurisdiction_name.json b/tests/fixtures/0.4/valid-schema/entity_jurisdiction_name.json new file mode 100644 index 0000000..391ae93 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_jurisdiction_name.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "jurisdiction": { + "name": "Ireland" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_name.json b/tests/fixtures/0.4/valid-schema/entity_name.json new file mode 100644 index 0000000..074dea5 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_name.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "name": "Fermentcat Ltd" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_nomination.json b/tests/fixtures/0.4/valid-schema/entity_nomination.json new file mode 100644 index 0000000..b4c7105 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_nomination.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2018-09-01", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement", + "subtype": "nomination" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_public_listing.json b/tests/fixtures/0.4/valid-schema/entity_public_listing.json new file mode 100644 index 0000000..c97356a --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_public_listing.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": false + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_public_listing_company_filings.json b/tests/fixtures/0.4/valid-schema/entity_public_listing_company_filings.json new file mode 100644 index 0000000..e7c9830 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_public_listing_company_filings.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing": { + "hasPublicListing": false, + "companyFilingsURLs": [ + "https://www.test.org" + ] + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_security_MIC.json b/tests/fixtures/0.4/valid-schema/entity_security_MIC.json new file mode 100644 index 0000000..5172d92 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_security_MIC.json @@ -0,0 +1,28 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "marketIdentifierCode": "MIC code", + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_security_OMIC.json b/tests/fixtures/0.4/valid-schema/entity_security_OMIC.json new file mode 100644 index 0000000..5bb49ee --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_security_OMIC.json @@ -0,0 +1,28 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "operatingMarketIdentifierCode": "MIC code", + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_security_id.json b/tests/fixtures/0.4/valid-schema/entity_security_id.json new file mode 100644 index 0000000..7125149 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_security_id.json @@ -0,0 +1,28 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT", + "id": "12345" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_security_idscheme.json b/tests/fixtures/0.4/valid-schema/entity_security_idscheme.json new file mode 100644 index 0000000..79bcf7d --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_security_idscheme.json @@ -0,0 +1,28 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT", + "idScheme": "isin" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_security_listing.json b/tests/fixtures/0.4/valid-schema/entity_security_listing.json new file mode 100644 index 0000000..16ec5dc --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_security_listing.json @@ -0,0 +1,27 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "publicListing":{ + "hasPublicListing" : true, + "securitiesListings": [ + { + "security": { + "ticker": "FMT" + }, + "stockExchangeName" :"Irish stock exchange", + "stockExchangeJurisdiction": "IE" + } + ] + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_statementDate.json b/tests/fixtures/0.4/valid-schema/entity_statementDate.json new file mode 100644 index 0000000..86e48fd --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_statementDate.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_statementDate_time.json b/tests/fixtures/0.4/valid-schema/entity_statementDate_time.json new file mode 100644 index 0000000..a9eee4b --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_statementDate_time.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2020-09-11T16:30:23Z", + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "registeredEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_trust_legal_entity.json b/tests/fixtures/0.4/valid-schema/entity_trust_legal_entity.json new file mode 100644 index 0000000..c103e38 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_trust_legal_entity.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2022-01-08", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "legalEntity", + "subtype": "trust" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_type_details.json b/tests/fixtures/0.4/valid-schema/entity_type_details.json new file mode 100644 index 0000000..9d8bdf3 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_type_details.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-01-01", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody", + "details": "department for transport" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_type_registered_entity_subtype.json b/tests/fixtures/0.4/valid-schema/entity_type_registered_entity_subtype.json new file mode 100644 index 0000000..6ad7099 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_type_registered_entity_subtype.json @@ -0,0 +1,17 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity", + "subtype": "other", + "details": "other type of entity" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_type_statebody_other.json b/tests/fixtures/0.4/valid-schema/entity_type_statebody_other.json new file mode 100644 index 0000000..434387e --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_type_statebody_other.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2017-01-01", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "stateBody", + "subtype": "other" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_type_trust_arrangement.json b/tests/fixtures/0.4/valid-schema/entity_type_trust_arrangement.json new file mode 100644 index 0000000..f43e9b3 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_type_trust_arrangement.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "statementDate": "2022-01-08", + "publicationDetails": { + "publicationDate": "2021-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "arrangement", + "subtype": "trust" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_unspecified_entity_description.json b/tests/fixtures/0.4/valid-schema/entity_unspecified_entity_description.json new file mode 100644 index 0000000..1588469 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_unspecified_entity_description.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "unknownEntity" + }, + "unspecifiedEntityDetails": { + "reason": "noBeneficialOwners", + "description": "no shareholders with over 10% of shares" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/entity_unspecified_entity_details.json b/tests/fixtures/0.4/valid-schema/entity_unspecified_entity_details.json new file mode 100644 index 0000000..850b281 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_unspecified_entity_details.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "unknownEntity" + }, + "unspecifiedEntityDetails": { + "reason": "noBeneficialOwners" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/entity_uri.json b/tests/fixtures/0.4/valid-schema/entity_uri.json new file mode 100644 index 0000000..bcf3cfb --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/entity_uri.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + }, + "uri": "https://www.example.com/index.html" + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/person.json b/tests/fixtures/0.4/valid-schema/person.json new file mode 100644 index 0000000..3c037d6 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person.json @@ -0,0 +1,53 @@ +[{ + "statementId": "733b20a572f8b306b538344c7946c9cb", + "statementDate": "2019-09-11T11:17:23Z", + "publicationDetails": { + "publicationDate": "2019-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "license": "http://opendefinition.org/licenses/cc-zero", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "recordStatus": "new", + "declarationSubject": "ent-93c75c87ab28f889", + "source": { + "assertedBy": [ + { + "name": "Riyadh Byrne-Amin" + } + ] + }, + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "type": "legal", + "fullName": "Riyadh Byrne-Amin", + "familyName": "Byrne-Amin", + "givenName": "Riyadh" + } + ], + "birthDate": "1990-06-12", + "identifiers": [ + { + "id": "7700225VH", + "scheme": "IRL-TAXID", + "schemeName": "Ireland Personal Public Service Number" + } + ], + "nationalities": [ + { + "name": "Iraq", + "code": "IQ" + }, + { + "name": "Ireland", + "code": "IE" + } + ] + } +}] diff --git a/tests/fixtures/0.4/valid-schema/person_2.json b/tests/fixtures/0.4/valid-schema/person_2.json new file mode 100644 index 0000000..e7c7c4b --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_2.json @@ -0,0 +1,40 @@ +[ + { + "statementId": "crxpru288148613461215288221503762424", + "statementDate": "2019-01-20", + "publicationDetails": { + "publicationDate": "2019-01-31", + "bodsVersion": "0.4", + "license": "http://opendefinition.org/licenses/cc-zero", + "publisher": { + "name": "Company Register, Delaware" + } + }, + "recordId": "018AF6B3EB", + "recordType": "person", + "recordStatus": "new", + "source": { + "type": ["selfDeclaration"], + "assertedBy": [ + { + "name": "Maria Esteves" + } + ] + }, + "declaration": "bo-jtc-8755982746", + "declarationSubject": "01B68D7633", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "type": "legal", + "fullName": "Maria Esteves", + "familyName": "Esteves", + "givenName": "Maria" + } + ], + "birthDate": "1956-05-24" + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_endDate.json b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_endDate.json new file mode 100644 index 0000000..1441a89 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_endDate.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "endDate": "2020-10-15" + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_jurisdiction.json b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_jurisdiction.json new file mode 100644 index 0000000..bedc637 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_jurisdiction.json @@ -0,0 +1,24 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "jurisdiction": { + "code": "GB", + "name": "United Kingdom of Great Britain and Northern Ireland (the)" + } + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_missingInfoReason.json b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_missingInfoReason.json new file mode 100644 index 0000000..4d889f2 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_missingInfoReason.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "unknown", + "details": [ + { + "missingInfoReason": "Awaiting record" + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_reason.json b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_reason.json new file mode 100644 index 0000000..9f46142 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_reason.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "reason": "Member of Parliament" + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_source.json b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_source.json new file mode 100644 index 0000000..56d5e5a --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_source.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "source": { + "type": [ + "selfDeclaration" + ] + } + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_startDate.json b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_startDate.json new file mode 100644 index 0000000..48b49c6 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_PepStatusDetails_startDate.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep", + "details": [ + { + "startDate": "2016-10-15" + } + ] + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_addresses_type.json b/tests/fixtures/0.4/valid-schema/person_addresses_type.json new file mode 100644 index 0000000..dbe5d8d --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_addresses_type.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "recordId": "123", + "recordType": "person", + "recordDetails": { + "personType": "knownPerson", + "isComponent": false, + "addresses": [ + { + "type":"residence", + "address": "23 Regent St, London", + "country": { + "name": "United Kingdom", + "code":"GB" + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/person_birth_date.json b/tests/fixtures/0.4/valid-schema/person_birth_date.json new file mode 100644 index 0000000..b9128bd --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_birth_date.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1990-06-12" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_birth_date_year.json b/tests/fixtures/0.4/valid-schema/person_birth_date_year.json new file mode 100644 index 0000000..77d0f12 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_birth_date_year.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1990" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_birth_date_year_month.json b/tests/fixtures/0.4/valid-schema/person_birth_date_year_month.json new file mode 100644 index 0000000..c63f6fe --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_birth_date_year_month.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "birthDate": "1990-06" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_birth_place.json b/tests/fixtures/0.4/valid-schema/person_birth_place.json new file mode 100644 index 0000000..25ce175 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_birth_place.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "placeOfBirth":{ + "type": "placeOfBirth", + "country": { + "code":"IE", + "name":"Ireland" + } + } + + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/person_death_date_full.json b/tests/fixtures/0.4/valid-schema/person_death_date_full.json new file mode 100644 index 0000000..6c995ee --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_death_date_full.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "deathDate": "2001-06-12" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_death_date_year.json b/tests/fixtures/0.4/valid-schema/person_death_date_year.json new file mode 100644 index 0000000..2a2a6e0 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_death_date_year.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "deathDate": "2001" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_death_date_year_month.json b/tests/fixtures/0.4/valid-schema/person_death_date_year_month.json new file mode 100644 index 0000000..33f2d94 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_death_date_year_month.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "deathDate": "2001-06" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_identifiers_id.json b/tests/fixtures/0.4/valid-schema/person_identifiers_id.json new file mode 100644 index 0000000..60d1f0d --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_identifiers_id.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [ + { + "id": "7700225VH", + "scheme": "IRL-TAXID" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/person_identifiers_scheme.json b/tests/fixtures/0.4/valid-schema/person_identifiers_scheme.json new file mode 100644 index 0000000..14136ef --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_identifiers_scheme.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [ + { + "scheme": "IRL-TAXID" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/person_identifiers_scheme_name.json b/tests/fixtures/0.4/valid-schema/person_identifiers_scheme_name.json new file mode 100644 index 0000000..9f4949a --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_identifiers_scheme_name.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "identifiers": [ + { + "schemeName": "Ireland Personal Public Service Number" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_names_family_name.json b/tests/fixtures/0.4/valid-schema/person_names_family_name.json new file mode 100644 index 0000000..474f581 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_names_family_name.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "familyName": "Byrne-Amin", + "fullName": "Riyadh Byrne-Amin" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_names_full_name.json b/tests/fixtures/0.4/valid-schema/person_names_full_name.json new file mode 100644 index 0000000..2213f07 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_names_full_name.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "fullName": "Riyadh Byrne-Amin" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_names_given_name.json b/tests/fixtures/0.4/valid-schema/person_names_given_name.json new file mode 100644 index 0000000..fdf0f36 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_names_given_name.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "givenName": "Riyadh", + "fullName": "Riyadh Byrne-Amin" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_names_patronymic.json b/tests/fixtures/0.4/valid-schema/person_names_patronymic.json new file mode 100644 index 0000000..66c11c2 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_names_patronymic.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "patronymicName": "Sergeyevich", + "fullName": "Yuri Sergeyevich" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_names_type.json b/tests/fixtures/0.4/valid-schema/person_names_type.json new file mode 100644 index 0000000..363e427 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_names_type.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "names": [ + { + "type": "legal", + "fullName": "Riyadh Byrne-Amin" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/person_nationalities_code.json b/tests/fixtures/0.4/valid-schema/person_nationalities_code.json new file mode 100644 index 0000000..20dba87 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_nationalities_code.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "name": "Iraq", + "code": "IQ" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_nationalities_name.json b/tests/fixtures/0.4/valid-schema/person_nationalities_name.json new file mode 100644 index 0000000..a8076d8 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_nationalities_name.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "nationalities": [ + { + "name": "Iraq" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_politicalExposure_object.json b/tests/fixtures/0.4/valid-schema/person_politicalExposure_object.json new file mode 100644 index 0000000..fbf1362 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_politicalExposure_object.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "politicalExposure": { + "status": "isPep" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_taxResidencies.json b/tests/fixtures/0.4/valid-schema/person_taxResidencies.json new file mode 100644 index 0000000..41a275c --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_taxResidencies.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson", + "taxResidencies": [ + { + "name": "Ireland", + "code": "IE" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/person_unspecified_person_details.json b/tests/fixtures/0.4/valid-schema/person_unspecified_person_details.json new file mode 100644 index 0000000..a581913 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/person_unspecified_person_details.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "unknownPerson", + "unspecifiedPersonDetails": { + "reason": "unknown" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/publication_details_date.json b/tests/fixtures/0.4/valid-schema/publication_details_date.json new file mode 100644 index 0000000..0a41e57 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/publication_details_date.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "bodsVersion": "0.4", + "publisher": { + "name": "Test Publisher" + }, + "publicationDate": "2021-09-11T00:00:00+00:00" + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/publication_details_license.json b/tests/fixtures/0.4/valid-schema/publication_details_license.json new file mode 100644 index 0000000..432ae43 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/publication_details_license.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "name": "Test Publisher" + }, + "license": "http://opendefinition.org/licenses/cc-zero" + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/publication_details_publisher_name.json b/tests/fixtures/0.4/valid-schema/publication_details_publisher_name.json new file mode 100644 index 0000000..51cff00 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/publication_details_publisher_name.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/publication_details_publisher_name_url.json b/tests/fixtures/0.4/valid-schema/publication_details_publisher_name_url.json new file mode 100644 index 0000000..f8a8d1e --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/publication_details_publisher_name_url.json @@ -0,0 +1,23 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "name": "test", + "url": "https://www.test.org" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/publication_details_publisher_url.json b/tests/fixtures/0.4/valid-schema/publication_details_publisher_url.json new file mode 100644 index 0000000..7fe238a --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/publication_details_publisher_url.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "bodsVersion": "0.4", + "publisher": { + "url": "https://www.test.org" + } + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/publication_details_version.json b/tests/fixtures/0.4/valid-schema/publication_details_version.json new file mode 100644 index 0000000..ee6832b --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/publication_details_version.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "publicationDetails": { + "publicationDate": "2021-09-11", + "publisher": { + "name": "Test Publisher" + }, + "bodsVersion": "0.4" + }, + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/record_status.json b/tests/fixtures/0.4/valid-schema/record_status.json new file mode 100644 index 0000000..7cceb68 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/record_status.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "733b20a572f8b306b538344c7946c9cb", + "recordId": "per-5faa4103dee78621", + "recordType": "person", + "recordStatus": "new", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "personType": "knownPerson" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship.json b/tests/fixtures/0.4/valid-schema/relationship.json new file mode 100644 index 0000000..5739fad --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship.json @@ -0,0 +1,45 @@ +[{ + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "statementDate": "2020-09-11T16:30:23Z", + "publicationDetails": { + "publicationDate": "2020-09-11T00:00:00+00:00", + "bodsVersion": "0.4", + "license": "http://opendefinition.org/licenses/cc-zero", + "publisher": { + "name": "Irish Business Authority" + } + }, + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "recordStatus": "updated", + "declarationSubject": "ent-93c75c87ab28f889", + "source": { + "assertedBy": [ + { + "name": "Riyadh Byrne-Amin" + } + ] + }, + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "type": "shareholding", + "directOrIndirect": "direct", + "beneficialOwnershipOrControl": true, + "share": { + "exact": 50 + }, + "startDate": "2019-09-11" + }, + { + "type": "boardMember", + "directOrIndirect": "direct", + "beneficialOwnershipOrControl": true, + "startDate": "2019-09-11" + } + ] + } +}] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship_2.json b/tests/fixtures/0.4/valid-schema/relationship_2.json new file mode 100644 index 0000000..4fc82c8 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_2.json @@ -0,0 +1,60 @@ +[{ + "statementId": "crxpru407636437638495407739553674232", + "statementDate": "2019-01-20", + "publicationDetails": { + "publicationDate": "2019-01-31", + "bodsVersion": "0.4", + "license": "http://opendefinition.org/licenses/cc-zero", + "publisher": { + "name": "Company Register, Delaware" + } + }, + "recordId": "022EBEB66B", + "recordType": "relationship", + "recordStatus": "new", + "source": { + "type": ["selfDeclaration"], + "assertedBy": [ + { + "name": "Maria Esteves" + } + ] + }, + "declaration": "bo-jtc-8755982746", + "declarationSubject": "01B68D7633", + "recordDetails": { + "isComponent": false, + "subject": "01B68D7633", + "interestedParty": "018AF6B3EB", + "interests": [ + { + "type": "shareholding", + "directOrIndirect": "direct", + "beneficialOwnershipOrControl": true, + "share": { + "exact": 100, + "maximum": 100, + "minimum": 100 + }, + "startDate": "2002-03-09" + }, + { + "type": "votingRights", + "directOrIndirect": "direct", + "beneficialOwnershipOrControl": true, + "share": { + "exact": 100, + "maximum": 100, + "minimum": 100 + }, + "startDate": "2002-03-09" + }, + { + "type": "boardChair", + "directOrIndirect": "direct", + "beneficialOwnershipOrControl": true, + "startDate": "2002-03-09" + } + ] + } +}] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship_component_records.json b/tests/fixtures/0.4/valid-schema/relationship_component_records.json new file mode 100644 index 0000000..0161b73 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_component_records.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "componentRecords": [ + "per-1234", + "ent-5678", + "rel-7890" + ], + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/relationship_interested_party.json b/tests/fixtures/0.4/valid-schema/relationship_interested_party.json new file mode 100644 index 0000000..2d68a22 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interested_party.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship_interested_party_unspecified_object.json b/tests/fixtures/0.4/valid-schema/relationship_interested_party_unspecified_object.json new file mode 100644 index 0000000..eb90162 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interested_party_unspecified_object.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f88", + "interestedParty": { + "reason": "interestedPartyExemptFromDisclosure" + } + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/relationship_interests_beneficial_ownership_or_control.json b/tests/fixtures/0.4/valid-schema/relationship_interests_beneficial_ownership_or_control.json new file mode 100644 index 0000000..1707e83 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interests_beneficial_ownership_or_control.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "beneficialOwnershipOrControl": true + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship_interests_details.json b/tests/fixtures/0.4/valid-schema/relationship_interests_details.json new file mode 100644 index 0000000..ea58216 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interests_details.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "details": "details about interest" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/relationship_interests_direct_or_indirect.json b/tests/fixtures/0.4/valid-schema/relationship_interests_direct_or_indirect.json new file mode 100644 index 0000000..2dabbd7 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interests_direct_or_indirect.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "directOrIndirect": "direct" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship_interests_end_date.json b/tests/fixtures/0.4/valid-schema/relationship_interests_end_date.json new file mode 100644 index 0000000..25b5d68 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interests_end_date.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "endDate": "2019-09-11" + } + ] + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/relationship_interests_share.json b/tests/fixtures/0.4/valid-schema/relationship_interests_share.json new file mode 100644 index 0000000..6df170c --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interests_share.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "exact": 50 + } + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship_interests_share_exclusive_minmax.json b/tests/fixtures/0.4/valid-schema/relationship_interests_share_exclusive_minmax.json new file mode 100644 index 0000000..091c244 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interests_share_exclusive_minmax.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "share": { + "exclusiveMinimum": 25, + "exclusiveMaximum": 75 + } + } + ] + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/relationship_interests_start_date.json b/tests/fixtures/0.4/valid-schema/relationship_interests_start_date.json new file mode 100644 index 0000000..a717cf1 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interests_start_date.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "startDate": "2019-09-11" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship_interests_type.json b/tests/fixtures/0.4/valid-schema/relationship_interests_type.json new file mode 100644 index 0000000..8fa16c8 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_interests_type.json @@ -0,0 +1,19 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621", + "interests": [ + { + "type": "shareholding" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship_is_component_true.json b/tests/fixtures/0.4/valid-schema/relationship_is_component_true.json new file mode 100644 index 0000000..1d8db6c --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_is_component_true.json @@ -0,0 +1,15 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": true, + "componentRecords": [], + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/relationship_is_component_true2.json b/tests/fixtures/0.4/valid-schema/relationship_is_component_true2.json new file mode 100644 index 0000000..77c832c --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_is_component_true2.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": true, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/relationship_subject.json b/tests/fixtures/0.4/valid-schema/relationship_subject.json new file mode 100644 index 0000000..2d68a22 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_subject.json @@ -0,0 +1,14 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": "ent-93c75c87ab28f889", + "interestedParty": "per-5faa4103dee78621" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/relationship_subject_unspecified_object.json b/tests/fixtures/0.4/valid-schema/relationship_subject_unspecified_object.json new file mode 100644 index 0000000..a58095d --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/relationship_subject_unspecified_object.json @@ -0,0 +1,16 @@ +[ + { + "statementId": "9d167324c416bbfd37fe5c1a1b2afa95", + "recordId": "rel-b05e7c91e0a04e4f", + "recordType": "relationship", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "recordDetails": { + "isComponent": false, + "subject": { + "reason": "subjectExemptFromDisclosure" + }, + "interestedParty": "per-5faa4103dee78621" + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/source.json b/tests/fixtures/0.4/valid-schema/source.json new file mode 100644 index 0000000..9c8b9ed --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/source.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "assertedBy": [ + { + "name": "Mary Walsh" + } + ] + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_createdBy.json b/tests/fixtures/0.4/valid-schema/statement_annotations_createdBy.json new file mode 100644 index 0000000..897b98b --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_createdBy.json @@ -0,0 +1,24 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "createdBy": { + "name": "Joe Harris" + } + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_createdBy_uri.json b/tests/fixtures/0.4/valid-schema/statement_annotations_createdBy_uri.json new file mode 100644 index 0000000..d341eac --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_createdBy_uri.json @@ -0,0 +1,25 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "createdBy": { + "name": "Joe Harris", + "uri": "https://www.example.com/index.html" + } + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_creationDate.json b/tests/fixtures/0.4/valid-schema/statement_annotations_creationDate.json new file mode 100644 index 0000000..9fb39f9 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_creationDate.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "creationDate": "2017-11-20" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_creationDate_time.json b/tests/fixtures/0.4/valid-schema/statement_annotations_creationDate_time.json new file mode 100644 index 0000000..09db440 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_creationDate_time.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "creationDate": "2017-11-20T16:30:23Z" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_description.json b/tests/fixtures/0.4/valid-schema/statement_annotations_description.json new file mode 100644 index 0000000..5742194 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_description.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "description": "The interested party is a British MP and, at the time this statement was made, the Secretary of State for Health and Social Care." + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_empty_transformed.json b/tests/fixtures/0.4/valid-schema/statement_annotations_empty_transformed.json new file mode 100644 index 0000000..7603fa2 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_empty_transformed.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "correcting", + "transformedContent": "" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_statementPointerTarget.json b/tests/fixtures/0.4/valid-schema/statement_annotations_statementPointerTarget.json new file mode 100644 index 0000000..3e5395e --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_statementPointerTarget.json @@ -0,0 +1,21 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_transformedContent.json b/tests/fixtures/0.4/valid-schema/statement_annotations_transformedContent.json new file mode 100644 index 0000000..9bd3fad --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_transformedContent.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/statementDate", + "motivation": "transformation", + "transformedContent": "12-31-2020" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_url.json b/tests/fixtures/0.4/valid-schema/statement_annotations_url.json new file mode 100644 index 0000000..80215a1 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_url.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "identifying", + "url": "https://www.example.com/index.html" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/statement_annotations_url_linking.json b/tests/fixtures/0.4/valid-schema/statement_annotations_url_linking.json new file mode 100644 index 0000000..ff65dcb --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_annotations_url_linking.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "declarationSubject": "xyz", + "statementDate": "2017-11-18", + "annotations": [ + { + "statementPointerTarget": "/recordDetails/interestedParty", + "motivation": "linking", + "url": "https://www.example.com/index.html" + } + ], + "recordId": "123", + "recordType": "entity", + "recordDetails": { + "entityType": { + "type": "unknownEntity" + }, + "isComponent": false + } + } +] diff --git a/tests/fixtures/0.4/valid-schema/statement_source_assertedBy_uri.json b/tests/fixtures/0.4/valid-schema/statement_source_assertedBy_uri.json new file mode 100644 index 0000000..aba856a --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_source_assertedBy_uri.json @@ -0,0 +1,22 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "assertedBy": [ + { + "uri": "https://www.example.com/index.html" + } + ] + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_source_description.json b/tests/fixtures/0.4/valid-schema/statement_source_description.json new file mode 100644 index 0000000..e07dea4 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_source_description.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "description": "Official register updated annually" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_source_retrievedAt.json b/tests/fixtures/0.4/valid-schema/statement_source_retrievedAt.json new file mode 100644 index 0000000..14130fd --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_source_retrievedAt.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "retrievedAt": "2017-11-15" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_source_retrievedAt_time.json b/tests/fixtures/0.4/valid-schema/statement_source_retrievedAt_time.json new file mode 100644 index 0000000..a3af0b6 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_source_retrievedAt_time.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "retrievedAt": "2017-11-15T16:30:23Z" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_source_type.json b/tests/fixtures/0.4/valid-schema/statement_source_type.json new file mode 100644 index 0000000..cb60b17 --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_source_type.json @@ -0,0 +1,20 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "type": [ + "selfDeclaration" + ] + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/fixtures/0.4/valid-schema/statement_source_url.json b/tests/fixtures/0.4/valid-schema/statement_source_url.json new file mode 100644 index 0000000..80d8f2c --- /dev/null +++ b/tests/fixtures/0.4/valid-schema/statement_source_url.json @@ -0,0 +1,18 @@ +[ + { + "statementId": "2f7bf9370f1254068e5e946df067d07d", + "recordId": "ent-93c75c87ab28f889", + "recordType": "entity", + "declarationSubject": "ent-93c75c87ab28f889", + "statementDate": "2017-11-18", + "source": { + "url": "https://www.example.com/index.html" + }, + "recordDetails": { + "isComponent": false, + "entityType": { + "type": "registeredEntity" + } + } + } +] \ No newline at end of file diff --git a/tests/test_additional_checks_0_4_0.py b/tests/test_additional_checks_0_4_0.py new file mode 100644 index 0000000..3d7dcc4 --- /dev/null +++ b/tests/test_additional_checks_0_4_0.py @@ -0,0 +1,2191 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_retrievedat_not_future_date_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "retrievedat_not_future_date-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_retrievedat_not_future_date_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "retrievedat_not_future_date-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_retrievedat_not_future_date_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "retrievedat_not_future_date-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_retrievedat_not_future_date_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "retrievedat_not_future_date-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_date_not_future_date_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_date_not_future_date-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_date_not_future_date_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_date_not_future_date-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_date_not_future_date_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_date_not_future_date-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_creation_date_not_future_date_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_annotation_creation_date_future_date-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_creation_date_not_future_date_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_annotation_creation_date_future_date-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_creation_date_not_future_date_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_annotation_creation_date_future_date-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_publication_date_future_date_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_publication_date_future_date-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_publication_date_future_date_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_publication_date_future_date-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_publication_date_future_date_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_publication_date_future_date-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_publication_date_future_date_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_publication_date_future_date-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_person_date_of_death_sane_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_date_of_death_sane-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_date_of_death_sane_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_date_of_death_sane-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_date_of_death_sane_invalid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_date_of_death_sane-invalid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_date_of_death_sane_invalid_4(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_date_of_death_sane-invalid-4.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_date_of_death_sane_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_date_of_death_sane-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_person_date_of_death_sane_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_date_of_death_sane-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_entity_foundation_dissolution_dates_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_foundation_dissolution_dates-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_entity_foundation_dissolution_dates_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_foundation_dissolution_dates-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_entity_foundation_dissolution_dates_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_foundation_dissolution_dates-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_person_birth_date_sensible_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_birth_date_sensible-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_birth_date_sensible_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_birth_date_sensible-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_birth_date_sensible_invalid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_birth_date_sensible-invalid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_birth_date_sensible_invalid_4(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_birth_date_sensible-invalid-4.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_birth_date_sensible_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_birth_date_sensible-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_person_birth_date_sensible_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_birth_date_sensible-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_relationship_interests_start_end_dates_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interests_start_end_dates-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_interests_start_end_dates_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interests_start_end_dates-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_relationship_interests_start_end_dates_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interests_start_end_dates-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_entity_securities_listings_haspubliclisting_not_false_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_securities_listings_haspubliclisting_not_false-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_entity_securities_listings_haspubliclisting_not_false_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_securities_listings_haspubliclisting_not_false-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_entity_securities_listings_haspubliclisting_not_false_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_securities_listings_haspubliclisting_not_false-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_relationship_interests_share_values_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interests_share_values-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_interests_share_values_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interests_share_values-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_interests_share_values_invalid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interests_share_values-invalid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_interests_share_values_invalid_4(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interests_share_values-invalid-4.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_interests_share_values_invalid_5(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interests_share_values-invalid-4.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_interests_share_values_invalid_6(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interests_share_values-invalid-6.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_declaration_subject_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_declaration_subject-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_declaration_subject_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_declaration_subject-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_declaration_subject_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_declaration_subject-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_entity_is_component_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_is_component-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_entity_is_component_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_is_component-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 3 # 2 extra ordering errors + + +def test_statement_entity_is_component_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_is_component-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_person_is_component_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_is_component-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 2 # Extra ordering error + + +def test_statement_person_is_component_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_is_component-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_is_component_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_is_component-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_relationship_is_component_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_is_component-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_is_component_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_is_component-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_is_component_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_is_component-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_duplicate_statement_id_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_must_have_unique_statement_identifier-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_duplicate_statement_id_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_must_have_unique_statement_identifier-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_duplicate_statement_id_invalid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_must_have_unique_statement_identifier-invalid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_duplicate_statement_id_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_must_have_unique_statement_identifier-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_series_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_series-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_series_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_series-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_series_invalid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_series-invalid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_series_invalid_4(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_series-invalid-4.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_series_invalid_5(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_series-invalid-5.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_series_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_series-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_series_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_series-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_relationship_component_records_are_record_ids_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_component_records_are_record_ids-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_component_records_are_record_ids_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_component_records_are_record_ids-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_relationship_component_records_are_record_ids_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_component_records_are_record_ids-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_relationship_subject_refers_to_entity_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_subject_refers_to_entity_statement-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_relationship_subject_refers_to_entity_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_subject_refers_to_entity_statement-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_relationship_subject_refers_to_entity_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_subject_refers_to_entity_statement-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_relationship_interested_party_entity_or_person_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_relationship_interested_party_entity_or_person-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_annotiation_statement_pointer_target_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "annotiation_statement_pointer_target-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_annotiation_statement_pointer_target_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "annotiation_statement_pointer_target-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_annotiation_statement_pointer_target_invalid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "annotiation_statement_pointer_target-invalid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_annotiation_statement_pointer_target_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "annotiation_statement_pointer_target-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_annotiation_statement_pointer_target_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "annotiation_statement_pointer_target-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_interested_party_person_with_beneficial_ownership_or_control_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "interested_party_person_with_beneficial_ownership_or_control-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_interested_party_person_with_beneficial_ownership_or_control_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "interested_party_person_with_beneficial_ownership_or_control-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_interested_party_person_with_beneficial_ownership_or_control_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "interested_party_person_with_beneficial_ownership_or_control-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_relationship_interest_nominee_or_nominator_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "relationship_interest_nominee_or_nominator-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_relationship_interest_nominee_or_nominator_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "relationship_interest_nominee_or_nominator-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_relationship_interest_nominee_or_nominator_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "relationship_interest_nominee_or_nominator-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_relationship_interest_for_trusts_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "relationship_interest_for_trusts-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_relationship_interest_for_trusts_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "relationship_interest_for_trusts-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_relationship_interest_for_trusts_invalid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "relationship_interest_for_trusts-invalid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_relationship_interest_for_trusts_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "relationship_interest_for_trusts-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_relationship_interest_for_trusts_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "relationship_interest_for_trusts-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_relationship_interest_for_trusts_valid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "relationship_interest_for_trusts-valid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_serialisation_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_serialisation-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_serialisation_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_serialisation-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_serialisation_invalid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_serialisation-invalid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_serialisation_invalid_4(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_serialisation-invalid-4.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_serialisation_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_serialisation-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_person_identifiers_have_correct_scheme_invalid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_identifiers_have_correct_scheme-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_identifiers_have_correct_scheme_invalid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_identifiers_have_correct_scheme-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_identifiers_have_correct_scheme_invalid_3(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_identifiers_have_correct_scheme-invalid-3.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_identifiers_have_correct_scheme_invalid_4(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_identifiers_have_correct_scheme-invalid-4.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_identifiers_have_correct_scheme_invalid_5(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_identifiers_have_correct_scheme-invalid-5.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_identifiers_have_correct_scheme_invalid_6(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_identifiers_have_correct_scheme-invalid-6.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_person_identifiers_have_correct_scheme_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_identifiers_have_correct_scheme-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_person_identifiers_have_correct_scheme_valid_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_person_identifiers_have_correct_scheme-valid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_statement_entity_identifier_scheme_known_invalid_1(): + # Testing CheckStatementEntityIdentifiersHaveKnownScheme + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_identifier_scheme_known-invalid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_entity_identifier_scheme_known_invalid_2(): + # Testing CheckStatementEntityIdentifiersHaveKnownScheme + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_identifier_scheme_known-invalid-2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 1 + + +def test_statement_entity_identifier_scheme_known_valid_1(): + # Testing CheckStatementEntityIdentifiersHaveKnownScheme + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional-checks", + "statement_entity_identifier_scheme_known-valid-1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 diff --git a/tests/test_additional_fields_0_4_0.py b/tests/test_additional_fields_0_4_0.py new file mode 100644 index 0000000..dc2ce11 --- /dev/null +++ b/tests/test_additional_fields_0_4_0.py @@ -0,0 +1,46 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_additional_fields_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional_fields_1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 2 + assert results["additional_checks_count"] == 0 + + +def test_additional_fields_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "additional_fields_2.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert ( + results["additional_checks_count"] == 2 + ) # Some checks fail because isolated statement diff --git a/tests/test_api_0_1.py b/tests/test_api_0_1.py index e689ced..3fc5d69 100644 --- a/tests/test_api_0_1.py +++ b/tests/test_api_0_1.py @@ -587,7 +587,6 @@ def test_basic_statement_id_and_type_errors(): assert validation_error["path"] == [3] validation_error = results["validation_errors"][4] - print(validation_error) assert "Invalid code found in statementType" == validation_error["message"] assert validation_error["path"] == [4, "statementType"] @@ -1239,7 +1238,8 @@ def test_badfile_all_validation_errors(): "badfile_all_validation_errors.json", ) # This file is generated with - # libcovebods jsv tests/fixtures/0.1/badfile_all_validation_errors.json > tests/fixtures/0.1/badfile_all_validation_errors.expected.json + # libcovebods jsv tests/fixtures/0.1/badfile_all_validation_errors.json > + # tests/fixtures/0.1/badfile_all_validation_errors.expected.json expected_json_filename = os.path.join( os.path.dirname(os.path.realpath(__file__)), "fixtures", diff --git a/tests/test_api_0_4.py b/tests/test_api_0_4.py new file mode 100644 index 0000000..96cb882 --- /dev/null +++ b/tests/test_api_0_4.py @@ -0,0 +1,145 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_basic_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.4", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_has_public_listing_information_but_has_public_listing_is_false_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "has_public_listing_information_but_has_public_listing_is_false_1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + + assert results["additional_checks_count"] == 1 + assert ( + results["additional_checks"][0]["type"] + == "has_public_listing_information_but_has_public_listing_is_false" + ) + assert ( + results["additional_checks"][0]["statement"] + == "1dc0e987-5c57-4a1c-b3ad-61353b66a9b7" + ) + + +def test_entity_sub_type_does_not_align_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "entity_sub_type_does_not_align_1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 1 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + assert ( + results["validation_errors"][0]["message"] == "'trust' is not one of ['other']" + ) + assert results["validation_errors"][0]["path_ending"] == "subtype" + + +def test_entity_sub_type_does_align_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "entity_sub_type_does_align_1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_basic_with_correct_mic_codes_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "basic_with_correct_mic_codes_1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 + + +def test_basic_with_operating_mic_code_missing_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "basic_with_operating_mic_code_missing_1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + + assert results["additional_checks_count"] == 1 + assert ( + results["additional_checks"][0]["type"] + == "entity_security_listing_market_identifier_code_set_but_not_operating_market_identifier_code" + ) + assert results["additional_checks"][0]["statement_type"] == "entity" + assert ( + results["additional_checks"][0]["statement"] + == "2f7bf9370f1254068e5e946df067d07d" + ) diff --git a/tests/test_data_reader.py b/tests/test_data_reader.py index c24de5d..1dff0e0 100644 --- a/tests/test_data_reader.py +++ b/tests/test_data_reader.py @@ -19,6 +19,21 @@ def test_full_get_all_data_1(): assert expected == actual +def test_full_get_all_data_2(): + + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.4", "basic_1.json" + ) + + with open(json_filename) as fp: + expected = json.load(fp) + + data_reader = libcovebods.data_reader.DataReader(json_filename) + actual = data_reader.get_all_data() + + assert expected == actual + + def test_sample_but_no_change_get_all_data_1(): json_filename = os.path.join( diff --git a/tests/test_lib_common.py b/tests/test_lib_common.py index fd6f996..2aad091 100644 --- a/tests/test_lib_common.py +++ b/tests/test_lib_common.py @@ -71,10 +71,7 @@ def test_this_YYYY(self): def test_this_YYYY_MM(self): today = dateutil.utils.today(UTC) - assert ( - is_interest_current({"endDate": "{}-{}".format(today.year, today.month)}) - is True - ) + assert is_interest_current({"endDate": f"{today.year}-{today.month}"}) is True def test_this_date(self): assert ( diff --git a/tests/test_sample_mode.py b/tests/test_sample_mode.py new file mode 100644 index 0000000..01ee25e --- /dev/null +++ b/tests/test_sample_mode.py @@ -0,0 +1,24 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_sample_mode_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "sample_300_statements.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename, sample_mode=True) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 + assert results["additional_fields_count"] == 0 + assert results["additional_checks_count"] == 0 diff --git a/tests/test_schema_validation_0_4.py b/tests/test_schema_validation_0_4.py new file mode 100644 index 0000000..ff377e8 --- /dev/null +++ b/tests/test_schema_validation_0_4.py @@ -0,0 +1,103 @@ +import csv +import os +import pathlib +import tempfile + +import pytest + +from tests.api import bods_json_output + + +@pytest.fixture +def expected_errors(): + expected = [] + with open( + "tests/fixtures/0.4/invalid-schema/expected_errors.csv", newline="" + ) as csvfile: + reader = csv.reader(csvfile) + for row in reader: + expected.append(row) + return expected + + +@pytest.fixture +def valid_statements(): + return pathlib.Path("tests/fixtures/0.4/valid-schema").glob("*.json") + + +def extract_elements(element_path): + elems = [0 if elem == "$[0]" else elem for elem in element_path.split(".")] + out = [] + for elem in elems: + if isinstance(elem, str) and "[0]" in elem: + out.append(elem.split("[0]")[0]) + out.append(0) + else: + out.append(elem) + if len(out) == 1 and out[0] == "$": + out = [] + return out + + +def test_all_schema_validation_invalid(expected_errors): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + + for expected in expected_errors: + + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "invalid-schema", + expected[0], + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + if expected[1] in ("enum", "type"): + assert results["validation_errors_count"] > 0 + else: + assert results["validation_errors_count"] == 1 + assert results["validation_errors"][0]["validator"] == expected[1] + assert results["validation_errors"][0]["path"] == extract_elements(expected[2]) + if expected[1] == "required": + assert ( + results["validation_errors"][0]["extra"][ + "required_key_which_is_missing" + ] + == expected[3] + ) + elif expected[1] in ( + "enum", + "anyOf", + "type", + "maxLength", + "minLength", + "format", + "minimum", + "maximum", + "pattern", + "oneOf", + "const", + ): + pass + else: + pass + + +def test_all_schema_validation_valid(valid_statements): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + + for valid_statement in valid_statements: + + results = bods_json_output(cove_temp_folder, valid_statement) + + assert results["schema_version"] == "0.4" + assert results["validation_errors_count"] == 0 diff --git a/tests/test_stat_count_declaration_subjects.py b/tests/test_stat_count_declaration_subjects.py new file mode 100644 index 0000000..a9c79f9 --- /dev/null +++ b/tests/test_stat_count_declaration_subjects.py @@ -0,0 +1,23 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_schema_0_4_count(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "statistic_count_declaration_subjects.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + + assert results["statistics"]["count_declaration_subjects"] == 2 diff --git a/tests/test_stat_count_entity_statements.py b/tests/test_stat_count_entity_statements.py new file mode 100644 index 0000000..bd61d2b --- /dev/null +++ b/tests/test_stat_count_entity_statements.py @@ -0,0 +1,82 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_schema_0_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.2", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.2" + + assert results["statistics"]["count_entity_statements"] == 1 + assert ( + results["statistics"]["count_entity_statements_types"]["registeredEntity"] == 1 + ) + assert ( + results["statistics"]["count_entity_statements_types_with_any_identifier"][ + "registeredEntity" + ] + == 1 + ) + assert ( + results["statistics"][ + "count_entity_statements_types_with_any_identifier_with_id_and_scheme" + ]["registeredEntity"] + == 1 + ) + + +def test_schema_0_3_basic_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.3", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.3" + + assert results["statistics"]["count_entity_statements"] == 1 + assert ( + results["statistics"]["count_entity_statements_types"]["registeredEntity"] == 1 + ) + assert ( + results["statistics"]["count_entity_statements_types_with_any_identifier"][ + "registeredEntity" + ] + == 1 + ) + assert ( + results["statistics"][ + "count_entity_statements_types_with_any_identifier_with_id_and_scheme" + ]["registeredEntity"] + == 1 + ) + + +def test_schema_0_4_basic_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.4", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + + assert results["statistics"]["count_entity_statements"] == 1 diff --git a/tests/test_stat_count_ownership_or_control_statement.py b/tests/test_stat_count_ownership_or_control_statement.py new file mode 100644 index 0000000..11b7e6d --- /dev/null +++ b/tests/test_stat_count_ownership_or_control_statement.py @@ -0,0 +1,52 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_schema_0_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.2", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.2" + + assert results["statistics"]["count_ownership_or_control_statement"] == 1 + + +def test_schema_0_3_basic_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.3", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.3" + + assert results["statistics"]["count_ownership_or_control_statement"] == 1 + + +def test_schema_0_4_basic_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.4", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + + assert results["statistics"]["count_ownership_or_control_statement"] == 1 diff --git a/tests/test_stat_count_ownership_or_control_statement_interest_direct_or_indirect.py b/tests/test_stat_count_ownership_or_control_statement_interest_direct_or_indirect.py index e314670..40a6d25 100644 --- a/tests/test_stat_count_ownership_or_control_statement_interest_direct_or_indirect.py +++ b/tests/test_stat_count_ownership_or_control_statement_interest_direct_or_indirect.py @@ -38,7 +38,8 @@ def test_schema_0_3_basic_1(): assert results["schema_version"] == "0.3" # We want to test the dict has the correct keys! - # So these tests are deliberately written so they will error if the specified key is not in that dict + # So these tests are deliberately written so they will error if the specified key + # is not in that dict assert ( 1 == results["statistics"][ diff --git a/tests/test_stat_count_ownership_or_control_statement_interest_statement_types.py b/tests/test_stat_count_ownership_or_control_statement_interest_statement_types.py index 67023fe..dfdffa2 100644 --- a/tests/test_stat_count_ownership_or_control_statement_interest_statement_types.py +++ b/tests/test_stat_count_ownership_or_control_statement_interest_statement_types.py @@ -17,14 +17,16 @@ def test_schema_0_1(): assert results["schema_version"] == "0.1" - # Schema v0.1 and Schema v0.2 have different enum options, make sure that is reflected in data + # Schema v0.1 and Schema v0.2 have different enum options, make sure that + # is reflected in data keys = results["statistics"][ "count_ownership_or_control_statement_interest_statement_types" ].keys() assert 12 == len(keys) # We want to test the dict has the correct keys! - # So these tests are deliberately written so they will error if the specified key is not in that dict + # So these tests are deliberately written so they will error if the specified + # key is not in that dict assert ( 1 == results["statistics"][ @@ -112,14 +114,16 @@ def test_schema_0_2(): assert results["schema_version"] == "0.2" - # Schema v0.1 and Schema v0.2 have different enum options, make sure that is reflected in data + # Schema v0.1 and Schema v0.2 have different enum options, make sure that + # is reflected in data keys = results["statistics"][ "count_ownership_or_control_statement_interest_statement_types" ].keys() assert 14 == len(keys) # We want to test the dict has the correct keys! - # So these tests are deliberately written so they will error if the specified key is not in that dict + # So these tests are deliberately written so they will error if the specified key + # is not in that dict assert ( 1 == results["statistics"][ diff --git a/tests/test_stat_count_person_statements.py b/tests/test_stat_count_person_statements.py new file mode 100644 index 0000000..6b63a5c --- /dev/null +++ b/tests/test_stat_count_person_statements.py @@ -0,0 +1,55 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_schema_0_2(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.2", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.2" + + assert results["statistics"]["count_person_statements"] == 1 + assert results["statistics"]["count_person_statements_types"]["knownPerson"] == 1 + + +def test_schema_0_3_basic_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.3", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.3" + + assert results["statistics"]["count_person_statements"] == 1 + assert results["statistics"]["count_person_statements_types"]["knownPerson"] == 1 + + +def test_schema_0_4_basic_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "fixtures", "0.4", "basic_1.json" + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + + assert results["statistics"]["count_person_statements"] == 1 + assert results["statistics"]["count_person_statements_types"]["knownPerson"] == 1 diff --git a/tests/test_stat_counts_0_4.py b/tests/test_stat_counts_0_4.py new file mode 100644 index 0000000..47017f9 --- /dev/null +++ b/tests/test_stat_counts_0_4.py @@ -0,0 +1,85 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_sample_mode_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "sample_300_statements.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename, sample_mode=True) + + assert results["schema_version"] == "0.4" + + assert results["statistics"]["count_entity_statements"] == 50 + assert ( + results["statistics"]["count_entity_statements_types"]["registeredEntity"] == 50 + ) + assert ( + results["statistics"]["count_entity_statements_types_with_any_identifier"][ + "registeredEntity" + ] + == 50 + ) + assert ( + results["statistics"][ + "count_entity_statements_types_with_any_identifier_with_id_and_scheme" + ]["registeredEntity"] + == 50 + ) + assert results["statistics"]["count_person_statements"] == 50 + assert results["statistics"]["count_person_statements_types"]["knownPerson"] == 50 + assert results["statistics"]["count_ownership_or_control_statement"] == 50 + assert ( + results["statistics"][ + "count_ownership_or_control_statement_interested_party_with_person" + ] + == 50 + ) + assert ( + results["statistics"][ + "count_ownership_or_control_statement_interested_party_with_entity" + ] + == 0 + ) + assert ( + results["statistics"][ + "count_ownership_or_control_statement_interested_party_with_unspecified" + ] + == 0 + ) + assert ( + results["statistics"]["count_ownership_or_control_statement_interested_party"] + == 50 + ) + assert ( + results["statistics"][ + "count_ownership_or_control_statement_interest_statement_types" + ]["shareholding"] + == 50 + ) + assert ( + results["statistics"]["count_ownership_or_control_statement_by_year"][2020] + == 50 + ) + assert ( + results["statistics"]["count_ownership_or_control_statement_subject_by_year"][ + 2020 + ] + == 50 + ) + assert ( + results["statistics"][ + "count_ownership_or_control_statement_interested_party_by_year" + ][2020] + == 50 + ) From e1c570c8b84e9e3a9ebc225950bcdd19d9909ffe Mon Sep 17 00:00:00 2001 From: "Ed (ODSC)" Date: Thu, 19 Dec 2024 08:11:40 +0000 Subject: [PATCH 2/4] Break-up checks/statistics, more statistics, tests and cleanup --- libcovebods/config.py | 32 +- libcovebods/data/schema-0-4-0.json | 4219 ----------------- libcovebods/data_reader.py | 6 - libcovebods/run_tasks.py | 154 +- libcovebods/schema.py | 9 +- libcovebods/tasks/checks/legacy_checks.py | 611 +++ libcovebods/tasks/checks/pre_record_checks.py | 113 + .../record_based_checks.py} | 761 +-- libcovebods/tasks/peps.py | 83 +- .../pre_record_statistics.py} | 283 +- .../statistics/record_based_statistics.py | 418 ++ pyproject.toml | 11 - setup.py | 7 +- tests/test_stat_count_addresses_0_4.py | 29 + tests/test_stat_count_pep_0_4.py | 30 + ...unt_relationship_direct_or_indirect_0_4.py | 40 + ...t_stat_count_relationship_interests_0_4.py | 28 + 17 files changed, 1487 insertions(+), 5347 deletions(-) delete mode 100644 libcovebods/data/schema-0-4-0.json create mode 100644 libcovebods/tasks/checks/legacy_checks.py create mode 100644 libcovebods/tasks/checks/pre_record_checks.py rename libcovebods/tasks/{checks.py => checks/record_based_checks.py} (62%) rename libcovebods/tasks/{statistics.py => statistics/pre_record_statistics.py} (56%) create mode 100644 libcovebods/tasks/statistics/record_based_statistics.py delete mode 100644 pyproject.toml create mode 100644 tests/test_stat_count_addresses_0_4.py create mode 100644 tests/test_stat_count_pep_0_4.py create mode 100644 tests/test_stat_count_relationship_direct_or_indirect_0_4.py create mode 100644 tests/test_stat_count_relationship_interests_0_4.py diff --git a/libcovebods/config.py b/libcovebods/config.py index 482274c..34b80a4 100644 --- a/libcovebods/config.py +++ b/libcovebods/config.py @@ -25,12 +25,42 @@ }, # In some cases we default to the latest schema version, so we need to know what the latest version is. # It should be a key that is in the 'schema_versions' data. + # Note: Schema changed substantially from 0.3 to 0.4 (record based) so in cases where the schema + # version is not specified will try to determine whether is pre or post that change, and default to + # either the latest version (if after change) or a pre-change schema if before change "schema_latest_version": "0.4", # Or latest version before change to records (in 0.4) "schema_latest_nonrecord_version": "0.3", # These default values are very wide on purpose. It is left to apps using this to tighten them up. - "bods_additional_checks_person_birthdate_min_year": 1, + "bods_additional_checks_person_birthdate_min_year": 1800, "bods_additional_checks_person_birthdate_max_year": datetime.datetime.now().year, + # Other widely used (but "non-standard") country codes that should be allowed + # See: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3 (User-assigned code elements section) + "bods_additional_checks_other_country_codes": ( + "BAH", + "D", + "EUE", + "GBD", + "GBN", + "GBO", + "GBP", + "GBS", + "UNA", + "UNK", + "UNO", + "XBA", + "XIM", + "XCC", + "XCO", + "XEC", + "XPO", + "XOM", + "XXA", + "XXB", + "XXC", + "XXX", + "ZIM", + ), } diff --git a/libcovebods/data/schema-0-4-0.json b/libcovebods/data/schema-0-4-0.json deleted file mode 100644 index 98a88a9..0000000 --- a/libcovebods/data/schema-0-4-0.json +++ /dev/null @@ -1,4219 +0,0 @@ -{ - "$id": "urn:statement", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Statements", - "description": "An array of Statements.", - "version": "0.4", - "type": "array", - "items": { - "title": "Statement", - "description": "A claim about a person, entity or relationship, made at a particular point in time.", - "type": "object", - "properties": { - "statementId": { - "title": "Statement Identifier", - "description": "A persistent globally unique identifier for this Statement. Length MUST be 32 - 64 characters (inclusive).", - "type": "string", - "minLength": 32, - "maxLength": 64 - }, - "statementDate": { - "title": "Statement Date", - "description": "The date on which this statement was declared by the source, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "annotations": { - "title": "Annotations", - "description": "Annotations about this Statement or parts of this Statement", - "type": "array", - "items": { - "title": "Annotation", - "description": "Additional information about the data contained in this Statement. Annotations can apply to a whole statement, an object or a single field. Custom properties can be included within the Annotation object to provide structured data where required.", - "type": "object", - "properties": { - "statementPointerTarget": { - "title": "Statement Fragment Pointer", - "description": "An RFC6901 JSON Pointer (https://tools.ietf.org/html/rfc6901) describing the target fragment of the statement that this Annotation applies to, starting from the root of the Statement. An empty string (\"\") indicates that the Annotation applies to the whole Statement.", - "type": "string" - }, - "creationDate": { - "title": "Creation Date", - "description": "The date on which this Annotation was created, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "createdBy": { - "title": "Created By", - "description": "The person, organisation or agent that created this Annotation.", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the person, organisation or agent that created this Annotation.", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "An optional URI to identify the person, organisation or agent that created this Annotation.", - "type": "string", - "format": "uri" - } - } - }, - "motivation": { - "title": "Motivation", - "description": "The reason for this Annotation, using the annotationMotivation codelist.", - "type": "string", - "enum": [ - "commenting", - "correcting", - "identifying", - "linking", - "transformation" - ], - "codelist": "annotationMotivation.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "A free text description providing extra information about part of this Statement.", - "type": "string" - }, - "transformedContent": { - "type": "string", - "title": "Transformed Content", - "description": "A representation of the Annotation target after the transformation in the `description` field has been applied. This field MUST only be used when the `motivation` is 'transformation'." - }, - "url": { - "title": "URL", - "description": "A linked resource that annotates, provides context for or enhances this Statement. The content of the resource, or the relationship to the statement, MAY be described in the `description` field. This field is REQUIRED if the value of `motivation` is 'linking'.", - "type": "string", - "format": "uri" - } - }, - "allOf": [ - { - "if": { - "properties": { - "motivation": { - "const": "linking" - } - } - }, - "then": { - "required": [ - "statementPointerTarget", - "motivation", - "url" - ] - }, - "else": { - "required": [ - "statementPointerTarget", - "motivation" - ] - } - }, - { - "if": { - "not": { - "properties": { - "motivation": { - "const": "transformation" - } - } - } - }, - "then": { - "properties": { - "transformedContent": { - "const": "" - } - } - } - } - ] - } - }, - "publicationDetails": { - "title": "Publication Details", - "description": "Information concerning the publication of this Statement.", - "type": "object", - "properties": { - "publicationDate": { - "title": "Publication date", - "description": "The date on which this statement was published, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "bodsVersion": { - "title": "BODS Version", - "description": "The version of the Beneficial Ownership Data Standard to which this Statement conforms, expressed as major.minor (e.g. 0.2 or 1.0). In a published BODS dataset, all Statements MUST have the same major version number.", - "type": "string", - "pattern": "^(\\d+\\.)(\\d+)$" - }, - "license": { - "title": "License URL", - "description": "A link to the license that applies to this Statement. The canonical URI of the license SHOULD be used. Publishers are encouraged to use a Public Domain Dedication or Open Definition Conformant (http://opendefinition.org/licenses/) license.", - "type": "string", - "format": "uri" - }, - "publisher": { - "type": "object", - "title": "Publisher", - "description": "Details of the organisation or person publishing a Statement.", - "properties": { - "name": { - "title": "Name", - "description": "The name of the publisher.", - "type": "string" - }, - "url": { - "title": "URL", - "description": "The URL where details of the full dataset, or of the publisher, can be found.", - "type": "string", - "format": "uri" - } - }, - "anyOf": [ - { - "required": [ - "name" - ] - }, - { - "required": [ - "url" - ] - } - ] - } - }, - "required": [ - "publicationDate", - "bodsVersion", - "publisher" - ] - }, - "source": { - "title": "Source", - "description": "The source of information in this statement. Each statement SHOULD contain source information.", - "type": "object", - "properties": { - "type": { - "title": "Source Type", - "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", - "type": "array", - "items": { - "type": "string", - "enum": [ - "selfDeclaration", - "officialRegister", - "thirdParty", - "primaryResearch", - "verified" - ], - "codelist": "sourceType.csv", - "openCodelist": false - } - }, - "description": { - "title": "Description", - "description": "Additional, free text information about the source of information.", - "type": "string" - }, - "url": { - "title": "Source URL", - "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", - "type": "string", - "format": "uri" - }, - "retrievedAt": { - "title": "Retrieved At", - "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "assertedBy": { - "title": "Asserted By", - "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the agent making the assertion", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "An optional URI to identify the agent making the assertion", - "type": "string", - "format": "uri" - } - } - } - } - } - }, - "declaration": { - "title": "Declaration Reference", - "description": "An identifier or reference for a declaration within the publisher\u2019s system. Where a Statement is a claim from a particular declaration (made at a point in time by a `source` about a `declarationSubject`) this field identifies the declaration.", - "type": "string" - }, - "declarationSubject": { - "title": "Declaration Subject", - "description": "A `recordId` value for the subject of a beneficial ownership network (always an entity or person).", - "type": "string" - }, - "recordId": { - "title": "Record Identifier", - "description": "A unique identifier for the record (within the publisher's system) to which this Statement relates. (A record captures information about an entity, natural person or relationship within the beneficial ownership network of a particular declaration subject.)", - "type": "string" - }, - "recordType": { - "title": "Record Type", - "description": "The type of record (within the publisher's system) to which this Statement relates: entity, person, or relationship.", - "type": "string", - "enum": [ - "person", - "entity", - "relationship" - ], - "codelist": "recordType.csv", - "openCodelist": false - }, - "recordStatus": { - "title": "Record Status", - "description": "The lifecycle status of the record (within the publisher's system) to which this Statement relates, using the recordStatus codelist.", - "type": "string", - "enum": [ - "new", - "updated", - "closed" - ], - "codelist": "recordStatus.csv", - "openCodelist": false - }, - "recordDetails": { - "title": "Record Details", - "description": "The details of the entity, person or relationship as declared on the Statement Date.", - "type": "object" - } - }, - "allOf": [ - { - "if": { - "properties": { - "recordType": { - "const": "entity" - } - } - }, - "then": { - "properties": { - "recordDetails": { - "$id": "urn:entity", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "version": "0.4", - "title": "Entity Record Details", - "description": "Information about an entity.", - "type": "object", - "properties": { - "isComponent": { - "title": "Is component", - "description": "Whether this entity is a component in an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this entity MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Entity Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Entity Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship statement MUST have a `isComponent` value of 'false'.", - "type": "boolean" - }, - "entityType": { - "type": "object", - "title": "Entity Type", - "description": "The form of the entity described in the Statement.", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "title": "Type", - "description": "The general form of the entity, using the entityType codelist.", - "codelist": "entityType.csv", - "enum": [ - "registeredEntity", - "legalEntity", - "arrangement", - "anonymousEntity", - "unknownEntity", - "state", - "stateBody" - ] - }, - "subtype": { - "type": "string", - "title": "Subtype", - "description": "The particular form of the entity, where relevant, using the entitySubtype codelist. The value MUST align with the `entityType` value.", - "codelist": "entitySubtype.csv", - "enum": [ - "governmentDepartment", - "stateAgency", - "other", - "trust", - "nomination" - ], - "openCodelist": false - }, - "details": { - "type": "string", - "title": "Details", - "description": "This may be used to provide a local name for this type of entity, or any further information to identify the type of entity. For example, in Finland 'ministeri\u00f6' for a government department." - } - }, - "propertyOrder": 4, - "allOf": [ - { - "if": { - "properties": { - "type": { - "enum": [ - "arrangement" - ] - } - } - }, - "then": { - "properties": { - "subtype": { - "enum": [ - "trust", - "nomination", - "other" - ] - } - } - } - }, - { - "if": { - "properties": { - "type": { - "enum": [ - "legalEntity" - ] - } - } - }, - "then": { - "properties": { - "subtype": { - "enum": [ - "trust", - "other" - ] - } - } - } - }, - { - "if": { - "properties": { - "type": { - "enum": [ - "stateBody" - ] - } - } - }, - "then": { - "properties": { - "subtype": { - "enum": [ - "governmentDepartment", - "stateAgency", - "other" - ] - } - } - } - }, - { - "if": { - "properties": { - "type": { - "enum": [ - "registeredEntity", - "state", - "anonymousEntity", - "unknownEntity" - ] - } - } - }, - "then": { - "properties": { - "subtype": { - "enum": [ - "other" - ] - } - } - } - } - ] - }, - "unspecifiedEntityDetails": { - "title": "Unspecified or unknown person or entity", - "description": "A `reason` MUST be supplied.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", - "type": "string", - "enum": [ - "noBeneficialOwners", - "subjectUnableToConfirmOrIdentifyBeneficialOwner", - "interestedPartyHasNotProvidedInformation", - "subjectExemptFromDisclosure", - "interestedPartyExemptFromDisclosure", - "unknown", - "informationUnknownToPublisher" - ], - "codelist": "unspecifiedReason.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", - "type": "string" - } - }, - "required": [ - "reason" - ] - }, - "name": { - "title": "Entity Name", - "description": "The declared name of this entity.", - "type": "string", - "propertyOrder": 10 - }, - "alternateNames": { - "title": "Alternative Names", - "description": "An array of other names this entity is known by.", - "type": "array", - "items": { - "type": "string", - "title": "Name", - "description": "A name this entity is known by." - }, - "propertyOrder": 12 - }, - "jurisdiction": { - "title": "Jurisdiction", - "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the jurisdiction", - "type": "string" - }, - "code": { - "title": "Country or Subdivision Code", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", - "type": "string", - "maxLength": 6, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "identifiers": { - "title": "Identifiers", - "description": "One or more official identifiers for this entity. Where available, official registration numbers should be provided.", - "type": "array", - "items": { - "title": "Identifier", - "description": "An identifier that has been assigned to a person or entity. `scheme` or `schemeName` (or both) MUST be included in an Identifier object.", - "type": "object", - "properties": { - "id": { - "title": "ID", - "description": "The identifier for a person or entity, as issued by the scheme.", - "type": "string" - }, - "scheme": { - "title": "Scheme Code", - "description": "For entities, a code from org-id.guide (https://www.org-id.guide) for an identifier-issuing authority (e.g. 'GB-COH'). For natural persons, a value with the pattern {JURISDICTION}-{TYPE} where JURISDICTION is an ISO 3166-1 3-digit country code and TYPE is one of PASSPORT, TAXID or IDCARD.", - "type": "string" - }, - "schemeName": { - "title": "Scheme Name", - "description": "The name of the identifier-issuing authority.", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "A canonical URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) for the identifier and associated details of the person or entity, if one exists.", - "type": "string", - "format": "uri" - } - }, - "anyOf": [ - { - "required": [ - "scheme" - ] - }, - { - "required": [ - "schemeName" - ] - }, - { - "required": [ - "scheme", - "schemeName" - ] - } - ] - }, - "propertyOrder": 20 - }, - "foundingDate": { - "title": "Founding Date", - "description": "The date on which this entity was founded, created or registered. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date", - "propertyOrder": 30 - }, - "dissolutionDate": { - "title": "Dissolution Date", - "description": "The date on which this entity was dissolved or ceased, if it is no longer active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date", - "propertyOrder": 35 - }, - "addresses": { - "title": "Addresses", - "description": "One or more addresses for this entity.", - "type": "array", - "items": { - "title": "Address", - "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", - "type": "object", - "properties": { - "type": { - "title": "Type", - "description": "The function of the address, using the addressType codelist.", - "type": "string", - "enum": [ - "placeOfBirth", - "residence", - "registered", - "service", - "alternative", - "business" - ], - "codelist": "addressType.csv", - "openCodelist": false - }, - "address": { - "title": "Address", - "description": "The address, with each line or component separated by a line-break or comma.", - "type": "string" - }, - "postCode": { - "title": "Postcode", - "description": "The postal code for this address.", - "type": "string" - }, - "country": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - } - } - }, - "propertyOrder": 40 - }, - "uri": { - "title": "URI", - "description": "Where a persistent URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) is available for this entity this should be included.", - "type": "string", - "format": "uri", - "propertyOrder": 21 - }, - "publicListing": { - "type": "object", - "title": "Public Listing", - "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", - "required": [ - "hasPublicListing" - ], - "minProperties": 1, - "properties": { - "hasPublicListing": { - "type": "boolean", - "title": "Has Public Listing", - "description": "Whether the entity is a publicly listed company." - }, - "companyFilingsURLs": { - "type": "array", - "title": "Company Filings URLs", - "description": "URL or URLs where regulatory filings related to major holdings can be retrieved. URLs may point to pages maintained by regulatory bodies, stock exchanges or by the company itself.", - "items": { - "type": "string", - "format": "uri" - } - }, - "securitiesListings": { - "type": "array", - "title": "Securities Listings", - "description": "Details of the entity's securities and the public exchanges and markets on which they are traded. All equity securities SHOULD be listed here, plus any other securities from which beneficial ownership might be derived. Where a security is traded on more than one market, there SHOULD be an entry for each market (or market segment).", - "items": { - "type": "object", - "title": "Securities Listing", - "description": "Details of a security and the market on which it is traded.", - "required": [ - "stockExchangeJurisdiction", - "security", - "stockExchangeName" - ], - "properties": { - "marketIdentifierCode": { - "type": "string", - "title": "Market Identifier Code (MIC)", - "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "operatingMarketIdentifierCode": { - "type": "string", - "title": "Operating Market Identifier Code (Operating MIC)", - "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "stockExchangeJurisdiction": { - "type": "string", - "title": "Stock Exchange Jurisdiction", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", - "maxLength": 6, - "minLength": 2 - }, - "stockExchangeName": { - "type": "string", - "title": "Stock Exchange Name", - "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." - }, - "security": { - "type": "object", - "title": "Security", - "description": "Identifying information of the stock or other security.", - "required": [ - "ticker" - ], - "properties": { - "idScheme": { - "type": "string", - "title": "Identifier Scheme", - "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", - "enum": [ - "isin", - "figi", - "cusip", - "cins" - ], - "codelist": "securitiesIdentifierSchemes.csv" - }, - "id": { - "type": "string", - "title": "Identifier", - "description": "The unique identifier of the security as issued under the `idScheme`." - }, - "ticker": { - "type": "string", - "title": "Stock Ticker", - "description": "The stock ticker identifying this security on the named stock exchange." - } - } - } - } - } - } - } - }, - "formedByStatute": { - "type": "object", - "title": "Formed by Statute", - "description": "The law which mandated the formation of the entity described in the statement, where applicable. This information SHOULD be provided where a state has created an agency or other entity with specific legislation.", - "properties": { - "name": { - "type": "string", - "title": "Statute Name", - "description": "The name of the law. " - }, - "date": { - "type": "string", - "title": "Date", - "description": "The date on which the law came into force. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "format": "date" - } - }, - "propertyOrder": 18 - } - }, - "required": [ - "isComponent", - "entityType" - ], - "$defs": { - "PublicListing": { - "type": "object", - "title": "Public Listing", - "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", - "required": [ - "hasPublicListing" - ], - "minProperties": 1, - "properties": { - "hasPublicListing": { - "type": "boolean", - "title": "Has Public Listing", - "description": "Whether the entity is a publicly listed company." - }, - "companyFilingsURLs": { - "type": "array", - "title": "Company Filings URLs", - "description": "URL or URLs where regulatory filings related to major holdings can be retrieved. URLs may point to pages maintained by regulatory bodies, stock exchanges or by the company itself.", - "items": { - "type": "string", - "format": "uri" - } - }, - "securitiesListings": { - "type": "array", - "title": "Securities Listings", - "description": "Details of the entity's securities and the public exchanges and markets on which they are traded. All equity securities SHOULD be listed here, plus any other securities from which beneficial ownership might be derived. Where a security is traded on more than one market, there SHOULD be an entry for each market (or market segment).", - "items": { - "type": "object", - "title": "Securities Listing", - "description": "Details of a security and the market on which it is traded.", - "required": [ - "stockExchangeJurisdiction", - "security", - "stockExchangeName" - ], - "properties": { - "marketIdentifierCode": { - "type": "string", - "title": "Market Identifier Code (MIC)", - "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "operatingMarketIdentifierCode": { - "type": "string", - "title": "Operating Market Identifier Code (Operating MIC)", - "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "stockExchangeJurisdiction": { - "type": "string", - "title": "Stock Exchange Jurisdiction", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", - "maxLength": 6, - "minLength": 2 - }, - "stockExchangeName": { - "type": "string", - "title": "Stock Exchange Name", - "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." - }, - "security": { - "type": "object", - "title": "Security", - "description": "Identifying information of the stock or other security.", - "required": [ - "ticker" - ], - "properties": { - "idScheme": { - "type": "string", - "title": "Identifier Scheme", - "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", - "enum": [ - "isin", - "figi", - "cusip", - "cins" - ], - "codelist": "securitiesIdentifierSchemes.csv" - }, - "id": { - "type": "string", - "title": "Identifier", - "description": "The unique identifier of the security as issued under the `idScheme`." - }, - "ticker": { - "type": "string", - "title": "Stock Ticker", - "description": "The stock ticker identifying this security on the named stock exchange." - } - } - } - } - } - } - } - }, - "SecuritiesListing": { - "type": "object", - "title": "Securities Listing", - "description": "Details of a security and the market on which it is traded.", - "required": [ - "stockExchangeJurisdiction", - "security", - "stockExchangeName" - ], - "properties": { - "marketIdentifierCode": { - "type": "string", - "title": "Market Identifier Code (MIC)", - "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "operatingMarketIdentifierCode": { - "type": "string", - "title": "Operating Market Identifier Code (Operating MIC)", - "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "stockExchangeJurisdiction": { - "type": "string", - "title": "Stock Exchange Jurisdiction", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", - "maxLength": 6, - "minLength": 2 - }, - "stockExchangeName": { - "type": "string", - "title": "Stock Exchange Name", - "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." - }, - "security": { - "type": "object", - "title": "Security", - "description": "Identifying information of the stock or other security.", - "required": [ - "ticker" - ], - "properties": { - "idScheme": { - "type": "string", - "title": "Identifier Scheme", - "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", - "enum": [ - "isin", - "figi", - "cusip", - "cins" - ], - "codelist": "securitiesIdentifierSchemes.csv" - }, - "id": { - "type": "string", - "title": "Identifier", - "description": "The unique identifier of the security as issued under the `idScheme`." - }, - "ticker": { - "type": "string", - "title": "Stock Ticker", - "description": "The stock ticker identifying this security on the named stock exchange." - } - } - } - } - } - } - } - } - } - }, - { - "if": { - "properties": { - "recordType": { - "const": "person" - } - } - }, - "then": { - "properties": { - "recordDetails": { - "$id": "urn:person", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "version": "0.4", - "type": "object", - "title": "Person Record Details", - "description": "Information about a natural person.", - "properties": { - "isComponent": { - "title": "Is component", - "description": "Whether this person is a component of an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this person MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Person Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Person Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship Statement MUST have a `isComponent` value of 'false'.", - "type": "boolean" - }, - "personType": { - "title": "Person Type", - "description": "The status of this person, using the personType codelist. Where a person has the type 'anonymousPerson' or 'unknownPerson' a reason for the absence of information SHOULD be provided in 'unspecifiedPersonDetails'", - "type": "string", - "enum": [ - "anonymousPerson", - "unknownPerson", - "knownPerson" - ], - "propertyOrder": 4, - "codelist": "personType.csv", - "openCodelist": false - }, - "unspecifiedPersonDetails": { - "title": "Unspecified or unknown person or entity", - "description": "A `reason` MUST be supplied.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", - "type": "string", - "enum": [ - "noBeneficialOwners", - "subjectUnableToConfirmOrIdentifyBeneficialOwner", - "interestedPartyHasNotProvidedInformation", - "subjectExemptFromDisclosure", - "interestedPartyExemptFromDisclosure", - "unknown", - "informationUnknownToPublisher" - ], - "codelist": "unspecifiedReason.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", - "type": "string" - } - }, - "required": [ - "reason" - ] - }, - "names": { - "title": "Names", - "description": "One or more known names for this person.", - "type": "array", - "items": { - "title": "Name", - "description": "A name by which this person is known. A name MUST be provided in `fullName`, and MAY be broken down in the `familyName`, `givenName` and `patronymicName` fields, based on the EC ISA Core Person Vocabulary (https://joinup.ec.europa.eu/solution/e-government-core-vocabularies) definitions.", - "type": "object", - "required": [ - "fullName" - ], - "properties": { - "type": { - "title": "Type", - "description": "The status of this name for the person, using the nameType codelist.", - "type": "string", - "enum": [ - "legal", - "translation", - "transliteration", - "former", - "alternative", - "birth" - ], - "codelist": "nameType.csv", - "openCodelist": false - }, - "fullName": { - "title": "Full Name", - "description": "The complete name of the person.", - "type": "string" - }, - "familyName": { - "title": "Family Name", - "description": "Part of the person's `fullName` which is shared by family members. The value may include prefixes or suffixes, e.g. 'de Boer', 'van de Putte', 'von und zu Orlow'. The value may be a multiple-part family name, such as are commonly found in Hispanic countries. For example, Miguel de Cervantes Saavedra's Family Name would be recorded as 'de Cervantes Saavedra.'", - "type": "string" - }, - "givenName": { - "title": "Given Names", - "description": "The part of the person's `fullName` that identifies the person within their family. These are given to a person by their parents at birth or may be legally recognised as 'given names' through a formal process. For example, the given name for Johann Sebastian Bach is 'Johann Sebastian'.", - "type": "string" - }, - "patronymicName": { - "title": "Patronymic Name", - "description": "Part of the person's `fullName` which is inherited from their father, as is common in countries such as Iceland, Ethiopia and Russia. For example, the 'Sergeyevich' in 'Mikhail Sergeyevich Gorbachev'.", - "type": "string" - } - } - }, - "propertyOrder": 10 - }, - "identifiers": { - "title": "Identifiers", - "description": "One or more official identifiers for this person. Where available, official registration numbers should be provided.", - "type": "array", - "items": { - "title": "Identifier", - "description": "An identifier that has been assigned to a person or entity. `scheme` or `schemeName` (or both) MUST be included in an Identifier object.", - "type": "object", - "properties": { - "id": { - "title": "ID", - "description": "The identifier for a person or entity, as issued by the scheme.", - "type": "string" - }, - "scheme": { - "title": "Scheme Code", - "description": "For entities, a code from org-id.guide (https://www.org-id.guide) for an identifier-issuing authority (e.g. 'GB-COH'). For natural persons, a value with the pattern {JURISDICTION}-{TYPE} where JURISDICTION is an ISO 3166-1 3-digit country code and TYPE is one of PASSPORT, TAXID or IDCARD.", - "type": "string" - }, - "schemeName": { - "title": "Scheme Name", - "description": "The name of the identifier-issuing authority.", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "A canonical URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) for the identifier and associated details of the person or entity, if one exists.", - "type": "string", - "format": "uri" - } - }, - "anyOf": [ - { - "required": [ - "scheme" - ] - }, - { - "required": [ - "schemeName" - ] - }, - { - "required": [ - "scheme", - "schemeName" - ] - } - ] - }, - "propertyOrder": 20 - }, - "nationalities": { - "title": "Nationality", - "description": "The nationalities held by this person.", - "type": "array", - "items": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "propertyOrder": 30 - }, - "placeOfBirth": { - "title": "Address", - "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", - "type": "object", - "properties": { - "type": { - "title": "Type", - "description": "The function of the address, using the addressType codelist.", - "type": "string", - "enum": [ - "placeOfBirth", - "residence", - "registered", - "service", - "alternative", - "business" - ], - "codelist": "addressType.csv", - "openCodelist": false - }, - "address": { - "title": "Address", - "description": "The address, with each line or component separated by a line-break or comma.", - "type": "string" - }, - "postCode": { - "title": "Postcode", - "description": "The postal code for this address.", - "type": "string" - }, - "country": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - } - } - }, - "birthDate": { - "title": "Date of Birth", - "description": "The date of birth for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", - "type": "string", - "anyOf": [ - { - "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" - }, - { - "format": "date" - } - ], - "propertyOrder": 35 - }, - "deathDate": { - "title": "Death Date", - "description": "The date of death for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", - "type": "string", - "anyOf": [ - { - "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" - }, - { - "format": "date" - } - ], - "propertyOrder": 36 - }, - "taxResidencies": { - "title": "Tax Residency", - "description": "The tax residencies held by this person, as an array of Country objects.", - "type": "array", - "items": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "propertyOrder": 55 - }, - "addresses": { - "title": "Addresses", - "description": "One or more addresses for this person.", - "type": "array", - "items": { - "title": "Address", - "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", - "type": "object", - "properties": { - "type": { - "title": "Type", - "description": "The function of the address, using the addressType codelist.", - "type": "string", - "enum": [ - "placeOfBirth", - "residence", - "registered", - "service", - "alternative", - "business" - ], - "codelist": "addressType.csv", - "openCodelist": false - }, - "address": { - "title": "Address", - "description": "The address, with each line or component separated by a line-break or comma.", - "type": "string" - }, - "postCode": { - "title": "Postcode", - "description": "The postal code for this address.", - "type": "string" - }, - "country": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - } - } - }, - "propertyOrder": 60 - }, - "politicalExposure": { - "type": "object", - "title": "Political Exposure", - "description": "Information about whether, and how, the person described by this statement is politically exposed. Use this property only if politically exposed person (PEP) declarations are expected as part of beneficial ownership declarations.", - "required": [ - "status" - ], - "properties": { - "status": { - "type": "string", - "title": "Politically Exposed Person (PEP) Status", - "description": "This value is 'isPep' or 'isNotPep' according to whether the person described by this statement has the status of politically exposed person (PEP). An 'unknown' value means a PEP status declaration is expected but missing; the reason for the missing data SHOULD be supplied in the `details` array.", - "enum": [ - "isPep", - "isNotPep", - "unknown" - ] - }, - "details": { - "type": "array", - "title": "Politically Exposed Person (PEP) Details", - "description": "One or more descriptions of this person's Politically Exposed Person (PEP) status.", - "items": { - "title": "PEP Status Details", - "description": "Information about a person's political involvement.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason for this person being declared a politically-exposed person.", - "type": "string" - }, - "missingInfoReason": { - "title": "Missing Information Reasons", - "description": "An explanation of why the PEP status for the person is not provided (i.e. `politicalExposure.status` is 'unknown'). This may be a standard descriptive phrase from the source system, or a free text justification. Where this field is present it should be the only field except for `source`.", - "type": "string" - }, - "jurisdiction": { - "title": "Jurisdiction", - "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the jurisdiction", - "type": "string" - }, - "code": { - "title": "Country or Subdivision Code", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", - "type": "string", - "maxLength": 6, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "startDate": { - "title": "State Date", - "description": "The date from which this person had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "endDate": { - "title": "End Date", - "description": "The date from which this person no longer had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "source": { - "title": "Source", - "description": "Details describing an information source.", - "type": "object", - "properties": { - "type": { - "title": "Source Type", - "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", - "type": "array", - "items": { - "type": "string", - "enum": [ - "selfDeclaration", - "officialRegister", - "thirdParty", - "primaryResearch", - "verified" - ], - "codelist": "sourceType.csv", - "openCodelist": false - } - }, - "description": { - "title": "Description", - "description": "Additional, free text information about the source of information.", - "type": "string" - }, - "url": { - "title": "Source URL", - "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", - "type": "string", - "format": "uri" - }, - "retrievedAt": { - "title": "Retrieved At", - "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "assertedBy": { - "title": "Asserted By", - "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the agent making the assertion", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "An optional URI to identify the agent making the assertion", - "type": "string", - "format": "uri" - } - } - } - } - } - } - } - } - } - } - } - }, - "required": [ - "personType", - "isComponent" - ], - "$defs": { - "Name": { - "title": "Name", - "description": "A name by which this person is known. A name MUST be provided in `fullName`, and MAY be broken down in the `familyName`, `givenName` and `patronymicName` fields, based on the EC ISA Core Person Vocabulary (https://joinup.ec.europa.eu/solution/e-government-core-vocabularies) definitions.", - "type": "object", - "required": [ - "fullName" - ], - "properties": { - "type": { - "title": "Type", - "description": "The status of this name for the person, using the nameType codelist.", - "type": "string", - "enum": [ - "legal", - "translation", - "transliteration", - "former", - "alternative", - "birth" - ], - "codelist": "nameType.csv", - "openCodelist": false - }, - "fullName": { - "title": "Full Name", - "description": "The complete name of the person.", - "type": "string" - }, - "familyName": { - "title": "Family Name", - "description": "Part of the person's `fullName` which is shared by family members. The value may include prefixes or suffixes, e.g. 'de Boer', 'van de Putte', 'von und zu Orlow'. The value may be a multiple-part family name, such as are commonly found in Hispanic countries. For example, Miguel de Cervantes Saavedra's Family Name would be recorded as 'de Cervantes Saavedra.'", - "type": "string" - }, - "givenName": { - "title": "Given Names", - "description": "The part of the person's `fullName` that identifies the person within their family. These are given to a person by their parents at birth or may be legally recognised as 'given names' through a formal process. For example, the given name for Johann Sebastian Bach is 'Johann Sebastian'.", - "type": "string" - }, - "patronymicName": { - "title": "Patronymic Name", - "description": "Part of the person's `fullName` which is inherited from their father, as is common in countries such as Iceland, Ethiopia and Russia. For example, the 'Sergeyevich' in 'Mikhail Sergeyevich Gorbachev'.", - "type": "string" - } - } - }, - "PepStatusDetails": { - "title": "PEP Status Details", - "description": "Information about a person's political involvement.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason for this person being declared a politically-exposed person.", - "type": "string" - }, - "missingInfoReason": { - "title": "Missing Information Reasons", - "description": "An explanation of why the PEP status for the person is not provided (i.e. `politicalExposure.status` is 'unknown'). This may be a standard descriptive phrase from the source system, or a free text justification. Where this field is present it should be the only field except for `source`.", - "type": "string" - }, - "jurisdiction": { - "title": "Jurisdiction", - "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the jurisdiction", - "type": "string" - }, - "code": { - "title": "Country or Subdivision Code", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", - "type": "string", - "maxLength": 6, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "startDate": { - "title": "State Date", - "description": "The date from which this person had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "endDate": { - "title": "End Date", - "description": "The date from which this person no longer had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "source": { - "title": "Source", - "description": "Details describing an information source.", - "type": "object", - "properties": { - "type": { - "title": "Source Type", - "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", - "type": "array", - "items": { - "type": "string", - "enum": [ - "selfDeclaration", - "officialRegister", - "thirdParty", - "primaryResearch", - "verified" - ], - "codelist": "sourceType.csv", - "openCodelist": false - } - }, - "description": { - "title": "Description", - "description": "Additional, free text information about the source of information.", - "type": "string" - }, - "url": { - "title": "Source URL", - "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", - "type": "string", - "format": "uri" - }, - "retrievedAt": { - "title": "Retrieved At", - "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "assertedBy": { - "title": "Asserted By", - "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the agent making the assertion", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "An optional URI to identify the agent making the assertion", - "type": "string", - "format": "uri" - } - } - } - } - } - } - } - } - } - } - } - } - }, - { - "if": { - "properties": { - "recordType": { - "const": "relationship" - } - } - }, - "then": { - "properties": { - "recordDetails": { - "$id": "urn:relationship", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "version": "0.4", - "title": "Relationship Record Details", - "description": "Information about the interests that an interested party (a person or entity) holds in the subject (an entity).", - "type": "object", - "properties": { - "isComponent": { - "title": "Is component", - "description": "Whether this relationship is a component of a wider indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this secondary Relationship Statement MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Relationship Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Relationship Statement SHOULD be considered when replacing the primary Relationship Statement, and (4) the primary Relationship Statement MUST have an `isComponent` value of 'false'. Where `isComponent` is 'false', this Relationship Statement is the primary declaration of the relationship between the `subject` and the `interestedParty`.", - "type": "boolean" - }, - "componentRecords": { - "title": "Component Record IDs", - "description": "The `recordId` values of all component records that provide detail about this relationship between the `subject` and the `interestedParty` (if it is indirect). If this relationship has components, its own `isComponent` value MUST be 'false'.", - "type": "array", - "items": { - "type": "string" - } - }, - "subject": { - "title": "Subject", - "description": "The `recordId` for the subject of the relationship, or a reason why the subject cannot be specified. The subject MUST be an entity.", - "oneOf": [ - { - "type": "string" - }, - { - "title": "Unspecified or unknown person or entity", - "description": "A `reason` MUST be supplied.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", - "type": "string", - "enum": [ - "noBeneficialOwners", - "subjectUnableToConfirmOrIdentifyBeneficialOwner", - "interestedPartyHasNotProvidedInformation", - "subjectExemptFromDisclosure", - "interestedPartyExemptFromDisclosure", - "unknown", - "informationUnknownToPublisher" - ], - "codelist": "unspecifiedReason.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", - "type": "string" - } - }, - "required": [ - "reason" - ] - } - ] - }, - "interestedParty": { - "title": "Interested Party", - "description": "The `recordId` for the interested party in the relationship, or an Unspecified Record object with a reason for why this information has not been disclosed. The interested party MAY be an entity or a person. An Unspecified Record SHOULD only be used where no information at all is known about interested parties beyond this point of the beneficial ownership network. If the interested party is known to be an entity or person but their particular identity is unavailable, a `recordId` for them SHOULD be provided here (and the their `recordDetails.[person|entity]Type` should indicate that they are anonymous or unknown).", - "oneOf": [ - { - "type": "string" - }, - { - "title": "Unspecified or unknown person or entity", - "description": "A `reason` MUST be supplied.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", - "type": "string", - "enum": [ - "noBeneficialOwners", - "subjectUnableToConfirmOrIdentifyBeneficialOwner", - "interestedPartyHasNotProvidedInformation", - "subjectExemptFromDisclosure", - "interestedPartyExemptFromDisclosure", - "unknown", - "informationUnknownToPublisher" - ], - "codelist": "unspecifiedReason.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", - "type": "string" - } - }, - "required": [ - "reason" - ] - } - ] - }, - "interests": { - "title": "Interests", - "description": "A description of the interests held by the interested party in the subject.", - "type": "array", - "items": { - "title": "Interest", - "description": "A description of an interest held by an interestedParty in the subject.", - "type": "object", - "properties": { - "type": { - "title": "Type of Interest", - "description": "The nature of the interest, using the interestType codelist.", - "type": "string", - "enum": [ - "shareholding", - "votingRights", - "appointmentOfBoard", - "otherInfluenceOrControl", - "seniorManagingOfficial", - "settlor", - "trustee", - "protector", - "beneficiaryOfLegalArrangement", - "rightsToSurplusAssetsOnDissolution", - "rightsToProfitOrIncome", - "rightsGrantedByContract", - "conditionalRightsGrantedByContract", - "controlViaCompanyRulesOrArticles", - "controlByLegalFramework", - "boardMember", - "boardChair", - "unknownInterest", - "unpublishedInterest", - "enjoymentAndUseOfAssets", - "rightToProfitOrIncomeFromAssets", - "nominee", - "nominator" - ], - "codelist": "interestType.csv", - "openCodelist": false - }, - "directOrIndirect": { - "title": "Direct or Indirect", - "description": "How directly the interest is exercised by the interested party. The value MUST be 'indirect' if intermediate entities or agents are known to exist, and MUST be 'direct' if such intermediaries are known not to exist. Otherwise the value MUST be 'unknown'.", - "type": "string", - "enum": [ - "direct", - "indirect", - "unknown" - ], - "codelist": "directOrIndirect.csv", - "openCodelist": false - }, - "beneficialOwnershipOrControl": { - "title": "Beneficial Ownership or Control", - "description": "Whether this interest (alone or with others) means the interested party is a beneficial owner of the subject. If 'true' the interested party MUST be a natural person. The definition of 'beneficial owner' in operation SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "boolean" - }, - "details": { - "title": "Details", - "description": "The local name given to this kind of interest, or further information (semi-structured or unstructured) to clarify the nature of the interest.", - "type": "string" - }, - "share": { - "title": "Percentage Share", - "description": "The proportion of this type of interest held by the interested party, where an interest is countable. Provide the `exact` percentage if known. Otherwise, `minimum` (or `exclusiveMinimum`) and `maximum` (or `exclusiveMaximum`) can be used to record the range into which the proportion falls. (The `minimum` and `maximum` values are inclusive.)", - "type": "object", - "properties": { - "exact": { - "title": "Exact percentage", - "description": "The exact share of this interest held (if available).", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "maximum": { - "title": "Maximum Percentage", - "description": "The inclusive upper bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "minimum": { - "title": "Minimum Percentage", - "description": "The inclusive lower bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "exclusiveMinimum": { - "title": "Exclusive Minimum percentage", - "description": "The exclusive lower bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "exclusiveMaximum": { - "title": "Exclusive Maximum Percentage", - "description": "The exclusive upper bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - } - } - }, - "startDate": { - "title": "Start Date", - "description": "The date from which this interest was active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "endDate": { - "title": "End Date", - "description": "The date from which this interest ceased to exist. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - } - } - } - } - }, - "required": [ - "isComponent", - "subject", - "interestedParty" - ], - "if": { - "properties": { - "isComponent": { - "const": true - } - } - }, - "then": { - "properties": { - "componentRecords": { - "const": [] - } - } - }, - "$defs": { - "Interest": { - "title": "Interest", - "description": "A description of an interest held by an interestedParty in the subject.", - "type": "object", - "properties": { - "type": { - "title": "Type of Interest", - "description": "The nature of the interest, using the interestType codelist.", - "type": "string", - "enum": [ - "shareholding", - "votingRights", - "appointmentOfBoard", - "otherInfluenceOrControl", - "seniorManagingOfficial", - "settlor", - "trustee", - "protector", - "beneficiaryOfLegalArrangement", - "rightsToSurplusAssetsOnDissolution", - "rightsToProfitOrIncome", - "rightsGrantedByContract", - "conditionalRightsGrantedByContract", - "controlViaCompanyRulesOrArticles", - "controlByLegalFramework", - "boardMember", - "boardChair", - "unknownInterest", - "unpublishedInterest", - "enjoymentAndUseOfAssets", - "rightToProfitOrIncomeFromAssets", - "nominee", - "nominator" - ], - "codelist": "interestType.csv", - "openCodelist": false - }, - "directOrIndirect": { - "title": "Direct or Indirect", - "description": "How directly the interest is exercised by the interested party. The value MUST be 'indirect' if intermediate entities or agents are known to exist, and MUST be 'direct' if such intermediaries are known not to exist. Otherwise the value MUST be 'unknown'.", - "type": "string", - "enum": [ - "direct", - "indirect", - "unknown" - ], - "codelist": "directOrIndirect.csv", - "openCodelist": false - }, - "beneficialOwnershipOrControl": { - "title": "Beneficial Ownership or Control", - "description": "Whether this interest (alone or with others) means the interested party is a beneficial owner of the subject. If 'true' the interested party MUST be a natural person. The definition of 'beneficial owner' in operation SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "boolean" - }, - "details": { - "title": "Details", - "description": "The local name given to this kind of interest, or further information (semi-structured or unstructured) to clarify the nature of the interest.", - "type": "string" - }, - "share": { - "title": "Percentage Share", - "description": "The proportion of this type of interest held by the interested party, where an interest is countable. Provide the `exact` percentage if known. Otherwise, `minimum` (or `exclusiveMinimum`) and `maximum` (or `exclusiveMaximum`) can be used to record the range into which the proportion falls. (The `minimum` and `maximum` values are inclusive.)", - "type": "object", - "properties": { - "exact": { - "title": "Exact percentage", - "description": "The exact share of this interest held (if available).", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "maximum": { - "title": "Maximum Percentage", - "description": "The inclusive upper bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "minimum": { - "title": "Minimum Percentage", - "description": "The inclusive lower bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "exclusiveMinimum": { - "title": "Exclusive Minimum percentage", - "description": "The exclusive lower bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "exclusiveMaximum": { - "title": "Exclusive Maximum Percentage", - "description": "The exclusive upper bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - } - } - }, - "startDate": { - "title": "Start Date", - "description": "The date from which this interest was active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "endDate": { - "title": "End Date", - "description": "The date from which this interest ceased to exist. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - } - } - } - } - } - } - } - } - ], - "required": [ - "statementId", - "declarationSubject", - "recordId", - "recordType", - "recordDetails", - "statementDate" - ] - }, - "$defs": { - "Statement": { - "title": "Statement", - "description": "A claim about a person, entity or relationship, made at a particular point in time.", - "type": "object", - "properties": { - "statementId": { - "title": "Statement Identifier", - "description": "A persistent globally unique identifier for this Statement. Length MUST be 32 - 64 characters (inclusive).", - "type": "string", - "minLength": 32, - "maxLength": 64 - }, - "statementDate": { - "title": "Statement Date", - "description": "The date on which this statement was declared by the source, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "annotations": { - "title": "Annotations", - "description": "Annotations about this Statement or parts of this Statement", - "type": "array", - "items": { - "title": "Annotation", - "description": "Additional information about the data contained in this Statement. Annotations can apply to a whole statement, an object or a single field. Custom properties can be included within the Annotation object to provide structured data where required.", - "type": "object", - "properties": { - "statementPointerTarget": { - "title": "Statement Fragment Pointer", - "description": "An RFC6901 JSON Pointer (https://tools.ietf.org/html/rfc6901) describing the target fragment of the statement that this Annotation applies to, starting from the root of the Statement. An empty string (\"\") indicates that the Annotation applies to the whole Statement.", - "type": "string" - }, - "creationDate": { - "title": "Creation Date", - "description": "The date on which this Annotation was created, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "createdBy": { - "title": "Created By", - "description": "The person, organisation or agent that created this Annotation.", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the person, organisation or agent that created this Annotation.", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "An optional URI to identify the person, organisation or agent that created this Annotation.", - "type": "string", - "format": "uri" - } - } - }, - "motivation": { - "title": "Motivation", - "description": "The reason for this Annotation, using the annotationMotivation codelist.", - "type": "string", - "enum": [ - "commenting", - "correcting", - "identifying", - "linking", - "transformation" - ], - "codelist": "annotationMotivation.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "A free text description providing extra information about part of this Statement.", - "type": "string" - }, - "transformedContent": { - "type": "string", - "title": "Transformed Content", - "description": "A representation of the Annotation target after the transformation in the `description` field has been applied. This field MUST only be used when the `motivation` is 'transformation'." - }, - "url": { - "title": "URL", - "description": "A linked resource that annotates, provides context for or enhances this Statement. The content of the resource, or the relationship to the statement, MAY be described in the `description` field. This field is REQUIRED if the value of `motivation` is 'linking'.", - "type": "string", - "format": "uri" - } - }, - "allOf": [ - { - "if": { - "properties": { - "motivation": { - "const": "linking" - } - } - }, - "then": { - "required": [ - "statementPointerTarget", - "motivation", - "url" - ] - }, - "else": { - "required": [ - "statementPointerTarget", - "motivation" - ] - } - }, - { - "if": { - "not": { - "properties": { - "motivation": { - "const": "transformation" - } - } - } - }, - "then": { - "properties": { - "transformedContent": { - "const": "" - } - } - } - } - ] - } - }, - "publicationDetails": { - "title": "Publication Details", - "description": "Information concerning the publication of this Statement.", - "type": "object", - "properties": { - "publicationDate": { - "title": "Publication date", - "description": "The date on which this statement was published, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "bodsVersion": { - "title": "BODS Version", - "description": "The version of the Beneficial Ownership Data Standard to which this Statement conforms, expressed as major.minor (e.g. 0.2 or 1.0). In a published BODS dataset, all Statements MUST have the same major version number.", - "type": "string", - "pattern": "^(\\d+\\.)(\\d+)$" - }, - "license": { - "title": "License URL", - "description": "A link to the license that applies to this Statement. The canonical URI of the license SHOULD be used. Publishers are encouraged to use a Public Domain Dedication or Open Definition Conformant (http://opendefinition.org/licenses/) license.", - "type": "string", - "format": "uri" - }, - "publisher": { - "type": "object", - "title": "Publisher", - "description": "Details of the organisation or person publishing a Statement.", - "properties": { - "name": { - "title": "Name", - "description": "The name of the publisher.", - "type": "string" - }, - "url": { - "title": "URL", - "description": "The URL where details of the full dataset, or of the publisher, can be found.", - "type": "string", - "format": "uri" - } - }, - "anyOf": [ - { - "required": [ - "name" - ] - }, - { - "required": [ - "url" - ] - } - ] - } - }, - "required": [ - "publicationDate", - "bodsVersion", - "publisher" - ] - }, - "source": { - "title": "Source", - "description": "Details describing an information source.", - "type": "object", - "properties": { - "type": { - "title": "Source Type", - "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", - "type": "array", - "items": { - "type": "string", - "enum": [ - "selfDeclaration", - "officialRegister", - "thirdParty", - "primaryResearch", - "verified" - ], - "codelist": "sourceType.csv", - "openCodelist": false - } - }, - "description": { - "title": "Description", - "description": "Additional, free text information about the source of information.", - "type": "string" - }, - "url": { - "title": "Source URL", - "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", - "type": "string", - "format": "uri" - }, - "retrievedAt": { - "title": "Retrieved At", - "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "assertedBy": { - "title": "Asserted By", - "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the agent making the assertion", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "An optional URI to identify the agent making the assertion", - "type": "string", - "format": "uri" - } - } - } - } - } - }, - "declaration": { - "title": "Declaration Reference", - "description": "An identifier or reference for a declaration within the publisher\u2019s system. Where a Statement is a claim from a particular declaration (made at a point in time by a `source` about a `declarationSubject`) this field identifies the declaration.", - "type": "string" - }, - "declarationSubject": { - "title": "Declaration Subject", - "description": "A `recordId` value for the subject of a beneficial ownership network (always an entity or person).", - "type": "string" - }, - "recordId": { - "title": "Record Identifier", - "description": "A unique identifier for the record (within the publisher's system) to which this Statement relates. (A record captures information about an entity, natural person or relationship within the beneficial ownership network of a particular declaration subject.)", - "type": "string" - }, - "recordType": { - "title": "Record Type", - "description": "The type of record (within the publisher's system) to which this Statement relates: entity, person, or relationship.", - "type": "string", - "enum": [ - "entity", - "person", - "relationship" - ], - "codelist": "recordType.csv", - "openCodelist": false - }, - "recordStatus": { - "title": "Record Status", - "description": "The lifecycle status of the record (within the publisher's system) to which this Statement relates, using the recordStatus codelist.", - "type": "string", - "enum": [ - "new", - "updated", - "closed" - ], - "codelist": "recordStatus.csv", - "openCodelist": false - }, - "recordDetails": { - "title": "Record Details", - "description": "The details of the entity, person or relationship as declared on the Statement Date.", - "type": "object" - } - }, - "allOf": [ - { - "if": { - "properties": { - "recordType": { - "const": "entity" - } - } - }, - "then": { - "properties": { - "recordDetails": { - "$id": "urn:entity", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "version": "0.4", - "title": "Entity Record Details", - "description": "Information about an entity.", - "type": "object", - "properties": { - "isComponent": { - "title": "Is component", - "description": "Whether this entity is a component in an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this entity MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Entity Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Entity Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship statement MUST have a `isComponent` value of 'false'.", - "type": "boolean" - }, - "entityType": { - "type": "object", - "title": "Entity Type", - "description": "The form of the entity described in the Statement.", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "title": "Type", - "description": "The general form of the entity, using the entityType codelist.", - "codelist": "entityType.csv", - "enum": [ - "registeredEntity", - "legalEntity", - "arrangement", - "anonymousEntity", - "unknownEntity", - "state", - "stateBody" - ] - }, - "subtype": { - "type": "string", - "title": "Subtype", - "description": "The particular form of the entity, where relevant, using the entitySubtype codelist. The value MUST align with the `entityType` value.", - "codelist": "entitySubtype.csv", - "enum": [ - "governmentDepartment", - "stateAgency", - "other", - "trust", - "nomination" - ], - "openCodelist": false - }, - "details": { - "type": "string", - "title": "Details", - "description": "This may be used to provide a local name for this type of entity, or any further information to identify the type of entity. For example, in Finland 'ministeri\u00f6' for a government department." - } - }, - "propertyOrder": 4, - "allOf": [ - { - "if": { - "properties": { - "type": { - "enum": [ - "arrangement" - ] - } - } - }, - "then": { - "properties": { - "subtype": { - "enum": [ - "trust", - "nomination", - "other" - ] - } - } - } - }, - { - "if": { - "properties": { - "type": { - "enum": [ - "legalEntity" - ] - } - } - }, - "then": { - "properties": { - "subtype": { - "enum": [ - "trust", - "other" - ] - } - } - } - }, - { - "if": { - "properties": { - "type": { - "enum": [ - "stateBody" - ] - } - } - }, - "then": { - "properties": { - "subtype": { - "enum": [ - "governmentDepartment", - "stateAgency", - "other" - ] - } - } - } - }, - { - "if": { - "properties": { - "type": { - "enum": [ - "registeredEntity", - "state", - "anonymousEntity", - "unknownEntity" - ] - } - } - }, - "then": { - "properties": { - "subtype": { - "enum": [ - "other" - ] - } - } - } - } - ] - }, - "unspecifiedEntityDetails": { - "title": "Unspecified or unknown person or entity", - "description": "A `reason` MUST be supplied.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", - "type": "string", - "enum": [ - "noBeneficialOwners", - "subjectUnableToConfirmOrIdentifyBeneficialOwner", - "interestedPartyHasNotProvidedInformation", - "subjectExemptFromDisclosure", - "interestedPartyExemptFromDisclosure", - "unknown", - "informationUnknownToPublisher" - ], - "codelist": "unspecifiedReason.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", - "type": "string" - } - }, - "required": [ - "reason" - ] - }, - "name": { - "title": "Entity Name", - "description": "The declared name of this entity.", - "type": "string", - "propertyOrder": 10 - }, - "alternateNames": { - "title": "Alternative Names", - "description": "An array of other names this entity is known by.", - "type": "array", - "items": { - "type": "string", - "title": "Name", - "description": "A name this entity is known by." - }, - "propertyOrder": 12 - }, - "jurisdiction": { - "title": "Jurisdiction", - "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the jurisdiction", - "type": "string" - }, - "code": { - "title": "Country or Subdivision Code", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", - "type": "string", - "maxLength": 6, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "identifiers": { - "title": "Identifiers", - "description": "One or more official identifiers for this entity. Where available, official registration numbers should be provided.", - "type": "array", - "items": { - "title": "Identifier", - "description": "An identifier that has been assigned to a person or entity. `scheme` or `schemeName` (or both) MUST be included in an Identifier object.", - "type": "object", - "properties": { - "id": { - "title": "ID", - "description": "The identifier for a person or entity, as issued by the scheme.", - "type": "string" - }, - "scheme": { - "title": "Scheme Code", - "description": "For entities, a code from org-id.guide (https://www.org-id.guide) for an identifier-issuing authority (e.g. 'GB-COH'). For natural persons, a value with the pattern {JURISDICTION}-{TYPE} where JURISDICTION is an ISO 3166-1 3-digit country code and TYPE is one of PASSPORT, TAXID or IDCARD.", - "type": "string" - }, - "schemeName": { - "title": "Scheme Name", - "description": "The name of the identifier-issuing authority.", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "A canonical URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) for the identifier and associated details of the person or entity, if one exists.", - "type": "string", - "format": "uri" - } - }, - "anyOf": [ - { - "required": [ - "scheme" - ] - }, - { - "required": [ - "schemeName" - ] - }, - { - "required": [ - "scheme", - "schemeName" - ] - } - ] - }, - "propertyOrder": 20 - }, - "foundingDate": { - "title": "Founding Date", - "description": "The date on which this entity was founded, created or registered. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date", - "propertyOrder": 30 - }, - "dissolutionDate": { - "title": "Dissolution Date", - "description": "The date on which this entity was dissolved or ceased, if it is no longer active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date", - "propertyOrder": 35 - }, - "addresses": { - "title": "Addresses", - "description": "One or more addresses for this entity.", - "type": "array", - "items": { - "title": "Address", - "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", - "type": "object", - "properties": { - "type": { - "title": "Type", - "description": "The function of the address, using the addressType codelist.", - "type": "string", - "enum": [ - "placeOfBirth", - "residence", - "registered", - "service", - "alternative", - "business" - ], - "codelist": "addressType.csv", - "openCodelist": false - }, - "address": { - "title": "Address", - "description": "The address, with each line or component separated by a line-break or comma.", - "type": "string" - }, - "postCode": { - "title": "Postcode", - "description": "The postal code for this address.", - "type": "string" - }, - "country": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - } - } - }, - "propertyOrder": 40 - }, - "uri": { - "title": "URI", - "description": "Where a persistent URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) is available for this entity this should be included.", - "type": "string", - "format": "uri", - "propertyOrder": 21 - }, - "publicListing": { - "type": "object", - "title": "Public Listing", - "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", - "required": [ - "hasPublicListing" - ], - "minProperties": 1, - "properties": { - "hasPublicListing": { - "type": "boolean", - "title": "Has Public Listing", - "description": "Whether the entity is a publicly listed company." - }, - "companyFilingsURLs": { - "type": "array", - "title": "Company Filings URLs", - "description": "URL or URLs where regulatory filings related to major holdings can be retrieved. URLs may point to pages maintained by regulatory bodies, stock exchanges or by the company itself.", - "items": { - "type": "string", - "format": "uri" - } - }, - "securitiesListings": { - "type": "array", - "title": "Securities Listings", - "description": "Details of the entity's securities and the public exchanges and markets on which they are traded. All equity securities SHOULD be listed here, plus any other securities from which beneficial ownership might be derived. Where a security is traded on more than one market, there SHOULD be an entry for each market (or market segment).", - "items": { - "type": "object", - "title": "Securities Listing", - "description": "Details of a security and the market on which it is traded.", - "required": [ - "stockExchangeJurisdiction", - "security", - "stockExchangeName" - ], - "properties": { - "marketIdentifierCode": { - "type": "string", - "title": "Market Identifier Code (MIC)", - "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "operatingMarketIdentifierCode": { - "type": "string", - "title": "Operating Market Identifier Code (Operating MIC)", - "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "stockExchangeJurisdiction": { - "type": "string", - "title": "Stock Exchange Jurisdiction", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", - "maxLength": 6, - "minLength": 2 - }, - "stockExchangeName": { - "type": "string", - "title": "Stock Exchange Name", - "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." - }, - "security": { - "type": "object", - "title": "Security", - "description": "Identifying information of the stock or other security.", - "required": [ - "ticker" - ], - "properties": { - "idScheme": { - "type": "string", - "title": "Identifier Scheme", - "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", - "enum": [ - "isin", - "figi", - "cusip", - "cins" - ], - "codelist": "securitiesIdentifierSchemes.csv" - }, - "id": { - "type": "string", - "title": "Identifier", - "description": "The unique identifier of the security as issued under the `idScheme`." - }, - "ticker": { - "type": "string", - "title": "Stock Ticker", - "description": "The stock ticker identifying this security on the named stock exchange." - } - } - } - } - } - } - } - }, - "formedByStatute": { - "type": "object", - "title": "Formed by Statute", - "description": "The law which mandated the formation of the entity described in the statement, where applicable. This information SHOULD be provided where a state has created an agency or other entity with specific legislation.", - "properties": { - "name": { - "type": "string", - "title": "Statute Name", - "description": "The name of the law. " - }, - "date": { - "type": "string", - "title": "Date", - "description": "The date on which the law came into force. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are not available, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "format": "date" - } - }, - "propertyOrder": 18 - } - }, - "required": [ - "isComponent", - "entityType" - ], - "$defs": { - "PublicListing": { - "type": "object", - "title": "Public Listing", - "description": "Details of a publicly listed company, its securities (shares and other tradable financial instruments related to the entity), and related regulatory filings.", - "required": [ - "hasPublicListing" - ], - "minProperties": 1, - "properties": { - "hasPublicListing": { - "type": "boolean", - "title": "Has Public Listing", - "description": "Whether the entity is a publicly listed company." - }, - "companyFilingsURLs": { - "type": "array", - "title": "Company Filings URLs", - "description": "URL or URLs where regulatory filings related to major holdings can be retrieved. URLs may point to pages maintained by regulatory bodies, stock exchanges or by the company itself.", - "items": { - "type": "string", - "format": "uri" - } - }, - "securitiesListings": { - "type": "array", - "title": "Securities Listings", - "description": "Details of the entity's securities and the public exchanges and markets on which they are traded. All equity securities SHOULD be listed here, plus any other securities from which beneficial ownership might be derived. Where a security is traded on more than one market, there SHOULD be an entry for each market (or market segment).", - "items": { - "type": "object", - "title": "Securities Listing", - "description": "Details of a security and the market on which it is traded.", - "required": [ - "stockExchangeJurisdiction", - "security", - "stockExchangeName" - ], - "properties": { - "marketIdentifierCode": { - "type": "string", - "title": "Market Identifier Code (MIC)", - "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "operatingMarketIdentifierCode": { - "type": "string", - "title": "Operating Market Identifier Code (Operating MIC)", - "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "stockExchangeJurisdiction": { - "type": "string", - "title": "Stock Exchange Jurisdiction", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", - "maxLength": 6, - "minLength": 2 - }, - "stockExchangeName": { - "type": "string", - "title": "Stock Exchange Name", - "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." - }, - "security": { - "type": "object", - "title": "Security", - "description": "Identifying information of the stock or other security.", - "required": [ - "ticker" - ], - "properties": { - "idScheme": { - "type": "string", - "title": "Identifier Scheme", - "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", - "enum": [ - "isin", - "figi", - "cusip", - "cins" - ], - "codelist": "securitiesIdentifierSchemes.csv" - }, - "id": { - "type": "string", - "title": "Identifier", - "description": "The unique identifier of the security as issued under the `idScheme`." - }, - "ticker": { - "type": "string", - "title": "Stock Ticker", - "description": "The stock ticker identifying this security on the named stock exchange." - } - } - } - } - } - } - } - }, - "SecuritiesListing": { - "type": "object", - "title": "Securities Listing", - "description": "Details of a security and the market on which it is traded.", - "required": [ - "stockExchangeJurisdiction", - "security", - "stockExchangeName" - ], - "properties": { - "marketIdentifierCode": { - "type": "string", - "title": "Market Identifier Code (MIC)", - "description": "The Market Identifier Code (MIC) of the market on which the security is traded. Where the security is traded on a segment of an exchange, this is the MIC of the segment. Where it is traded on the main exchange, this is the MIC of the main exchange and MUST match the `operatingMarketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "operatingMarketIdentifierCode": { - "type": "string", - "title": "Operating Market Identifier Code (Operating MIC)", - "description": "The Market Identifier Code (MIC) of the main exchange or trading platform handling trades in this security. Where the security is traded on a segment of an exchange, this is the MIC of the parent exchange or trading platform. Where it is traded on the main exchange, this is the MIC of that main exchange and MUST match the `marketIdentifierCode`. MICs are allocated and managed under ISO standard 10383." - }, - "stockExchangeJurisdiction": { - "type": "string", - "title": "Stock Exchange Jurisdiction", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction under which the exchange, market or trading platform is regulated.", - "maxLength": 6, - "minLength": 2 - }, - "stockExchangeName": { - "type": "string", - "title": "Stock Exchange Name", - "description": "The name of the exchange, market or trading platform on which the security is traded. If the security is traded on a segment of the exchange, then the name SHOULD include both elements. For example, 'London Stock Exchange - MTF'." - }, - "security": { - "type": "object", - "title": "Security", - "description": "Identifying information of the stock or other security.", - "required": [ - "ticker" - ], - "properties": { - "idScheme": { - "type": "string", - "title": "Identifier Scheme", - "description": "The scheme under which the security has been issued a unique, persistent identifier, using the securitiesIdentifierSchemes codelist.", - "enum": [ - "isin", - "figi", - "cusip", - "cins" - ], - "codelist": "securitiesIdentifierSchemes.csv" - }, - "id": { - "type": "string", - "title": "Identifier", - "description": "The unique identifier of the security as issued under the `idScheme`." - }, - "ticker": { - "type": "string", - "title": "Stock Ticker", - "description": "The stock ticker identifying this security on the named stock exchange." - } - } - } - } - } - } - } - } - } - }, - { - "if": { - "properties": { - "recordType": { - "const": "person" - } - } - }, - "then": { - "properties": { - "recordDetails": { - "$id": "urn:person", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "version": "0.4", - "type": "object", - "title": "Person Record Details", - "description": "Information about a natural person.", - "properties": { - "isComponent": { - "title": "Is component", - "description": "Whether this person is a component of an indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this person MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Person Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Person Statement SHOULD be considered when replacing the primary Relationship Statement. The primary Relationship Statement MUST have a `isComponent` value of 'false'.", - "type": "boolean" - }, - "personType": { - "title": "Person Type", - "description": "The status of this person, using the personType codelist. Where a person has the type 'anonymousPerson' or 'unknownPerson' a reason for the absence of information SHOULD be provided in 'unspecifiedPersonDetails'", - "type": "string", - "enum": [ - "anonymousPerson", - "unknownPerson", - "knownPerson" - ], - "propertyOrder": 4, - "codelist": "personType.csv", - "openCodelist": false - }, - "unspecifiedPersonDetails": { - "title": "Unspecified or unknown person or entity", - "description": "A `reason` MUST be supplied.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", - "type": "string", - "enum": [ - "noBeneficialOwners", - "subjectUnableToConfirmOrIdentifyBeneficialOwner", - "interestedPartyHasNotProvidedInformation", - "subjectExemptFromDisclosure", - "interestedPartyExemptFromDisclosure", - "unknown", - "informationUnknownToPublisher" - ], - "codelist": "unspecifiedReason.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", - "type": "string" - } - }, - "required": [ - "reason" - ] - }, - "names": { - "title": "Names", - "description": "One or more known names for this person.", - "type": "array", - "items": { - "title": "Name", - "description": "A name by which this person is known. A name MUST be provided in `fullName`, and MAY be broken down in the `familyName`, `givenName` and `patronymicName` fields, based on the EC ISA Core Person Vocabulary (https://joinup.ec.europa.eu/solution/e-government-core-vocabularies) definitions.", - "type": "object", - "required": [ - "fullName" - ], - "properties": { - "type": { - "title": "Type", - "description": "The status of this name for the person, using the nameType codelist.", - "type": "string", - "enum": [ - "legal", - "translation", - "transliteration", - "former", - "alternative", - "birth" - ], - "codelist": "nameType.csv", - "openCodelist": false - }, - "fullName": { - "title": "Full Name", - "description": "The complete name of the person.", - "type": "string" - }, - "familyName": { - "title": "Family Name", - "description": "Part of the person's `fullName` which is shared by family members. The value may include prefixes or suffixes, e.g. 'de Boer', 'van de Putte', 'von und zu Orlow'. The value may be a multiple-part family name, such as are commonly found in Hispanic countries. For example, Miguel de Cervantes Saavedra's Family Name would be recorded as 'de Cervantes Saavedra.'", - "type": "string" - }, - "givenName": { - "title": "Given Names", - "description": "The part of the person's `fullName` that identifies the person within their family. These are given to a person by their parents at birth or may be legally recognised as 'given names' through a formal process. For example, the given name for Johann Sebastian Bach is 'Johann Sebastian'.", - "type": "string" - }, - "patronymicName": { - "title": "Patronymic Name", - "description": "Part of the person's `fullName` which is inherited from their father, as is common in countries such as Iceland, Ethiopia and Russia. For example, the 'Sergeyevich' in 'Mikhail Sergeyevich Gorbachev'.", - "type": "string" - } - } - }, - "propertyOrder": 10 - }, - "identifiers": { - "title": "Identifiers", - "description": "One or more official identifiers for this person. Where available, official registration numbers should be provided.", - "type": "array", - "items": { - "title": "Identifier", - "description": "An identifier that has been assigned to a person or entity. `scheme` or `schemeName` (or both) MUST be included in an Identifier object.", - "type": "object", - "properties": { - "id": { - "title": "ID", - "description": "The identifier for a person or entity, as issued by the scheme.", - "type": "string" - }, - "scheme": { - "title": "Scheme Code", - "description": "For entities, a code from org-id.guide (https://www.org-id.guide) for an identifier-issuing authority (e.g. 'GB-COH'). For natural persons, a value with the pattern {JURISDICTION}-{TYPE} where JURISDICTION is an ISO 3166-1 3-digit country code and TYPE is one of PASSPORT, TAXID or IDCARD.", - "type": "string" - }, - "schemeName": { - "title": "Scheme Name", - "description": "The name of the identifier-issuing authority.", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "A canonical URI (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) for the identifier and associated details of the person or entity, if one exists.", - "type": "string", - "format": "uri" - } - }, - "anyOf": [ - { - "required": [ - "scheme" - ] - }, - { - "required": [ - "schemeName" - ] - }, - { - "required": [ - "scheme", - "schemeName" - ] - } - ] - }, - "propertyOrder": 20 - }, - "nationalities": { - "title": "Nationality", - "description": "The nationalities held by this person.", - "type": "array", - "items": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "propertyOrder": 30 - }, - "placeOfBirth": { - "title": "Address", - "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", - "type": "object", - "properties": { - "type": { - "title": "Type", - "description": "The function of the address, using the addressType codelist.", - "type": "string", - "enum": [ - "placeOfBirth", - "residence", - "registered", - "service", - "alternative", - "business" - ], - "codelist": "addressType.csv", - "openCodelist": false - }, - "address": { - "title": "Address", - "description": "The address, with each line or component separated by a line-break or comma.", - "type": "string" - }, - "postCode": { - "title": "Postcode", - "description": "The postal code for this address.", - "type": "string" - }, - "country": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - } - } - }, - "birthDate": { - "title": "Date of Birth", - "description": "The date of birth for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", - "type": "string", - "anyOf": [ - { - "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" - }, - { - "format": "date" - } - ], - "propertyOrder": 35 - }, - "deathDate": { - "title": "Death Date", - "description": "The date of death for this person, in YYYY, YYYY-MM, or YYYY-MM-DD format.", - "type": "string", - "anyOf": [ - { - "pattern": "^(\\d{4})(-(1[0-2]|0[1-9]))?$" - }, - { - "format": "date" - } - ], - "propertyOrder": 36 - }, - "taxResidencies": { - "title": "Tax Residency", - "description": "The tax residencies held by this person, as an array of Country objects.", - "type": "array", - "items": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "propertyOrder": 55 - }, - "addresses": { - "title": "Addresses", - "description": "One or more addresses for this person.", - "type": "array", - "items": { - "title": "Address", - "description": "Semi-structured address details, suitable for processing using address-parsing algorithms. Where postal codes and country information are isolated fields in source systems, this information SHOULD be published in the dedicated fields and SHOULD NOT be published in the `address` field.", - "type": "object", - "properties": { - "type": { - "title": "Type", - "description": "The function of the address, using the addressType codelist.", - "type": "string", - "enum": [ - "placeOfBirth", - "residence", - "registered", - "service", - "alternative", - "business" - ], - "codelist": "addressType.csv", - "openCodelist": false - }, - "address": { - "title": "Address", - "description": "The address, with each line or component separated by a line-break or comma.", - "type": "string" - }, - "postCode": { - "title": "Postcode", - "description": "The postal code for this address.", - "type": "string" - }, - "country": { - "title": "Country", - "description": "A country MUST have a name. A country SHOULD have a 2-letter country code (ISO 3166-1)", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the country", - "type": "string" - }, - "code": { - "title": "Country Code", - "description": "The 2-letter country code (ISO 3166-1) for this country.", - "type": "string", - "maxLength": 2, - "minLength": 2 - } - }, - "required": [ - "name" - ] - } - } - }, - "propertyOrder": 60 - }, - "politicalExposure": { - "type": "object", - "title": "Political Exposure", - "description": "Information about whether, and how, the person described by this statement is politically exposed. Use this property only if politically exposed person (PEP) declarations are expected as part of beneficial ownership declarations.", - "required": [ - "status" - ], - "properties": { - "status": { - "type": "string", - "title": "Politically Exposed Person (PEP) Status", - "description": "This value is 'isPep' or 'isNotPep' according to whether the person described by this statement has the status of politically exposed person (PEP). An 'unknown' value means a PEP status declaration is expected but missing; the reason for the missing data SHOULD be supplied in the `details` array.", - "enum": [ - "isPep", - "isNotPep", - "unknown" - ] - }, - "details": { - "type": "array", - "title": "Politically Exposed Person (PEP) Details", - "description": "One or more descriptions of this person's Politically Exposed Person (PEP) status.", - "items": { - "title": "PEP Status Details", - "description": "Information about a person's political involvement.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason for this person being declared a politically-exposed person.", - "type": "string" - }, - "missingInfoReason": { - "title": "Missing Information Reasons", - "description": "An explanation of why the PEP status for the person is not provided (i.e. `politicalExposure.status` is 'unknown'). This may be a standard descriptive phrase from the source system, or a free text justification. Where this field is present it should be the only field except for `source`.", - "type": "string" - }, - "jurisdiction": { - "title": "Jurisdiction", - "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the jurisdiction", - "type": "string" - }, - "code": { - "title": "Country or Subdivision Code", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", - "type": "string", - "maxLength": 6, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "startDate": { - "title": "State Date", - "description": "The date from which this person had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "endDate": { - "title": "End Date", - "description": "The date from which this person no longer had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "source": { - "title": "Source", - "description": "Details describing an information source.", - "type": "object", - "properties": { - "type": { - "title": "Source Type", - "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", - "type": "array", - "items": { - "type": "string", - "enum": [ - "selfDeclaration", - "officialRegister", - "thirdParty", - "primaryResearch", - "verified" - ], - "codelist": "sourceType.csv", - "openCodelist": false - } - }, - "description": { - "title": "Description", - "description": "Additional, free text information about the source of information.", - "type": "string" - }, - "url": { - "title": "Source URL", - "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", - "type": "string", - "format": "uri" - }, - "retrievedAt": { - "title": "Retrieved At", - "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "assertedBy": { - "title": "Asserted By", - "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the agent making the assertion", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "An optional URI to identify the agent making the assertion", - "type": "string", - "format": "uri" - } - } - } - } - } - } - } - } - } - } - } - }, - "required": [ - "personType", - "isComponent" - ], - "$defs": { - "Name": { - "title": "Name", - "description": "A name by which this person is known. A name MUST be provided in `fullName`, and MAY be broken down in the `familyName`, `givenName` and `patronymicName` fields, based on the EC ISA Core Person Vocabulary (https://joinup.ec.europa.eu/solution/e-government-core-vocabularies) definitions.", - "type": "object", - "required": [ - "fullName" - ], - "properties": { - "type": { - "title": "Type", - "description": "The status of this name for the person, using the nameType codelist.", - "type": "string", - "enum": [ - "legal", - "translation", - "transliteration", - "former", - "alternative", - "birth" - ], - "codelist": "nameType.csv", - "openCodelist": false - }, - "fullName": { - "title": "Full Name", - "description": "The complete name of the person.", - "type": "string" - }, - "familyName": { - "title": "Family Name", - "description": "Part of the person's `fullName` which is shared by family members. The value may include prefixes or suffixes, e.g. 'de Boer', 'van de Putte', 'von und zu Orlow'. The value may be a multiple-part family name, such as are commonly found in Hispanic countries. For example, Miguel de Cervantes Saavedra's Family Name would be recorded as 'de Cervantes Saavedra.'", - "type": "string" - }, - "givenName": { - "title": "Given Names", - "description": "The part of the person's `fullName` that identifies the person within their family. These are given to a person by their parents at birth or may be legally recognised as 'given names' through a formal process. For example, the given name for Johann Sebastian Bach is 'Johann Sebastian'.", - "type": "string" - }, - "patronymicName": { - "title": "Patronymic Name", - "description": "Part of the person's `fullName` which is inherited from their father, as is common in countries such as Iceland, Ethiopia and Russia. For example, the 'Sergeyevich' in 'Mikhail Sergeyevich Gorbachev'.", - "type": "string" - } - } - }, - "PepStatusDetails": { - "title": "PEP Status Details", - "description": "Information about a person's political involvement.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason for this person being declared a politically-exposed person.", - "type": "string" - }, - "missingInfoReason": { - "title": "Missing Information Reasons", - "description": "An explanation of why the PEP status for the person is not provided (i.e. `politicalExposure.status` is 'unknown'). This may be a standard descriptive phrase from the source system, or a free text justification. Where this field is present it should be the only field except for `source`.", - "type": "string" - }, - "jurisdiction": { - "title": "Jurisdiction", - "description": "A Jurisdiction MUST have a name. A jurisdiction SHOULD have a 2-letter country code (ISO 3166-1) or a subdivision code (ISO 3166-2).", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the jurisdiction", - "type": "string" - }, - "code": { - "title": "Country or Subdivision Code", - "description": "The 2-letter country code (ISO 3166-1) or the subdivision code (ISO 3166-2) for the jurisdiction.", - "type": "string", - "maxLength": 6, - "minLength": 2 - } - }, - "required": [ - "name" - ] - }, - "startDate": { - "title": "State Date", - "description": "The date from which this person had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "endDate": { - "title": "End Date", - "description": "The date from which this person no longer had the status of a Politically-exposed Person (PEP). The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "source": { - "title": "Source", - "description": "Details describing an information source.", - "type": "object", - "properties": { - "type": { - "title": "Source Type", - "description": "The types of the source, using the sourceType codelist. Include 'verified' in the array if the information in the Statement has undergone a verification process.", - "type": "array", - "items": { - "type": "string", - "enum": [ - "selfDeclaration", - "officialRegister", - "thirdParty", - "primaryResearch", - "verified" - ], - "codelist": "sourceType.csv", - "openCodelist": false - } - }, - "description": { - "title": "Description", - "description": "Additional, free text information about the source of information.", - "type": "string" - }, - "url": { - "title": "Source URL", - "description": "The external URL from which this information was fetched, if relevant. Or, if relevant, a URL providing additional detail on how this information was sourced.", - "type": "string", - "format": "uri" - }, - "retrievedAt": { - "title": "Retrieved At", - "description": "A timestamp indicating when this information was imported from an external system, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "assertedBy": { - "title": "Asserted By", - "description": "The people or organisations providing the information asserted in this Statement. This may include the declaring subject of a self-declaration, or the name of an agent making a declaration on their behalf. If this Statement has been verified, the array may include the name of the organisation providing verification.", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the agent making the assertion", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "An optional URI to identify the agent making the assertion", - "type": "string", - "format": "uri" - } - } - } - } - } - } - } - } - } - } - } - } - }, - { - "if": { - "properties": { - "recordType": { - "const": "relationship" - } - } - }, - "then": { - "properties": { - "recordDetails": { - "$id": "urn:relationship", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "version": "0.4", - "title": "Relationship Record Details", - "description": "Information about the interests that an interested party (a person or entity) holds in the subject (an entity).", - "type": "object", - "properties": { - "isComponent": { - "title": "Is component", - "description": "Whether this relationship is a component of a wider indirect relationship. Where `isComponent` is 'true': (1) the `recordId` of this secondary Relationship Statement MUST be an element in the `componentRecords` array of that primary Relationship Statement, (2) this Relationship Statement MUST come before that primary Relationship Statement in a BODS package or stream, (3) the replacement of this Relationship Statement SHOULD be considered when replacing the primary Relationship Statement, and (4) the primary Relationship Statement MUST have an `isComponent` value of 'false'. Where `isComponent` is 'false', this Relationship Statement is the primary declaration of the relationship between the `subject` and the `interestedParty`.", - "type": "boolean" - }, - "componentRecords": { - "title": "Component Record IDs", - "description": "The `recordId` values of all component records that provide detail about this relationship between the `subject` and the `interestedParty` (if it is indirect). If this relationship has components, its own `isComponent` value MUST be 'false'.", - "type": "array", - "items": { - "type": "string" - } - }, - "subject": { - "title": "Subject", - "description": "The `recordId` for the subject of the relationship, or a reason why the subject cannot be specified. The subject MUST be an entity.", - "oneOf": [ - { - "type": "string" - }, - { - "title": "Unspecified or unknown person or entity", - "description": "A `reason` MUST be supplied.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", - "type": "string", - "enum": [ - "noBeneficialOwners", - "subjectUnableToConfirmOrIdentifyBeneficialOwner", - "interestedPartyHasNotProvidedInformation", - "subjectExemptFromDisclosure", - "interestedPartyExemptFromDisclosure", - "unknown", - "informationUnknownToPublisher" - ], - "codelist": "unspecifiedReason.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", - "type": "string" - } - }, - "required": [ - "reason" - ] - } - ] - }, - "interestedParty": { - "title": "Interested Party", - "description": "The `recordId` for the interested party in the relationship, or an Unspecified Record object with a reason for why this information has not been disclosed. The interested party MAY be an entity or a person. An Unspecified Record SHOULD only be used where no information at all is known about interested parties beyond this point of the beneficial ownership network. If the interested party is known to be an entity or person but their particular identity is unavailable, a `recordId` for them SHOULD be provided here (and the their `recordDetails.[person|entity]Type` should indicate that they are anonymous or unknown).", - "oneOf": [ - { - "type": "string" - }, - { - "title": "Unspecified or unknown person or entity", - "description": "A `reason` MUST be supplied.", - "type": "object", - "properties": { - "reason": { - "title": "Reason", - "description": "The reason that a person or entity cannot be specified, using the unspecifiedReason codelist.", - "type": "string", - "enum": [ - "noBeneficialOwners", - "subjectUnableToConfirmOrIdentifyBeneficialOwner", - "interestedPartyHasNotProvidedInformation", - "subjectExemptFromDisclosure", - "interestedPartyExemptFromDisclosure", - "unknown", - "informationUnknownToPublisher" - ], - "codelist": "unspecifiedReason.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "Additional information about the absence of details for a person or entity. This field may be used to provide set phrases from a source system, or a free text explanation.", - "type": "string" - } - }, - "required": [ - "reason" - ] - } - ] - }, - "interests": { - "title": "Interests", - "description": "A description of the interests held by the interested party in the subject.", - "type": "array", - "items": { - "title": "Interest", - "description": "A description of an interest held by an interestedParty in the subject.", - "type": "object", - "properties": { - "type": { - "title": "Type of Interest", - "description": "The nature of the interest, using the interestType codelist.", - "type": "string", - "enum": [ - "shareholding", - "votingRights", - "appointmentOfBoard", - "otherInfluenceOrControl", - "seniorManagingOfficial", - "settlor", - "trustee", - "protector", - "beneficiaryOfLegalArrangement", - "rightsToSurplusAssetsOnDissolution", - "rightsToProfitOrIncome", - "rightsGrantedByContract", - "conditionalRightsGrantedByContract", - "controlViaCompanyRulesOrArticles", - "controlByLegalFramework", - "boardMember", - "boardChair", - "unknownInterest", - "unpublishedInterest", - "enjoymentAndUseOfAssets", - "rightToProfitOrIncomeFromAssets", - "nominee", - "nominator" - ], - "codelist": "interestType.csv", - "openCodelist": false - }, - "directOrIndirect": { - "title": "Direct or Indirect", - "description": "How directly the interest is exercised by the interested party. The value MUST be 'indirect' if intermediate entities or agents are known to exist, and MUST be 'direct' if such intermediaries are known not to exist. Otherwise the value MUST be 'unknown'.", - "type": "string", - "enum": [ - "direct", - "indirect", - "unknown" - ], - "codelist": "directOrIndirect.csv", - "openCodelist": false - }, - "beneficialOwnershipOrControl": { - "title": "Beneficial Ownership or Control", - "description": "Whether this interest (alone or with others) means the interested party is a beneficial owner of the subject. If 'true' the interested party MUST be a natural person. The definition of 'beneficial owner' in operation SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "boolean" - }, - "details": { - "title": "Details", - "description": "The local name given to this kind of interest, or further information (semi-structured or unstructured) to clarify the nature of the interest.", - "type": "string" - }, - "share": { - "title": "Percentage Share", - "description": "The proportion of this type of interest held by the interested party, where an interest is countable. Provide the `exact` percentage if known. Otherwise, `minimum` (or `exclusiveMinimum`) and `maximum` (or `exclusiveMaximum`) can be used to record the range into which the proportion falls. (The `minimum` and `maximum` values are inclusive.)", - "type": "object", - "properties": { - "exact": { - "title": "Exact percentage", - "description": "The exact share of this interest held (if available).", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "maximum": { - "title": "Maximum Percentage", - "description": "The inclusive upper bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "minimum": { - "title": "Minimum Percentage", - "description": "The inclusive lower bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "exclusiveMinimum": { - "title": "Exclusive Minimum percentage", - "description": "The exclusive lower bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "exclusiveMaximum": { - "title": "Exclusive Maximum Percentage", - "description": "The exclusive upper bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - } - } - }, - "startDate": { - "title": "Start Date", - "description": "The date from which this interest was active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "endDate": { - "title": "End Date", - "description": "The date from which this interest ceased to exist. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - } - } - } - } - }, - "required": [ - "isComponent", - "subject", - "interestedParty" - ], - "if": { - "properties": { - "isComponent": { - "const": true - } - } - }, - "then": { - "properties": { - "componentRecords": { - "const": [] - } - } - }, - "$defs": { - "Interest": { - "title": "Interest", - "description": "A description of an interest held by an interestedParty in the subject.", - "type": "object", - "properties": { - "type": { - "title": "Type of Interest", - "description": "The nature of the interest, using the interestType codelist.", - "type": "string", - "enum": [ - "shareholding", - "votingRights", - "appointmentOfBoard", - "otherInfluenceOrControl", - "seniorManagingOfficial", - "settlor", - "trustee", - "protector", - "beneficiaryOfLegalArrangement", - "rightsToSurplusAssetsOnDissolution", - "rightsToProfitOrIncome", - "rightsGrantedByContract", - "conditionalRightsGrantedByContract", - "controlViaCompanyRulesOrArticles", - "controlByLegalFramework", - "boardMember", - "boardChair", - "unknownInterest", - "unpublishedInterest", - "enjoymentAndUseOfAssets", - "rightToProfitOrIncomeFromAssets", - "nominee", - "nominator" - ], - "codelist": "interestType.csv", - "openCodelist": false - }, - "directOrIndirect": { - "title": "Direct or Indirect", - "description": "How directly the interest is exercised by the interested party. The value MUST be 'indirect' if intermediate entities or agents are known to exist, and MUST be 'direct' if such intermediaries are known not to exist. Otherwise the value MUST be 'unknown'.", - "type": "string", - "enum": [ - "direct", - "indirect", - "unknown" - ], - "codelist": "directOrIndirect.csv", - "openCodelist": false - }, - "beneficialOwnershipOrControl": { - "title": "Beneficial Ownership or Control", - "description": "Whether this interest (alone or with others) means the interested party is a beneficial owner of the subject. If 'true' the interested party MUST be a natural person. The definition of 'beneficial owner' in operation SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "boolean" - }, - "details": { - "title": "Details", - "description": "The local name given to this kind of interest, or further information (semi-structured or unstructured) to clarify the nature of the interest.", - "type": "string" - }, - "share": { - "title": "Percentage Share", - "description": "The proportion of this type of interest held by the interested party, where an interest is countable. Provide the `exact` percentage if known. Otherwise, `minimum` (or `exclusiveMinimum`) and `maximum` (or `exclusiveMaximum`) can be used to record the range into which the proportion falls. (The `minimum` and `maximum` values are inclusive.)", - "type": "object", - "properties": { - "exact": { - "title": "Exact percentage", - "description": "The exact share of this interest held (if available).", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "maximum": { - "title": "Maximum Percentage", - "description": "The inclusive upper bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "minimum": { - "title": "Minimum Percentage", - "description": "The inclusive lower bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "exclusiveMinimum": { - "title": "Exclusive Minimum percentage", - "description": "The exclusive lower bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - }, - "exclusiveMaximum": { - "title": "Exclusive Maximum Percentage", - "description": "The exclusive upper bound of the share of this interest.", - "type": "number", - "maximum": 100, - "minimum": 0 - } - } - }, - "startDate": { - "title": "Start Date", - "description": "The date from which this interest was active. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - }, - "endDate": { - "title": "End Date", - "description": "The date from which this interest ceased to exist. The date MUST be given in YYYY-MM-DD format. Where a precise month or date are unknown, the value may be rounded to the first day of the (first) month. This rounding SHOULD be noted in accompanying guidance (such as a publication policy or data use guide).", - "type": "string", - "format": "date" - } - } - } - } - } - } - } - } - ], - "required": [ - "statementId", - "declarationSubject", - "recordId", - "recordType", - "recordDetails", - "statementDate" - ] - }, - "Annotation": { - "title": "Annotation", - "description": "Additional information about the data contained in this Statement. Annotations can apply to a whole statement, an object or a single field. Custom properties can be included within the Annotation object to provide structured data where required.", - "type": "object", - "properties": { - "statementPointerTarget": { - "title": "Statement Fragment Pointer", - "description": "An RFC6901 JSON Pointer (https://tools.ietf.org/html/rfc6901) describing the target fragment of the statement that this Annotation applies to, starting from the root of the Statement. An empty string (\"\") indicates that the Annotation applies to the whole Statement.", - "type": "string" - }, - "creationDate": { - "title": "Creation Date", - "description": "The date on which this Annotation was created, in full-date (YYYY-MM-DD) or date-time (e.g. YYYY-MM-DDTHH:MM:SSZ) format. See the IETF RFC3339 standard, section 5.6.", - "type": "string", - "anyOf": [ - { - "format": "date" - }, - { - "format": "date-time" - } - ] - }, - "createdBy": { - "title": "Created By", - "description": "The person, organisation or agent that created this Annotation.", - "type": "object", - "properties": { - "name": { - "title": "Name", - "description": "The name of the person, organisation or agent that created this Annotation.", - "type": "string" - }, - "uri": { - "title": "URI", - "description": "An optional URI to identify the person, organisation or agent that created this Annotation.", - "type": "string", - "format": "uri" - } - } - }, - "motivation": { - "title": "Motivation", - "description": "The reason for this Annotation, using the annotationMotivation codelist.", - "type": "string", - "enum": [ - "commenting", - "correcting", - "identifying", - "linking", - "transformation" - ], - "codelist": "annotationMotivation.csv", - "openCodelist": false - }, - "description": { - "title": "Description", - "description": "A free text description providing extra information about part of this Statement.", - "type": "string" - }, - "transformedContent": { - "type": "string", - "title": "Transformed Content", - "description": "A representation of the Annotation target after the transformation in the `description` field has been applied. This field MUST only be used when the `motivation` is 'transformation'." - }, - "url": { - "title": "URL", - "description": "A linked resource that annotates, provides context for or enhances this Statement. The content of the resource, or the relationship to the statement, MAY be described in the `description` field. This field is REQUIRED if the value of `motivation` is 'linking'.", - "type": "string", - "format": "uri" - } - }, - "allOf": [ - { - "if": { - "properties": { - "motivation": { - "const": "linking" - } - } - }, - "then": { - "required": [ - "statementPointerTarget", - "motivation", - "url" - ] - }, - "else": { - "required": [ - "statementPointerTarget", - "motivation" - ] - } - }, - { - "if": { - "not": { - "properties": { - "motivation": { - "const": "transformation" - } - } - } - }, - "then": { - "properties": { - "transformedContent": { - "const": "" - } - } - } - } - ] - } - } -} diff --git a/libcovebods/data_reader.py b/libcovebods/data_reader.py index 0b5385a..ce85a57 100644 --- a/libcovebods/data_reader.py +++ b/libcovebods/data_reader.py @@ -57,12 +57,6 @@ def get_all_data(self): with open(self._filename, "rb") as fp: for statement in ijson.items(fp, "item"): statementType = get_statement_type(statement) - # statementType = ( - # statement.get("statementType") - # if isinstance(statement, dict) - # and isinstance(statement.get("statementType"), str) - # else "unknown" - # ) if statementType in count_statement_types: if ( count_statement_types[statementType] diff --git a/libcovebods/run_tasks.py b/libcovebods/run_tasks.py index 08ab182..96381e7 100644 --- a/libcovebods/run_tasks.py +++ b/libcovebods/run_tasks.py @@ -1,86 +1,98 @@ import libcovebods.data_reader -import libcovebods.tasks.checks import libcovebods.tasks.peps -import libcovebods.tasks.statistics +from libcovebods.tasks.checks import ( + legacy_checks, + pre_record_checks, + record_based_checks, +) +from libcovebods.tasks.statistics import pre_record_statistics, record_based_statistics from libcovebods.utils import get_statement_type TASK_CLASSES = [ - libcovebods.tasks.checks.LegacyChecks, - libcovebods.tasks.checks.LegacyChecksNeedingHistory, - libcovebods.tasks.checks.CheckHasPublicListing, - libcovebods.tasks.checks.CheckHasPublicListingRecord, - libcovebods.tasks.checks.CheckEntityTypeAndEntitySubtypeAlign, - libcovebods.tasks.checks.CheckEntitySecurityListingsMICSCodes, - libcovebods.tasks.checks.CheckEntitySecurityListingsMICSCodesRecord, - libcovebods.tasks.checks.CheckSourceRetrievedAtFutureDate, - libcovebods.tasks.checks.CheckStatementDateFutureDate, - libcovebods.tasks.checks.CheckAnnotationCreationDateFutureDate, - libcovebods.tasks.checks.CheckStatementPublicationDateFutureDate, - libcovebods.tasks.checks.CheckStatementPersonDateOfDeathSane, - libcovebods.tasks.checks.CheckStatementEntityFoundationDissolutionDates, - libcovebods.tasks.checks.CheckStatementPersonBirthDateSensible, - libcovebods.tasks.checks.CheckStatementRelationshipInterestsStartEndDates, - libcovebods.tasks.checks.CheckStatementRelationshipInterestsShareValues, - libcovebods.tasks.checks.CheckStatementDeclarationSubject, - libcovebods.tasks.checks.CheckStatementIsComponent, - libcovebods.tasks.checks.CheckStatementDuplicateStatementId, - libcovebods.tasks.checks.CheckStatementSeries, - libcovebods.tasks.checks.CheckStatementRelationshipParties, - libcovebods.tasks.checks.CheckAnnotationStatementPointerTarget, - libcovebods.tasks.checks.CheckStatementRelationshipInterests, - libcovebods.tasks.checks.CheckStatementSerialisation, - libcovebods.tasks.checks.CheckStatementPersonIdentifiersHaveCorrectScheme, - libcovebods.tasks.checks.CheckStatementEntityIdentifiersHaveKnownScheme, - libcovebods.tasks.statistics.StatisticsCountEntityStatements, - libcovebods.tasks.statistics.StatisticsCountEntityRecordStatements, - libcovebods.tasks.statistics.StatisticsCountPersonStatements, - libcovebods.tasks.statistics.StatisticsCountPersonRecordStatements, - libcovebods.tasks.statistics.StatisticsCountOwnershipOrControlStatements, - libcovebods.tasks.statistics.StatisticsCountOwnershipOrControlRecordStatements, - libcovebods.tasks.statistics.StatisticsCurrentOwnershipOrControlStatementsAndReplacesStatementsMissing, - libcovebods.tasks.statistics.StatisticAddress, - libcovebods.tasks.statistics.StatisticOwnershipOrControlInterestDirectOrIndirect, - libcovebods.tasks.statistics.StatisticOwnershipOrControlWithAtLeastOneInterestBeneficial, - libcovebods.tasks.statistics.StatisticDeclarationSubjects, - libcovebods.tasks.statistics.StatisticsStatementsRecordStatus, + legacy_checks.LegacyChecks, + legacy_checks.LegacyChecksNeedingHistory, + pre_record_checks.CheckHasPublicListing, + record_based_checks.CheckHasPublicListingRecord, + pre_record_checks.CheckEntityTypeAndEntitySubtypeAlign, + pre_record_checks.CheckEntitySecurityListingsMICSCodes, + record_based_checks.CheckEntitySecurityListingsMICSCodesRecord, + record_based_checks.CheckSourceRetrievedAtFutureDate, + record_based_checks.CheckStatementDateFutureDate, + record_based_checks.CheckAnnotationCreationDateFutureDate, + record_based_checks.CheckStatementPublicationDateFutureDate, + record_based_checks.CheckStatementPersonDateOfDeathSane, + record_based_checks.CheckStatementEntityFoundationDissolutionDates, + record_based_checks.CheckStatementPersonBirthDateSensible, + record_based_checks.CheckStatementRelationshipInterestsStartEndDates, + record_based_checks.CheckStatementRelationshipInterestsShareValues, + record_based_checks.CheckStatementDeclarationSubject, + record_based_checks.CheckStatementIsComponent, + record_based_checks.CheckStatementDuplicateStatementId, + record_based_checks.CheckStatementSeries, + record_based_checks.CheckStatementRelationshipParties, + record_based_checks.CheckAnnotationStatementPointerTarget, + record_based_checks.CheckStatementRelationshipInterests, + record_based_checks.CheckStatementSerialisation, + record_based_checks.CheckStatementPersonIdentifiersHaveCorrectScheme, + record_based_checks.CheckStatementEntityIdentifiersHaveKnownScheme, + pre_record_statistics.StatisticsCountEntityStatements, + record_based_statistics.StatisticsCountEntityRecordStatements, + pre_record_statistics.StatisticsCountPersonStatements, + record_based_statistics.StatisticsCountPersonRecordStatements, + pre_record_statistics.StatisticsCountOwnershipOrControlStatements, + record_based_statistics.StatisticsCountOwnershipOrControlRecordStatements, + pre_record_statistics.StatisticsCurrentOwnershipOrControlStatementsAndReplacesStatementsMissing, + pre_record_statistics.StatisticAddress, + record_based_statistics.StatisticRecordAddress, + pre_record_statistics.StatisticOwnershipOrControlInterestDirectOrIndirect, + record_based_statistics.StatisticOwnershipOrControlRecordInterestDirectOrIndirect, + pre_record_statistics.StatisticOwnershipOrControlWithAtLeastOneInterestBeneficial, + record_based_statistics.StatisticOwnershipOrControlRecordWithAtLeastOneInterestBeneficial, + record_based_statistics.StatisticDeclarationSubjects, + record_based_statistics.StatisticsStatementsRecordStatus, libcovebods.tasks.peps.PEPForSchema02Only, libcovebods.tasks.peps.PEPForSchema03AndAbove, + libcovebods.tasks.peps.PEPForSchema04AndAbove, ] TASK_CLASSES_IN_SAMPLE_MODE = [ - libcovebods.tasks.checks.LegacyChecks, - libcovebods.tasks.checks.CheckHasPublicListing, - libcovebods.tasks.checks.CheckHasPublicListingRecord, - libcovebods.tasks.checks.CheckEntityTypeAndEntitySubtypeAlign, - libcovebods.tasks.checks.CheckEntitySecurityListingsMICSCodes, - libcovebods.tasks.checks.CheckEntitySecurityListingsMICSCodesRecord, - libcovebods.tasks.checks.CheckSourceRetrievedAtFutureDate, - libcovebods.tasks.checks.CheckStatementDateFutureDate, - libcovebods.tasks.checks.CheckAnnotationCreationDateFutureDate, - libcovebods.tasks.checks.CheckStatementPublicationDateFutureDate, - libcovebods.tasks.checks.CheckStatementPersonDateOfDeathSane, - libcovebods.tasks.checks.CheckStatementEntityFoundationDissolutionDates, - libcovebods.tasks.checks.CheckStatementPersonBirthDateSensible, - libcovebods.tasks.checks.CheckStatementRelationshipInterestsStartEndDates, - libcovebods.tasks.checks.CheckStatementRelationshipInterestsShareValues, - libcovebods.tasks.checks.CheckStatementDuplicateStatementId, - libcovebods.tasks.checks.CheckAnnotationStatementPointerTarget, - libcovebods.tasks.checks.CheckStatementRelationshipInterests, - libcovebods.tasks.checks.CheckStatementPersonIdentifiersHaveCorrectScheme, - libcovebods.tasks.checks.CheckStatementEntityIdentifiersHaveKnownScheme, - libcovebods.tasks.statistics.StatisticsCountEntityStatements, - libcovebods.tasks.statistics.StatisticsCountEntityRecordStatements, - libcovebods.tasks.statistics.StatisticsCountPersonStatements, - libcovebods.tasks.statistics.StatisticsCountPersonRecordStatements, - libcovebods.tasks.statistics.StatisticsCountOwnershipOrControlStatements, - libcovebods.tasks.statistics.StatisticsCountOwnershipOrControlRecordStatements, - libcovebods.tasks.statistics.StatisticAddress, - libcovebods.tasks.statistics.StatisticOwnershipOrControlInterestDirectOrIndirect, - libcovebods.tasks.statistics.StatisticOwnershipOrControlWithAtLeastOneInterestBeneficial, - libcovebods.tasks.statistics.StatisticDeclarationSubjects, - libcovebods.tasks.statistics.StatisticsStatementsRecordStatus, + legacy_checks.LegacyChecks, + pre_record_checks.CheckHasPublicListing, + record_based_checks.CheckHasPublicListingRecord, + pre_record_checks.CheckEntityTypeAndEntitySubtypeAlign, + pre_record_checks.CheckEntitySecurityListingsMICSCodes, + record_based_checks.CheckEntitySecurityListingsMICSCodesRecord, + record_based_checks.CheckSourceRetrievedAtFutureDate, + record_based_checks.CheckStatementDateFutureDate, + record_based_checks.CheckAnnotationCreationDateFutureDate, + record_based_checks.CheckStatementPublicationDateFutureDate, + record_based_checks.CheckStatementPersonDateOfDeathSane, + record_based_checks.CheckStatementEntityFoundationDissolutionDates, + record_based_checks.CheckStatementPersonBirthDateSensible, + record_based_checks.CheckStatementRelationshipInterestsStartEndDates, + record_based_checks.CheckStatementRelationshipInterestsShareValues, + record_based_checks.CheckStatementDuplicateStatementId, + record_based_checks.CheckAnnotationStatementPointerTarget, + record_based_checks.CheckStatementRelationshipInterests, + record_based_checks.CheckStatementPersonIdentifiersHaveCorrectScheme, + record_based_checks.CheckStatementEntityIdentifiersHaveKnownScheme, + pre_record_statistics.StatisticsCountEntityStatements, + record_based_statistics.StatisticsCountEntityRecordStatements, + pre_record_statistics.StatisticsCountPersonStatements, + record_based_statistics.StatisticsCountPersonRecordStatements, + pre_record_statistics.StatisticsCountOwnershipOrControlStatements, + record_based_statistics.StatisticsCountOwnershipOrControlRecordStatements, + pre_record_statistics.StatisticAddress, + record_based_statistics.StatisticRecordAddress, + pre_record_statistics.StatisticOwnershipOrControlInterestDirectOrIndirect, + record_based_statistics.StatisticOwnershipOrControlRecordInterestDirectOrIndirect, + pre_record_statistics.StatisticOwnershipOrControlWithAtLeastOneInterestBeneficial, + record_based_statistics.StatisticOwnershipOrControlRecordWithAtLeastOneInterestBeneficial, + record_based_statistics.StatisticDeclarationSubjects, + record_based_statistics.StatisticsStatementsRecordStatus, libcovebods.tasks.peps.PEPForSchema02Only, libcovebods.tasks.peps.PEPForSchema03AndAbove, + libcovebods.tasks.peps.PEPForSchema04AndAbove, ] diff --git a/libcovebods/schema.py b/libcovebods/schema.py index 7020aee..e4a5090 100644 --- a/libcovebods/schema.py +++ b/libcovebods/schema.py @@ -58,7 +58,8 @@ def __work_out_schema_version( self.schema_version = self.config.config["schema_version"] return - # If bad data passed, then we assume it's the default version + # If bad data passed, then we assume it's the default version, + # or latest version if is record based data all_data = data_reader.get_all_data() if not isinstance(all_data, list) or len(all_data) == 0: if not isinstance(all_data, list): @@ -87,7 +88,7 @@ def __work_out_schema_version( or not isinstance(statement["publicationDetails"], dict) or "bodsVersion" not in statement["publicationDetails"] ): - # Use default version if not record based else latest version (revisit) + # Use default version if not record based else latest version if not record_based_statement(statement): self.pkg_schema_url = self.config.config["schema_url"] self.schema_host = self.config.config["schema_url_host"] @@ -113,7 +114,7 @@ def __work_out_schema_version( "type": "unknown_schema_version_used", "schema_version": str(self.schema_version_attempted), } - # Use latest non-record version if not record based else latest version (revisit) + # Use latest non-record version if not record based else latest version if not record_based_statement(statement): self.schema_version = self.config.config[ "schema_latest_nonrecord_version" @@ -141,7 +142,7 @@ def __work_out_schema_version( "type": "unknown_schema_version_used", "schema_version": self.schema_version_attempted, } - # Use latest non-record version if not record based else latest version (revisit) + # Use latest non-record version if not record based else latest version if not record_based_statement(statement): self.schema_version = self.config.config[ "schema_latest_nonrecord_version" diff --git a/libcovebods/tasks/checks/legacy_checks.py b/libcovebods/tasks/checks/legacy_checks.py new file mode 100644 index 0000000..ef40167 --- /dev/null +++ b/libcovebods/tasks/checks/legacy_checks.py @@ -0,0 +1,611 @@ +from libcove2.common import get_orgids_prefixes # type: ignore + +from libcovebods.base_task import AdditionalCheck +from libcovebods.utils import get_year_from_bods_birthdate_or_deathdate + + +class LegacyChecks(AdditionalCheck): + """Before the AdditionalCheck system was implemented, all this code was together in one class. + As we work on checks in this class, we should move them to seperate classes if possible. + This now only has legacy checks that don't need to store a history. + Ones that need to store history are in LegacyChecksNeedingHistory.""" + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_less_than("0.4") + + @staticmethod + def get_additional_check_types_possible( + lib_cove_bods_config, schema_object + ) -> list: + return [ + "entity_identifier_scheme_not_known", + "inconsistent_schema_version_used", + "wrong_address_type_used", + "person_birth_year_too_early", + "person_birth_year_too_late", + "ownership_or_control_statement_has_is_compontent_and_component_statement_ids", + "statement_is_beneficialOwnershipOrControl_but_no_person_specified", + "alternative_address_with_no_other_address_types", + ] + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.orgids_prefixes = get_orgids_prefixes() + + def check_entity_statement_first_pass(self, statement): + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. + if not statement.get("statementID"): + return + identifiers = statement.get("identifiers") + if isinstance(identifiers, list): + for identifier in identifiers: + if isinstance(identifier, dict): + if ( + "scheme" in identifier + and identifier["scheme"] + and identifier["scheme"] not in self.orgids_prefixes + ): + self._additional_check_results.append( + { + "type": "entity_identifier_scheme_not_known", + "scheme": identifier.get("scheme"), + "entity_statement": statement.get("statementID"), + } + ) + ( + inconsistent_schema_version_error, + inconsistent_schema_version_used, + ) = self._schema_object.get_inconsistent_schema_version_used_for_statement( + statement + ) + if inconsistent_schema_version_error: + self._additional_check_results.append( + { + "type": "inconsistent_schema_version_used", + "schema_version": inconsistent_schema_version_used, + "statement_type": "entity", + "statement": statement.get("statementID"), + } + ) + if self._schema_object.schema_version != "0.1": + if "addresses" in statement and isinstance(statement["addresses"], list): + self._check_addresses_list_for_alternatives(statement) + for address in statement["addresses"]: + if ( + "type" in address + and address["type"] + not in self._schema_object.get_address_types_allowed_in_entity_statement() + ): + self._additional_check_results.append( + { + "type": "wrong_address_type_used", + "address_type": address["type"], + "statement_type": "entity", + "statement": statement.get("statementID"), + } + ) + + def check_person_statement_first_pass(self, statement): + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. + if not statement.get("statementID"): + return + if "birthDate" in statement: + birth_year = get_year_from_bods_birthdate_or_deathdate( + statement["birthDate"] + ) + if birth_year: + if ( + birth_year + < self._lib_cove_bods_config.config[ + "bods_additional_checks_person_birthdate_min_year" + ] + ): + self._additional_check_results.append( + { + "type": "person_birth_year_too_early", + "year": birth_year, + "person_statement": statement.get("statementID"), + } + ) + elif ( + birth_year + > self._lib_cove_bods_config.config[ + "bods_additional_checks_person_birthdate_max_year" + ] + ): + self._additional_check_results.append( + { + "type": "person_birth_year_too_late", + "year": birth_year, + "person_statement": statement.get("statementID"), + } + ) + ( + inconsistent_schema_version_error, + inconsistent_schema_version_used, + ) = self._schema_object.get_inconsistent_schema_version_used_for_statement( + statement + ) + if inconsistent_schema_version_error: + self._additional_check_results.append( + { + "type": "inconsistent_schema_version_used", + "schema_version": inconsistent_schema_version_used, + "statement_type": "person", + "statement": statement.get("statementID"), + } + ) + if self._schema_object.schema_version != "0.1": + if "addresses" in statement and isinstance(statement["addresses"], list): + self._check_addresses_list_for_alternatives(statement) + for address in statement["addresses"]: + if ( + "type" in address + and address["type"] + not in self._schema_object.get_address_types_allowed_in_person_statement() + ): + self._additional_check_results.append( + { + "type": "wrong_address_type_used", + "address_type": address["type"], + "statement_type": "person", + "statement": statement.get("statementID"), + } + ) + + def check_ownership_or_control_statement_first_pass(self, statement): + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. + if not statement.get("statementID"): + return + ( + inconsistent_schema_version_error, + inconsistent_schema_version_used, + ) = self._schema_object.get_inconsistent_schema_version_used_for_statement( + statement + ) + if inconsistent_schema_version_error: + self._additional_check_results.append( + { + "type": "inconsistent_schema_version_used", + "schema_version": inconsistent_schema_version_used, + "statement_type": "ownership_or_control", + "statement": statement.get("statementID"), + } + ) + if self._schema_object.schema_version != "0.1": + if ( + "isComponent" in statement + and statement["isComponent"] + and "componentStatementIDs" in statement + and statement["componentStatementIDs"] + ): + self._additional_check_results.append( + { + "type": "ownership_or_control_statement_has_is_compontent_and_component_statement_ids", + "statement": statement.get("statementID"), + } + ) + # If any interest has beneficialOwnershipOrControl then a person statement ID must be specified. + interests = statement.get("interests", []) + if isinstance(interests, list): + interests_with_beneficialOwnershipOrControl = [ + i + for i in interests + if isinstance(i, dict) and i.get("beneficialOwnershipOrControl") + ] + if ( + len(interests_with_beneficialOwnershipOrControl) > 0 + and isinstance(statement.get("interestedParty", {}), dict) + and not statement.get("interestedParty").get( + "describedByPersonStatement" + ) + ): + self._additional_check_results.append( + { + "type": "statement_is_beneficialOwnershipOrControl_but_no_person_specified", + "statement_type": "ownership_or_control", + "statement": statement.get("statementID"), + } + ) + + def _check_addresses_list_for_alternatives(self, statement): + # Does this addresses list have any alternative? + found_alternative = False + for address in statement["addresses"]: + if "type" in address and address["type"] == "alternative": + found_alternative = True + + if not found_alternative: + return + + # It does! Well, if it has an alternative it must have another address that is not an alternative + found_non_alternative = False + for address in statement["addresses"]: + if "type" in address and address["type"] != "alternative": + found_non_alternative = True + + if not found_non_alternative: + self._additional_check_results.append( + { + "type": "alternative_address_with_no_other_address_types", + "statement_type": ( + "person" + if statement.get("statementType") == "personStatement" + else "entity" + ), + "statement": statement.get("statementID"), + } + ) + + +class LegacyChecksNeedingHistory(AdditionalCheck): + """Before the AdditionalCheck system was implemented, all this code was together in one class. + As we work on checks in this class, we should move them to seperate classes if possible. + This now only has legacy checks that need to store a history. + Ones that don't need to store history are in LegacyChecks.""" + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_less_than("0.4") + + @staticmethod + def get_additional_check_types_possible( + lib_cove_bods_config, schema_object + ) -> list: + return [ + "statement_is_component_but_is_after_use_in_component_statement_id", + "entity_statement_out_of_order", + "person_statement_out_of_order", + "entity_statement_not_used_in_ownership_or_control_statement", + "statement_is_component_but_not_used_in_component_statement_ids", + "person_statement_not_used_in_ownership_or_control_statement", + "entity_statement_missing", + "person_statement_missing", + "component_statement_id_not_in_package", + "duplicate_statement_id", + ] + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.person_statements_seen = [] + self.person_statements_seen_in_ownership_or_control_statement = [] + self.entity_statements_seen = [] + self.entity_statements_seen_in_ownership_or_control_statement = [] + self.ownership_or_control_statements_seen = [] + self.statement_ids_seen_in_component_statement_ids = [] + self.possible_out_of_order_statements = [] + self.statement_ids_counted = {} + + def check_entity_statement_first_pass(self, statement): + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. + if not statement.get("statementID"): + return + self.entity_statements_seen.append(statement.get("statementID")) + if self._schema_object.schema_version != "0.1": + if ( + statement.get("isComponent") + and statement.get("statementID") + and statement.get("statementID") + in self.statement_ids_seen_in_component_statement_ids + ): + self._additional_check_results.append( + { + "type": "statement_is_component_but_is_after_use_in_component_statement_id", + "statement_type": "entity", + "statement": statement.get("statementID"), + } + ) + + def check_person_statement_first_pass(self, statement): + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. + if not statement.get("statementID"): + return + self.person_statements_seen.append(statement.get("statementID")) + + def check_ownership_or_control_statement_first_pass(self, statement): + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. + if not statement.get("statementID"): + return + self.ownership_or_control_statements_seen.append(statement.get("statementID")) + interested_party = statement.get("interestedParty") + if isinstance(interested_party, dict): + interested_party_described_by_entity_statement = interested_party.get( + "describedByEntityStatement" + ) + interested_party_described_by_person_statement = interested_party.get( + "describedByPersonStatement" + ) + if interested_party_described_by_entity_statement: + self.entity_statements_seen_in_ownership_or_control_statement.append( + interested_party_described_by_entity_statement + ) + if ( + interested_party_described_by_entity_statement + not in self.entity_statements_seen + ): + self.possible_out_of_order_statements.append( + { + "type": "entity_statement_out_of_order", + "referenced_from": "interestedParty", + "entity_statement_out_of_order": interested_party_described_by_entity_statement, + "seen_in_ownership_or_control_statement": statement.get( + "statementID" + ), + } + ) + if interested_party_described_by_person_statement: + self.person_statements_seen_in_ownership_or_control_statement.append( + interested_party_described_by_person_statement + ) + if ( + interested_party_described_by_person_statement + not in self.person_statements_seen + ): + self.possible_out_of_order_statements.append( + { + "type": "person_statement_out_of_order", + "referenced_from": "interestedParty", + "person_statement_out_of_order": interested_party_described_by_person_statement, + "seen_in_ownership_or_control_statement": statement.get( + "statementID" + ), + } + ) + subject = statement.get("subject") + if isinstance(subject, dict): + subject_described_by_entity_statement = subject.get( + "describedByEntityStatement" + ) + if subject_described_by_entity_statement: + self.entity_statements_seen_in_ownership_or_control_statement.append( + subject_described_by_entity_statement + ) + if ( + subject_described_by_entity_statement + not in self.entity_statements_seen + ): + self.possible_out_of_order_statements.append( + { + "type": "entity_statement_out_of_order", + "referenced_from": "subject", + "entity_statement_out_of_order": subject_described_by_entity_statement, + "seen_in_ownership_or_control_statement": statement.get( + "statementID" + ), + } + ) + if self._schema_object.schema_version != "0.1": + if ( + statement.get("isComponent") + and statement.get("statementID") + and statement.get("statementID") + in self.statement_ids_seen_in_component_statement_ids + ): + self._additional_check_results.append( + { + "type": "statement_is_component_but_is_after_use_in_component_statement_id", + "statement_type": "ownership_or_control", + "statement": statement.get("statementID"), + } + ) + if ( + "componentStatementIDs" in statement + and not statement.get("isComponent") + and isinstance(statement["componentStatementIDs"], list) + ): + self.statement_ids_seen_in_component_statement_ids.extend( + statement["componentStatementIDs"] + ) + + def check_entity_statement_second_pass(self, statement): + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. + if not statement.get("statementID"): + return + if ( + statement.get("statementID") + not in self.entity_statements_seen_in_ownership_or_control_statement + ): + self._additional_check_results.append( + { + "type": "entity_statement_not_used_in_ownership_or_control_statement", + "entity_statement": statement.get("statementID"), + } + ) + if self._schema_object.schema_version != "0.1": + if ( + statement.get("isComponent") + and statement.get("statementID") + and statement.get("statementID") + not in self.statement_ids_seen_in_component_statement_ids + ): + self._additional_check_results.append( + { + "type": "statement_is_component_but_not_used_in_component_statement_ids", + "statement_type": "entity", + "statement": statement.get("statementID"), + } + ) + + def check_person_statement_second_pass(self, statement): + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. + if not statement.get("statementID"): + return + if ( + statement.get("statementID") + not in self.person_statements_seen_in_ownership_or_control_statement + ): + self._additional_check_results.append( + { + "type": "person_statement_not_used_in_ownership_or_control_statement", + "person_statement": statement.get("statementID"), + } + ) + if self._schema_object.schema_version != "0.1": + if ( + statement.get("isComponent") + and statement.get("statementID") + and statement.get("statementID") + not in self.statement_ids_seen_in_component_statement_ids + ): + self._additional_check_results.append( + { + "type": "statement_is_component_but_not_used_in_component_statement_ids", + "statement_type": "person", + "statement": statement.get("statementID"), + } + ) + + def check_ownership_or_control_statement_second_pass(self, statement): + # Not doing any work if no statementID preserves the old behaviour of the code, + # but this should be evaluated. + if not statement.get("statementID"): + return + interested_party = statement.get("interestedParty") + if isinstance(interested_party, dict): + interested_party_described_by_entity_statement = interested_party.get( + "describedByEntityStatement" + ) + interested_party_described_by_person_statement = interested_party.get( + "describedByPersonStatement" + ) + if interested_party_described_by_entity_statement: + if ( + interested_party_described_by_entity_statement + not in self.entity_statements_seen + ): + self._additional_check_results.append( + { + "type": "entity_statement_missing", + "missing_from": "interestedParty", + "entity_statement_missing": interested_party_described_by_entity_statement, + "seen_in_ownership_or_control_statement": statement.get( + "statementID" + ), + } + ) + if interested_party_described_by_person_statement: + if ( + interested_party_described_by_person_statement + not in self.person_statements_seen + ): + self._additional_check_results.append( + { + "type": "person_statement_missing", + "missing_from": "interestedParty", + "person_statement_missing": interested_party_described_by_person_statement, + "seen_in_ownership_or_control_statement": statement.get( + "statementID" + ), + } + ) + subject = statement.get("subject") + if isinstance(subject, dict): + subject_described_by_entity_statement = subject.get( + "describedByEntityStatement" + ) + if subject_described_by_entity_statement: + if ( + subject_described_by_entity_statement + not in self.entity_statements_seen + ): + self._additional_check_results.append( + { + "type": "entity_statement_missing", + "missing_from": "subject", + "entity_statement_missing": subject_described_by_entity_statement, + "seen_in_ownership_or_control_statement": statement.get( + "statementID" + ), + } + ) + if self._schema_object.schema_version != "0.1": + if "componentStatementIDs" in statement and isinstance( + statement["componentStatementIDs"], list + ): + for component_statement_id in statement["componentStatementIDs"]: + if ( + component_statement_id not in self.person_statements_seen + and component_statement_id not in self.entity_statements_seen + and component_statement_id + not in self.ownership_or_control_statements_seen + ): + self._additional_check_results.append( + { + "type": "component_statement_id_not_in_package", + "component_statement_id": component_statement_id, + "seen_in_ownership_or_control_statement": statement.get( + "statementID" + ), + } + ) + if ( + statement.get("isComponent") + and statement.get("statementID") + and statement.get("statementID") + not in self.statement_ids_seen_in_component_statement_ids + ): + self._additional_check_results.append( + { + "type": "statement_is_component_but_not_used_in_component_statement_ids", + "statement_type": "ownership_or_control", + "statement": statement.get("statementID"), + } + ) + + def final_checks(self): + # We have seen some possible out of order statements; + # but earlier we weren't sure if they were "out of order" or "missing"! + # Now we have other info, we can check and see which one they are. + for possible_out_of_order_statement in self.possible_out_of_order_statements: + if ( + possible_out_of_order_statement["type"] + == "entity_statement_out_of_order" + ): + if ( + possible_out_of_order_statement["entity_statement_out_of_order"] + in self.entity_statements_seen + ): + self._additional_check_results.append( + possible_out_of_order_statement + ) + else: + if ( + possible_out_of_order_statement["person_statement_out_of_order"] + in self.person_statements_seen + ): + self._additional_check_results.append( + possible_out_of_order_statement + ) + + # We can now look for duplicate IDs! + self.statement_ids_counted = {} + self._add_statement_ids_to_statement_ids_counted(self.person_statements_seen) + self._add_statement_ids_to_statement_ids_counted(self.entity_statements_seen) + self._add_statement_ids_to_statement_ids_counted( + self.ownership_or_control_statements_seen + ) + for k, v in self.statement_ids_counted.items(): + if v > 1: + self._additional_check_results.append( + { + "type": "duplicate_statement_id", + "id": k, + "count": v, + } + ) + + def _add_statement_ids_to_statement_ids_counted(self, statement_ids): + for statement_id in statement_ids: + if statement_id in self.statement_ids_counted: + self.statement_ids_counted[statement_id] += 1 + else: + self.statement_ids_counted[statement_id] = 1 diff --git a/libcovebods/tasks/checks/pre_record_checks.py b/libcovebods/tasks/checks/pre_record_checks.py new file mode 100644 index 0000000..669327e --- /dev/null +++ b/libcovebods/tasks/checks/pre_record_checks.py @@ -0,0 +1,113 @@ +from libcovebods.base_task import AdditionalCheck + + +class CheckHasPublicListing(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than( + "0.3" + ) and schema_object.is_schema_version_less_than("0.4") + + @staticmethod + def get_additional_check_types_possible( + lib_cove_bods_config, schema_object + ) -> list: + return ["has_public_listing_information_but_has_public_listing_is_false"] + + def check_entity_statement_first_pass(self, statement): + if isinstance(statement.get("publicListing"), dict): + pl = statement.get("publicListing") + if pl.get("companyFilingsURLs") or pl.get("securitiesListings"): + if not pl.get("hasPublicListing"): + self._additional_check_results.append( + { + "type": "has_public_listing_information_but_has_public_listing_is_false", + "statement_type": "entity", + "statement": statement.get("statementID"), + } + ) + + +class CheckEntityTypeAndEntitySubtypeAlign(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than( + "0.3" + ) and schema_object.is_schema_version_less_than("0.4") + + @staticmethod + def get_additional_check_types_possible( + lib_cove_bods_config, schema_object + ) -> list: + return ["statement_entity_type_and_entity_sub_type_do_not_align"] + + def check_entity_statement_first_pass(self, statement): + if isinstance(statement.get("entitySubtype"), dict): + entitySubtype = statement["entitySubtype"].get("generalCategory") + if entitySubtype and isinstance(entitySubtype, str): + entityType = statement.get("entityType") + entitySubtypeFirstBit = entitySubtype.split("-").pop(0) + if entityType != entitySubtypeFirstBit: + self._additional_check_results.append( + { + "type": "statement_entity_type_and_entity_sub_type_do_not_align", + "statement_type": "entity", + "statement": statement.get("statementID"), + } + ) + + +class CheckEntitySecurityListingsMICSCodes(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than( + "0.3" + ) and schema_object.is_schema_version_less_than("0.4") + + @staticmethod + def get_additional_check_types_possible( + lib_cove_bods_config, schema_object + ) -> list: + return ( + [ + "entity_security_listing_market_identifier_code_set_but_not_operating_market_identifier_code", + "entity_security_listing_operating_market_identifier_code_set_but_not_market_identifier_code", + ] + if ( + schema_object.is_schema_version_equal_to_or_greater_than("0.3") + and schema_object.is_schema_version_less_than("0.4") + ) + else [] + ) + + def check_entity_statement_first_pass(self, statement): + if isinstance(statement.get("publicListing"), dict) and isinstance( + statement["publicListing"].get("securitiesListings"), list + ): + for securitiesListing in statement["publicListing"].get( + "securitiesListings" + ): + if isinstance(securitiesListing, dict): + marketIdentifierCode = securitiesListing.get("marketIdentifierCode") + operatingMarketIdentifierCode = securitiesListing.get( + "operatingMarketIdentifierCode" + ) + if marketIdentifierCode and not operatingMarketIdentifierCode: + self._additional_check_results.append( + { + "type": "entity_security_listing_market_identifier_code_set_but_not_operating_market_identifier_code", + "statement_type": "entity", + "statement": statement.get("statementID"), + } + ) + elif operatingMarketIdentifierCode and not marketIdentifierCode: + self._additional_check_results.append( + { + "type": "entity_security_listing_operating_market_identifier_code_set_but_not_market_identifier_code", + "statement_type": "entity", + "statement": statement.get("statementID"), + } + ) diff --git a/libcovebods/tasks/checks.py b/libcovebods/tasks/checks/record_based_checks.py similarity index 62% rename from libcovebods/tasks/checks.py rename to libcovebods/tasks/checks/record_based_checks.py index 43e5da8..2f0f708 100644 --- a/libcovebods/tasks/checks.py +++ b/libcovebods/tasks/checks/record_based_checks.py @@ -6,646 +6,7 @@ from libcove2.common import get_orgids_prefixes # type: ignore from libcovebods.base_task import AdditionalCheck -from libcovebods.utils import ( - get_year_from_bods_birthdate_or_deathdate, - numeric_value, - parse_date_field, - sort_by_date, -) - - -class LegacyChecks(AdditionalCheck): - """Before the AdditionalCheck system was implemented, all this code was together in one class. - As we work on checks in this class, we should move them to seperate classes if possible. - This now only has legacy checks that don't need to store a history. - Ones that need to store history are in LegacyChecksNeedingHistory.""" - - @staticmethod - def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_less_than("0.4") - - @staticmethod - def get_additional_check_types_possible( - lib_cove_bods_config, schema_object - ) -> list: - return [ - "entity_identifier_scheme_not_known", - "inconsistent_schema_version_used", - "wrong_address_type_used", - "person_birth_year_too_early", - "person_birth_year_too_late", - "ownership_or_control_statement_has_is_compontent_and_component_statement_ids", - "statement_is_beneficialOwnershipOrControl_but_no_person_specified", - "alternative_address_with_no_other_address_types", - ] - - def __init__(self, lib_cove_bods_config, schema_object): - super().__init__(lib_cove_bods_config, schema_object) - self.orgids_prefixes = get_orgids_prefixes() - - def check_entity_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, - # but this should be evaluated. - if not statement.get("statementID"): - return - identifiers = statement.get("identifiers") - if isinstance(identifiers, list): - for identifier in identifiers: - if isinstance(identifier, dict): - if ( - "scheme" in identifier - and identifier["scheme"] - and identifier["scheme"] not in self.orgids_prefixes - ): - self._additional_check_results.append( - { - "type": "entity_identifier_scheme_not_known", - "scheme": identifier.get("scheme"), - "entity_statement": statement.get("statementID"), - } - ) - ( - inconsistent_schema_version_error, - inconsistent_schema_version_used, - ) = self._schema_object.get_inconsistent_schema_version_used_for_statement( - statement - ) - if inconsistent_schema_version_error: - self._additional_check_results.append( - { - "type": "inconsistent_schema_version_used", - "schema_version": inconsistent_schema_version_used, - "statement_type": "entity", - "statement": statement.get("statementID"), - } - ) - if self._schema_object.schema_version != "0.1": - if "addresses" in statement and isinstance(statement["addresses"], list): - self._check_addresses_list_for_alternatives(statement) - for address in statement["addresses"]: - if ( - "type" in address - and address["type"] - not in self._schema_object.get_address_types_allowed_in_entity_statement() - ): - self._additional_check_results.append( - { - "type": "wrong_address_type_used", - "address_type": address["type"], - "statement_type": "entity", - "statement": statement.get("statementID"), - } - ) - - def check_person_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, - # but this should be evaluated. - if not statement.get("statementID"): - return - if "birthDate" in statement: - birth_year = get_year_from_bods_birthdate_or_deathdate( - statement["birthDate"] - ) - if birth_year: - if ( - birth_year - < self._lib_cove_bods_config.config[ - "bods_additional_checks_person_birthdate_min_year" - ] - ): - self._additional_check_results.append( - { - "type": "person_birth_year_too_early", - "year": birth_year, - "person_statement": statement.get("statementID"), - } - ) - elif ( - birth_year - > self._lib_cove_bods_config.config[ - "bods_additional_checks_person_birthdate_max_year" - ] - ): - self._additional_check_results.append( - { - "type": "person_birth_year_too_late", - "year": birth_year, - "person_statement": statement.get("statementID"), - } - ) - ( - inconsistent_schema_version_error, - inconsistent_schema_version_used, - ) = self._schema_object.get_inconsistent_schema_version_used_for_statement( - statement - ) - if inconsistent_schema_version_error: - self._additional_check_results.append( - { - "type": "inconsistent_schema_version_used", - "schema_version": inconsistent_schema_version_used, - "statement_type": "person", - "statement": statement.get("statementID"), - } - ) - if self._schema_object.schema_version != "0.1": - if "addresses" in statement and isinstance(statement["addresses"], list): - self._check_addresses_list_for_alternatives(statement) - for address in statement["addresses"]: - if ( - "type" in address - and address["type"] - not in self._schema_object.get_address_types_allowed_in_person_statement() - ): - self._additional_check_results.append( - { - "type": "wrong_address_type_used", - "address_type": address["type"], - "statement_type": "person", - "statement": statement.get("statementID"), - } - ) - - def check_ownership_or_control_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, - # but this should be evaluated. - if not statement.get("statementID"): - return - ( - inconsistent_schema_version_error, - inconsistent_schema_version_used, - ) = self._schema_object.get_inconsistent_schema_version_used_for_statement( - statement - ) - if inconsistent_schema_version_error: - self._additional_check_results.append( - { - "type": "inconsistent_schema_version_used", - "schema_version": inconsistent_schema_version_used, - "statement_type": "ownership_or_control", - "statement": statement.get("statementID"), - } - ) - if self._schema_object.schema_version != "0.1": - if ( - "isComponent" in statement - and statement["isComponent"] - and "componentStatementIDs" in statement - and statement["componentStatementIDs"] - ): - self._additional_check_results.append( - { - "type": "ownership_or_control_statement_has_is_compontent_and_component_statement_ids", - "statement": statement.get("statementID"), - } - ) - # If any interest has beneficialOwnershipOrControl then a person statement ID must be specified. - interests = statement.get("interests", []) - if isinstance(interests, list): - interests_with_beneficialOwnershipOrControl = [ - i - for i in interests - if isinstance(i, dict) and i.get("beneficialOwnershipOrControl") - ] - if ( - len(interests_with_beneficialOwnershipOrControl) > 0 - and isinstance(statement.get("interestedParty", {}), dict) - and not statement.get("interestedParty").get( - "describedByPersonStatement" - ) - ): - self._additional_check_results.append( - { - "type": "statement_is_beneficialOwnershipOrControl_but_no_person_specified", - "statement_type": "ownership_or_control", - "statement": statement.get("statementID"), - } - ) - - def _check_addresses_list_for_alternatives(self, statement): - # Does this addresses list have any alternative? - found_alternative = False - for address in statement["addresses"]: - if "type" in address and address["type"] == "alternative": - found_alternative = True - - if not found_alternative: - return - - # It does! Well, if it has an alternative it must have another address that is not an alternative - found_non_alternative = False - for address in statement["addresses"]: - if "type" in address and address["type"] != "alternative": - found_non_alternative = True - - if not found_non_alternative: - self._additional_check_results.append( - { - "type": "alternative_address_with_no_other_address_types", - "statement_type": ( - "person" - if statement.get("statementType") == "personStatement" - else "entity" - ), - "statement": statement.get("statementID"), - } - ) - - -class LegacyChecksNeedingHistory(AdditionalCheck): - """Before the AdditionalCheck system was implemented, all this code was together in one class. - As we work on checks in this class, we should move them to seperate classes if possible. - This now only has legacy checks that need to store a history. - Ones that don't need to store history are in LegacyChecks.""" - - @staticmethod - def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_less_than("0.4") - - @staticmethod - def get_additional_check_types_possible( - lib_cove_bods_config, schema_object - ) -> list: - return [ - "statement_is_component_but_is_after_use_in_component_statement_id", - "entity_statement_out_of_order", - "person_statement_out_of_order", - "entity_statement_not_used_in_ownership_or_control_statement", - "statement_is_component_but_not_used_in_component_statement_ids", - "person_statement_not_used_in_ownership_or_control_statement", - "entity_statement_missing", - "person_statement_missing", - "component_statement_id_not_in_package", - "duplicate_statement_id", - ] - - def __init__(self, lib_cove_bods_config, schema_object): - super().__init__(lib_cove_bods_config, schema_object) - self.person_statements_seen = [] - self.person_statements_seen_in_ownership_or_control_statement = [] - self.entity_statements_seen = [] - self.entity_statements_seen_in_ownership_or_control_statement = [] - self.ownership_or_control_statements_seen = [] - self.statement_ids_seen_in_component_statement_ids = [] - self.possible_out_of_order_statements = [] - self.statement_ids_counted = {} - - def check_entity_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, - # but this should be evaluated. - if not statement.get("statementID"): - return - self.entity_statements_seen.append(statement.get("statementID")) - if self._schema_object.schema_version != "0.1": - if ( - statement.get("isComponent") - and statement.get("statementID") - and statement.get("statementID") - in self.statement_ids_seen_in_component_statement_ids - ): - self._additional_check_results.append( - { - "type": "statement_is_component_but_is_after_use_in_component_statement_id", - "statement_type": "entity", - "statement": statement.get("statementID"), - } - ) - - def check_person_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, - # but this should be evaluated. - if not statement.get("statementID"): - return - self.person_statements_seen.append(statement.get("statementID")) - - def check_ownership_or_control_statement_first_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, - # but this should be evaluated. - if not statement.get("statementID"): - return - self.ownership_or_control_statements_seen.append(statement.get("statementID")) - interested_party = statement.get("interestedParty") - if isinstance(interested_party, dict): - interested_party_described_by_entity_statement = interested_party.get( - "describedByEntityStatement" - ) - interested_party_described_by_person_statement = interested_party.get( - "describedByPersonStatement" - ) - if interested_party_described_by_entity_statement: - self.entity_statements_seen_in_ownership_or_control_statement.append( - interested_party_described_by_entity_statement - ) - if ( - interested_party_described_by_entity_statement - not in self.entity_statements_seen - ): - self.possible_out_of_order_statements.append( - { - "type": "entity_statement_out_of_order", - "referenced_from": "interestedParty", - "entity_statement_out_of_order": interested_party_described_by_entity_statement, - "seen_in_ownership_or_control_statement": statement.get( - "statementID" - ), - } - ) - if interested_party_described_by_person_statement: - self.person_statements_seen_in_ownership_or_control_statement.append( - interested_party_described_by_person_statement - ) - if ( - interested_party_described_by_person_statement - not in self.person_statements_seen - ): - self.possible_out_of_order_statements.append( - { - "type": "person_statement_out_of_order", - "referenced_from": "interestedParty", - "person_statement_out_of_order": interested_party_described_by_person_statement, - "seen_in_ownership_or_control_statement": statement.get( - "statementID" - ), - } - ) - subject = statement.get("subject") - if isinstance(subject, dict): - subject_described_by_entity_statement = subject.get( - "describedByEntityStatement" - ) - if subject_described_by_entity_statement: - self.entity_statements_seen_in_ownership_or_control_statement.append( - subject_described_by_entity_statement - ) - if ( - subject_described_by_entity_statement - not in self.entity_statements_seen - ): - self.possible_out_of_order_statements.append( - { - "type": "entity_statement_out_of_order", - "referenced_from": "subject", - "entity_statement_out_of_order": subject_described_by_entity_statement, - "seen_in_ownership_or_control_statement": statement.get( - "statementID" - ), - } - ) - if self._schema_object.schema_version != "0.1": - if ( - statement.get("isComponent") - and statement.get("statementID") - and statement.get("statementID") - in self.statement_ids_seen_in_component_statement_ids - ): - self._additional_check_results.append( - { - "type": "statement_is_component_but_is_after_use_in_component_statement_id", - "statement_type": "ownership_or_control", - "statement": statement.get("statementID"), - } - ) - if ( - "componentStatementIDs" in statement - and not statement.get("isComponent") - and isinstance(statement["componentStatementIDs"], list) - ): - self.statement_ids_seen_in_component_statement_ids.extend( - statement["componentStatementIDs"] - ) - - def check_entity_statement_second_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, - # but this should be evaluated. - if not statement.get("statementID"): - return - if ( - statement.get("statementID") - not in self.entity_statements_seen_in_ownership_or_control_statement - ): - self._additional_check_results.append( - { - "type": "entity_statement_not_used_in_ownership_or_control_statement", - "entity_statement": statement.get("statementID"), - } - ) - if self._schema_object.schema_version != "0.1": - if ( - statement.get("isComponent") - and statement.get("statementID") - and statement.get("statementID") - not in self.statement_ids_seen_in_component_statement_ids - ): - self._additional_check_results.append( - { - "type": "statement_is_component_but_not_used_in_component_statement_ids", - "statement_type": "entity", - "statement": statement.get("statementID"), - } - ) - - def check_person_statement_second_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, - # but this should be evaluated. - if not statement.get("statementID"): - return - if ( - statement.get("statementID") - not in self.person_statements_seen_in_ownership_or_control_statement - ): - self._additional_check_results.append( - { - "type": "person_statement_not_used_in_ownership_or_control_statement", - "person_statement": statement.get("statementID"), - } - ) - if self._schema_object.schema_version != "0.1": - if ( - statement.get("isComponent") - and statement.get("statementID") - and statement.get("statementID") - not in self.statement_ids_seen_in_component_statement_ids - ): - self._additional_check_results.append( - { - "type": "statement_is_component_but_not_used_in_component_statement_ids", - "statement_type": "person", - "statement": statement.get("statementID"), - } - ) - - def check_ownership_or_control_statement_second_pass(self, statement): - # Not doing any work if no statementID preserves the old behaviour of the code, - # but this should be evaluated. - if not statement.get("statementID"): - return - interested_party = statement.get("interestedParty") - if isinstance(interested_party, dict): - interested_party_described_by_entity_statement = interested_party.get( - "describedByEntityStatement" - ) - interested_party_described_by_person_statement = interested_party.get( - "describedByPersonStatement" - ) - if interested_party_described_by_entity_statement: - if ( - interested_party_described_by_entity_statement - not in self.entity_statements_seen - ): - self._additional_check_results.append( - { - "type": "entity_statement_missing", - "missing_from": "interestedParty", - "entity_statement_missing": interested_party_described_by_entity_statement, - "seen_in_ownership_or_control_statement": statement.get( - "statementID" - ), - } - ) - if interested_party_described_by_person_statement: - if ( - interested_party_described_by_person_statement - not in self.person_statements_seen - ): - self._additional_check_results.append( - { - "type": "person_statement_missing", - "missing_from": "interestedParty", - "person_statement_missing": interested_party_described_by_person_statement, - "seen_in_ownership_or_control_statement": statement.get( - "statementID" - ), - } - ) - subject = statement.get("subject") - if isinstance(subject, dict): - subject_described_by_entity_statement = subject.get( - "describedByEntityStatement" - ) - if subject_described_by_entity_statement: - if ( - subject_described_by_entity_statement - not in self.entity_statements_seen - ): - self._additional_check_results.append( - { - "type": "entity_statement_missing", - "missing_from": "subject", - "entity_statement_missing": subject_described_by_entity_statement, - "seen_in_ownership_or_control_statement": statement.get( - "statementID" - ), - } - ) - if self._schema_object.schema_version != "0.1": - if "componentStatementIDs" in statement and isinstance( - statement["componentStatementIDs"], list - ): - for component_statement_id in statement["componentStatementIDs"]: - if ( - component_statement_id not in self.person_statements_seen - and component_statement_id not in self.entity_statements_seen - and component_statement_id - not in self.ownership_or_control_statements_seen - ): - self._additional_check_results.append( - { - "type": "component_statement_id_not_in_package", - "component_statement_id": component_statement_id, - "seen_in_ownership_or_control_statement": statement.get( - "statementID" - ), - } - ) - if ( - statement.get("isComponent") - and statement.get("statementID") - and statement.get("statementID") - not in self.statement_ids_seen_in_component_statement_ids - ): - self._additional_check_results.append( - { - "type": "statement_is_component_but_not_used_in_component_statement_ids", - "statement_type": "ownership_or_control", - "statement": statement.get("statementID"), - } - ) - - def final_checks(self): - # We have seen some possible out of order statements; - # but earlier we weren't sure if they were "out of order" or "missing"! - # Now we have other info, we can check and see which one they are. - for possible_out_of_order_statement in self.possible_out_of_order_statements: - if ( - possible_out_of_order_statement["type"] - == "entity_statement_out_of_order" - ): - if ( - possible_out_of_order_statement["entity_statement_out_of_order"] - in self.entity_statements_seen - ): - self._additional_check_results.append( - possible_out_of_order_statement - ) - else: - if ( - possible_out_of_order_statement["person_statement_out_of_order"] - in self.person_statements_seen - ): - self._additional_check_results.append( - possible_out_of_order_statement - ) - - # We can now look for duplicate IDs! - self.statement_ids_counted = {} - self._add_statement_ids_to_statement_ids_counted(self.person_statements_seen) - self._add_statement_ids_to_statement_ids_counted(self.entity_statements_seen) - self._add_statement_ids_to_statement_ids_counted( - self.ownership_or_control_statements_seen - ) - for k, v in self.statement_ids_counted.items(): - if v > 1: - self._additional_check_results.append( - { - "type": "duplicate_statement_id", - "id": k, - "count": v, - } - ) - - def _add_statement_ids_to_statement_ids_counted(self, statement_ids): - for statement_id in statement_ids: - if statement_id in self.statement_ids_counted: - self.statement_ids_counted[statement_id] += 1 - else: - self.statement_ids_counted[statement_id] = 1 - - -class CheckHasPublicListing(AdditionalCheck): - @staticmethod - def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than( - "0.3" - ) and schema_object.is_schema_version_less_than("0.4") - - @staticmethod - def get_additional_check_types_possible( - lib_cove_bods_config, schema_object - ) -> list: - return ["has_public_listing_information_but_has_public_listing_is_false"] - - def check_entity_statement_first_pass(self, statement): - if isinstance(statement.get("publicListing"), dict): - pl = statement.get("publicListing") - if pl.get("companyFilingsURLs") or pl.get("securitiesListings"): - if not pl.get("hasPublicListing"): - self._additional_check_results.append( - { - "type": "has_public_listing_information_but_has_public_listing_is_false", - "statement_type": "entity", - "statement": statement.get("statementID"), - } - ) +from libcovebods.utils import numeric_value, parse_date_field, sort_by_date class CheckHasPublicListingRecord(AdditionalCheck): @@ -674,91 +35,6 @@ def check_entity_statement_first_pass(self, statement): ) -class CheckEntityTypeAndEntitySubtypeAlign(AdditionalCheck): - @staticmethod - def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than( - "0.3" - ) and schema_object.is_schema_version_less_than("0.4") - - @staticmethod - def get_additional_check_types_possible( - lib_cove_bods_config, schema_object - ) -> list: - return ["statement_entity_type_and_entity_sub_type_do_not_align"] - - def check_entity_statement_first_pass(self, statement): - if isinstance(statement.get("entitySubtype"), dict): - entitySubtype = statement["entitySubtype"].get("generalCategory") - if entitySubtype and isinstance(entitySubtype, str): - entityType = statement.get("entityType") - entitySubtypeFirstBit = entitySubtype.split("-").pop(0) - if entityType != entitySubtypeFirstBit: - self._additional_check_results.append( - { - "type": "statement_entity_type_and_entity_sub_type_do_not_align", - "statement_type": "entity", - "statement": statement.get("statementID"), - } - ) - - -class CheckEntitySecurityListingsMICSCodes(AdditionalCheck): - def __init__(self, lib_cove_bods_config, schema_object): - super().__init__(lib_cove_bods_config, schema_object) - - @staticmethod - def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than( - "0.3" - ) and schema_object.is_schema_version_less_than("0.4") - - @staticmethod - def get_additional_check_types_possible( - lib_cove_bods_config, schema_object - ) -> list: - return ( - [ - "entity_security_listing_market_identifier_code_set_but_not_operating_market_identifier_code", - "entity_security_listing_operating_market_identifier_code_set_but_not_market_identifier_code", - ] - if ( - schema_object.is_schema_version_equal_to_or_greater_than("0.3") - and schema_object.is_schema_version_less_than("0.4") - ) - else [] - ) - - def check_entity_statement_first_pass(self, statement): - if isinstance(statement.get("publicListing"), dict) and isinstance( - statement["publicListing"].get("securitiesListings"), list - ): - for securitiesListing in statement["publicListing"].get( - "securitiesListings" - ): - if isinstance(securitiesListing, dict): - marketIdentifierCode = securitiesListing.get("marketIdentifierCode") - operatingMarketIdentifierCode = securitiesListing.get( - "operatingMarketIdentifierCode" - ) - if marketIdentifierCode and not operatingMarketIdentifierCode: - self._additional_check_results.append( - { - "type": "entity_security_listing_market_identifier_code_set_but_not_operating_market_identifier_code", - "statement_type": "entity", - "statement": statement.get("statementID"), - } - ) - elif operatingMarketIdentifierCode and not marketIdentifierCode: - self._additional_check_results.append( - { - "type": "entity_security_listing_operating_market_identifier_code_set_but_not_market_identifier_code", - "statement_type": "entity", - "statement": statement.get("statementID"), - } - ) - - class CheckEntitySecurityListingsMICSCodesRecord(AdditionalCheck): def __init__(self, lib_cove_bods_config, schema_object): super().__init__(lib_cove_bods_config, schema_object) @@ -920,6 +196,9 @@ def check_statement_first_pass(self, statement): class CheckStatementPersonDateOfDeathSane(AdditionalCheck): def __init__(self, lib_cove_bods_config, schema_object): super().__init__(lib_cove_bods_config, schema_object) + self._min_date_year = lib_cove_bods_config.config[ + "bods_additional_checks_person_birthdate_min_year" + ] @staticmethod def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: @@ -936,7 +215,7 @@ def check_person_statement_first_pass(self, statement): if death_date: if ( death_date > datetime.now().date() - or death_date < datetime.strptime("1800-01-01", "%Y-%m-%d").date() + or death_date.year < self._min_date_year ): self._additional_check_results.append( { @@ -1803,6 +1082,9 @@ def __init__(self, lib_cove_bods_config, schema_object): self._count = 0 self._records = {} self._components = {} + self._other_codes = lib_cove_bods_config.config[ + "bods_additional_checks_other_country_codes" + ] @staticmethod def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: @@ -1833,36 +1115,11 @@ def check_person_statement_first_pass(self, statement): } ) else: - other_codes = ( - "BAH", - "D", - "EUE", - "GBD", - "GBN", - "GBO", - "GBP", - "GBS", - "UNA", - "UNK", - "UNO", - "XBA", - "XIM", - "XCC", - "XCO", - "XEC", - "XPO", - "XOM", - "XXA", - "XXB", - "XXC", - "XXX", - "ZIM", - ) if ( not pycountry.countries.get( alpha_3=identifier["scheme"].split("-")[0] ) - and identifier["scheme"].split("-")[0] not in other_codes + and identifier["scheme"].split("-")[0] not in self._other_codes ): self._additional_check_results.append( { diff --git a/libcovebods/tasks/peps.py b/libcovebods/tasks/peps.py index 2565a77..c4e045e 100644 --- a/libcovebods/tasks/peps.py +++ b/libcovebods/tasks/peps.py @@ -84,7 +84,9 @@ def __init__(self, lib_cove_bods_config, schema_object): @staticmethod def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than("0.3") + return schema_object.is_schema_version_equal_to_or_greater_than( + "0.3" + ) and schema_object.is_schema_version_less_than("0.4") @staticmethod def get_additional_check_types_possible( @@ -140,3 +142,82 @@ def get_statistics(self): "count_person_statements_have_pep_status": self.count_person_statements_have_pep_status, "count_person_statements_have_pep_status_statuses": self.count_person_statements_have_pep_status_statuses, } + + +class PEPForSchema04AndAbove(AdditionalCheck): + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.count_person_statements_have_pep_status = 0 + self.count_person_statements_have_pep_status_statuses = {} + for ( + value + ) in schema_object.get_person_statement_political_exposure_status_list(): + self.count_person_statements_have_pep_status_statuses[value] = 0 + + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + @staticmethod + def get_additional_check_types_possible( + lib_cove_bods_config, schema_object + ) -> list: + return ( + [ + "has_pep_details_with_missing_info_but_incorrect_pep_status", + "has_pep_details_but_incorrect_pep_status", + ] + if schema_object.is_schema_version_equal_to_or_greater_than("0.4") + else [] + ) + + def check_person_statement_first_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + if isinstance(statement["recordDetails"].get("politicalExposure"), dict): + status = statement["recordDetails"]["politicalExposure"].get("status") + if ( + status + in self.count_person_statements_have_pep_status_statuses.keys() + ): + self.count_person_statements_have_pep_status += 1 + self.count_person_statements_have_pep_status_statuses[status] += 1 + has_pep_details_with_missing_info_but_incorrect_pep_status = False + details = statement["recordDetails"]["politicalExposure"].get("details") + if isinstance(details, list): + details_with_missing_info = [ + x for x in details if x.get("missingInfoReason") + ] + if details_with_missing_info and status != "unknown": + has_pep_details_with_missing_info_but_incorrect_pep_status = ( + True + ) + self._additional_check_results.append( + { + "type": "has_pep_details_with_missing_info_but_incorrect_pep_status", + "statement_type": "person", + "statement": statement.get("statementID"), + } + ) + if ( + details + and (not status or status == "isNotPep") + and not has_pep_details_with_missing_info_but_incorrect_pep_status + ): + # This check is a less specific version of + # has_pep_details_with_missing_info_but_incorrect_pep_status + # so if that one has already been issued then we want to skip this one. + self._additional_check_results.append( + { + "type": "has_pep_details_but_incorrect_pep_status", + "statement_type": "person", + "statement": statement.get("statementID"), + } + ) + + def get_statistics(self): + return { + "count_person_statements_have_pep_status": self.count_person_statements_have_pep_status, + "count_person_statements_have_pep_status_statuses": self.count_person_statements_have_pep_status_statuses, + } diff --git a/libcovebods/tasks/statistics.py b/libcovebods/tasks/statistics/pre_record_statistics.py similarity index 56% rename from libcovebods/tasks/statistics.py rename to libcovebods/tasks/statistics/pre_record_statistics.py index 43003b8..f20e719 100644 --- a/libcovebods/tasks/statistics.py +++ b/libcovebods/tasks/statistics/pre_record_statistics.py @@ -67,76 +67,6 @@ def get_statistics(self): return data -class StatisticsCountEntityRecordStatements(AdditionalCheck): - @staticmethod - def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than("0.4") - - def __init__(self, lib_cove_bods_config, schema_object): - super().__init__(lib_cove_bods_config, schema_object) - self.count_entity_statements = 0 - self.count_entity_statements_types = {} - for value in schema_object.get_entity_statement_types_list(): - self.count_entity_statements_types[value] = 0 - self.count_entity_statements_types_with_any_identifier = ( - self.count_entity_statements_types.copy() - ) - self.count_entity_statements_types_with_any_identifier_with_id_and_scheme = ( - self.count_entity_statements_types.copy() - ) - - def check_entity_statement_first_pass(self, statement): - self.count_entity_statements += 1 - if ( - "recordDetails" in statement - and isinstance(statement["recordDetails"], dict) - and "entityType" in statement["recordDetails"] - and isinstance(statement["recordDetails"]["entityType"], dict) - and "type" in statement["recordDetails"]["entityType"] - and isinstance(statement["recordDetails"]["entityType"]["type"], str) - and statement["recordDetails"]["entityType"]["type"] - in self.count_entity_statements_types - ): - self.count_entity_statements_types[ - statement["recordDetails"]["entityType"]["type"] - ] += 1 - if "identifiers" in statement["recordDetails"] and isinstance( - statement["recordDetails"]["identifiers"], list - ): - has_ids = False - has_ids_with_id_and_scheme = False - for identifier in statement["recordDetails"]["identifiers"]: - if isinstance(identifier, dict): - has_ids = True - if ( - "scheme" in identifier - and isinstance(identifier["scheme"], str) - and identifier["scheme"] - and "id" in identifier - and isinstance(identifier["id"], str) - and identifier["id"] - ): - has_ids_with_id_and_scheme = True - - if has_ids: - self.count_entity_statements_types_with_any_identifier[ - statement["recordDetails"]["entityType"]["type"] - ] += 1 - if has_ids_with_id_and_scheme: - self.count_entity_statements_types_with_any_identifier_with_id_and_scheme[ - statement["recordDetails"]["entityType"]["type"] - ] += 1 - - def get_statistics(self): - data = { - "count_entity_statements": self.count_entity_statements, - "count_entity_statements_types": self.count_entity_statements_types, - "count_entity_statements_types_with_any_identifier": self.count_entity_statements_types_with_any_identifier, - "count_entity_statements_types_with_any_identifier_with_id_and_scheme": self.count_entity_statements_types_with_any_identifier_with_id_and_scheme, - } - return data - - class StatisticsCountPersonStatements(AdditionalCheck): @staticmethod def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: @@ -166,40 +96,6 @@ def get_statistics(self): return data -class StatisticsCountPersonRecordStatements(AdditionalCheck): - @staticmethod - def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than("0.4") - - def __init__(self, lib_cove_bods_config, schema_object): - super().__init__(lib_cove_bods_config, schema_object) - self.count_person_statements = 0 - self.count_person_statements_types = {} - for value in schema_object.get_person_statement_types_list(): - self.count_person_statements_types[value] = 0 - - def check_person_statement_first_pass(self, statement): - self.count_person_statements += 1 - if ( - "recordDetails" in statement - and isinstance(statement["recordDetails"], dict) - and "personType" in statement["recordDetails"] - and isinstance(statement["recordDetails"]["personType"], str) - and statement["recordDetails"]["personType"] - in self.count_person_statements_types - ): - self.count_person_statements_types[ - statement["recordDetails"]["personType"] - ] += 1 - - def get_statistics(self): - data = { - "count_person_statements": self.count_person_statements, - "count_person_statements_types": self.count_person_statements_types, - } - return data - - class StatisticsCountOwnershipOrControlStatements(AdditionalCheck): @staticmethod def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: @@ -308,118 +204,6 @@ def get_statistics(self): return data -class StatisticsCountOwnershipOrControlRecordStatements(AdditionalCheck): - @staticmethod - def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than("0.4") - - def __init__(self, lib_cove_bods_config, schema_object): - super().__init__(lib_cove_bods_config, schema_object) - self.entity_record_ids = [] - self.person_record_ids = [] - self.count_ownership_or_control_statement = 0 - self.count_ownership_or_control_statement_interested_party_with_person = 0 - self.count_ownership_or_control_statement_interested_party_with_entity = 0 - self.count_ownership_or_control_statement_interested_party_with_unspecified = 0 - self.count_ownership_or_control_statement_interested_party = 0 - self.count_ownership_or_control_statement_interest_statement_types = {} - for ( - value - ) in ( - schema_object.get_ownership_or_control_statement_interest_statement_types_list() - ): - self.count_ownership_or_control_statement_interest_statement_types[ - value - ] = 0 - self.count_ownership_or_control_statement_by_year = defaultdict(int) - self.subject_statement_ids_by_year = defaultdict(set) - self.count_ownership_or_control_statement_interested_party_by_year = ( - defaultdict(int) - ) - - def check_entity_statement_first_pass(self, statement): - if "recordId" in statement: - self.entity_record_ids.append(statement["recordId"]) - - def check_person_statement_first_pass(self, statement): - if "recordId" in statement: - self.person_record_ids.append(statement["recordId"]) - - def check_ownership_or_control_statement_first_pass(self, statement): - try: - year = int(statement.get("statementDate", "").split("-")[0]) - except (ValueError, AttributeError): - year = None - self.count_ownership_or_control_statement += 1 - if "recordDetails" in statement and isinstance( - statement["recordDetails"], dict - ): - interested_party = statement["recordDetails"].get("interestedParty") - if interested_party: - self.count_ownership_or_control_statement_interested_party += 1 - self.count_ownership_or_control_statement_interested_party_by_year[ - year - ] += 1 - if "interests" in statement["recordDetails"] and isinstance( - statement["recordDetails"]["interests"], list - ): - for interest in statement["recordDetails"]["interests"]: - if isinstance(interest, dict): - if ( - "type" in interest - and isinstance(interest["type"], str) - and interest["type"] - in self.count_ownership_or_control_statement_interest_statement_types - ): - self.count_ownership_or_control_statement_interest_statement_types[ - interest["type"] - ] += 1 - if "subject" in statement["recordDetails"] and isinstance( - statement["recordDetails"]["subject"], str - ): - self.subject_statement_ids_by_year[year].add( - statement["recordDetails"]["subject"] - ) - if "statementDate" in statement: - self.count_ownership_or_control_statement_by_year[year] += 1 - - def check_ownership_or_control_statement_second_pass(self, statement): - if "recordDetails" in statement and isinstance( - statement["recordDetails"], dict - ): - interested_party = statement["recordDetails"].get("interestedParty") - if interested_party: - if interested_party in self.entity_record_ids: - self.count_ownership_or_control_statement_interested_party_with_entity += ( - 1 - ) - if interested_party in self.person_record_ids: - self.count_ownership_or_control_statement_interested_party_with_person += ( - 1 - ) - if isinstance(interested_party, dict): - self.count_ownership_or_control_statement_interested_party_with_unspecified += ( - 1 - ) - - def get_statistics(self): - data = { - "count_ownership_or_control_statement": self.count_ownership_or_control_statement, - "count_ownership_or_control_statement_interested_party_with_person": self.count_ownership_or_control_statement_interested_party_with_person, - "count_ownership_or_control_statement_interested_party_with_entity": self.count_ownership_or_control_statement_interested_party_with_entity, - "count_ownership_or_control_statement_interested_party_with_unspecified": self.count_ownership_or_control_statement_interested_party_with_unspecified, - "count_ownership_or_control_statement_interested_party": self.count_ownership_or_control_statement_interested_party, - "count_ownership_or_control_statement_interest_statement_types": self.count_ownership_or_control_statement_interest_statement_types, - "count_ownership_or_control_statement_by_year": self.count_ownership_or_control_statement_by_year, - "count_ownership_or_control_statement_subject_by_year": { - year: len(year_set) - for year, year_set in self.subject_statement_ids_by_year.items() - }, - "count_ownership_or_control_statement_interested_party_by_year": self.count_ownership_or_control_statement_interested_party_by_year, - } - return data - - class StatisticsCurrentOwnershipOrControlStatementsAndReplacesStatementsMissing( AdditionalCheck ): @@ -463,47 +247,11 @@ def get_statistics(self): return data -class StatisticsStatementsRecordStatus(AdditionalCheck): +class StatisticAddress(AdditionalCheck): @staticmethod def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than("0.4") - - def __init__(self, lib_cove_bods_config, schema_object): - super().__init__(lib_cove_bods_config, schema_object) - self.records = {} - self.missing_new_records = {} - self.current_records_count = 0 - self.missing_new_records_count = 0 - - def check_statement_first_pass(self, statement): - if ( - isinstance(statement.get("recordStatus"), str) - and isinstance(statement.get("recordId"), str) - and statement.get("recordStatus") in ("new", "updated", "closed") - ): - if not statement.get("recordId") in self.records: - if not statement.get("recordStatus") == "new": - self.missing_new_records[statement.get("recordId")] = statement.get( - "statementId" - ) - self.records[statement.get("recordId")] = statement.get("recordStatus") - - def final_checks(self): - for record_id in self.records: - if not self.records[record_id] == "closed": - self.current_records_count += 1 - for record_id in self.missing_new_records: - self.missing_new_records_count += 1 - - def get_statistics(self): - data = { - "count_records_current": self.current_records_count, - "count_new_records_missing": self.missing_new_records_count, - } - return data - + return schema_object.is_schema_version_equal_to_or_less_than("0.3") -class StatisticAddress(AdditionalCheck): def __init__(self, lib_cove_bods_config, schema_object): super().__init__(lib_cove_bods_config, schema_object) self.count_addresses = 0 @@ -590,6 +338,10 @@ def get_statistics(self): class StatisticOwnershipOrControlWithAtLeastOneInterestBeneficial(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_less_than("0.3") + def __init__(self, lib_cove_bods_config, schema_object): super().__init__(lib_cove_bods_config, schema_object) self.stat = 0 @@ -608,26 +360,3 @@ def get_statistics(self): return { "count_ownership_or_control_statement_with_at_least_one_interest_beneficial": self.stat, } - - -class StatisticDeclarationSubjects(AdditionalCheck): - @staticmethod - def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: - return schema_object.is_schema_version_equal_to_or_greater_than("0.4") - - def __init__(self, lib_cove_bods_config, schema_object): - super().__init__(lib_cove_bods_config, schema_object) - self._declaration_subjects = {} - - def check_statement_first_pass(self, statement): - if ( - "recordId" in statement - and "declarationSubject" in statement - and statement["recordId"] == statement["declarationSubject"] - ): - self._declaration_subjects[statement["recordId"]] = 1 - - def get_statistics(self): - return { - "count_declaration_subjects": len(self._declaration_subjects), - } diff --git a/libcovebods/tasks/statistics/record_based_statistics.py b/libcovebods/tasks/statistics/record_based_statistics.py new file mode 100644 index 0000000..4bacdca --- /dev/null +++ b/libcovebods/tasks/statistics/record_based_statistics.py @@ -0,0 +1,418 @@ +from collections import defaultdict + +from libcovebods.base_task import AdditionalCheck + + +class StatisticsCountEntityRecordStatements(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.count_entity_statements = 0 + self.count_entity_statements_types = {} + for value in schema_object.get_entity_statement_types_list(): + self.count_entity_statements_types[value] = 0 + self.count_entity_statements_types_with_any_identifier = ( + self.count_entity_statements_types.copy() + ) + self.count_entity_statements_types_with_any_identifier_with_id_and_scheme = ( + self.count_entity_statements_types.copy() + ) + + def check_entity_statement_first_pass(self, statement): + self.count_entity_statements += 1 + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "entityType" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["entityType"], dict) + and "type" in statement["recordDetails"]["entityType"] + and isinstance(statement["recordDetails"]["entityType"]["type"], str) + and statement["recordDetails"]["entityType"]["type"] + in self.count_entity_statements_types + ): + self.count_entity_statements_types[ + statement["recordDetails"]["entityType"]["type"] + ] += 1 + if "identifiers" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["identifiers"], list + ): + has_ids = False + has_ids_with_id_and_scheme = False + for identifier in statement["recordDetails"]["identifiers"]: + if isinstance(identifier, dict): + has_ids = True + if ( + "scheme" in identifier + and isinstance(identifier["scheme"], str) + and identifier["scheme"] + and "id" in identifier + and isinstance(identifier["id"], str) + and identifier["id"] + ): + has_ids_with_id_and_scheme = True + + if has_ids: + self.count_entity_statements_types_with_any_identifier[ + statement["recordDetails"]["entityType"]["type"] + ] += 1 + if has_ids_with_id_and_scheme: + self.count_entity_statements_types_with_any_identifier_with_id_and_scheme[ + statement["recordDetails"]["entityType"]["type"] + ] += 1 + + def get_statistics(self): + data = { + "count_entity_statements": self.count_entity_statements, + "count_entity_statements_types": self.count_entity_statements_types, + "count_entity_statements_types_with_any_identifier": self.count_entity_statements_types_with_any_identifier, + "count_entity_statements_types_with_any_identifier_with_id_and_scheme": self.count_entity_statements_types_with_any_identifier_with_id_and_scheme, + } + return data + + +class StatisticsCountPersonRecordStatements(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.count_person_statements = 0 + self.count_person_statements_types = {} + for value in schema_object.get_person_statement_types_list(): + self.count_person_statements_types[value] = 0 + + def check_person_statement_first_pass(self, statement): + self.count_person_statements += 1 + if ( + "recordDetails" in statement + and isinstance(statement["recordDetails"], dict) + and "personType" in statement["recordDetails"] + and isinstance(statement["recordDetails"]["personType"], str) + and statement["recordDetails"]["personType"] + in self.count_person_statements_types + ): + self.count_person_statements_types[ + statement["recordDetails"]["personType"] + ] += 1 + + def get_statistics(self): + data = { + "count_person_statements": self.count_person_statements, + "count_person_statements_types": self.count_person_statements_types, + } + return data + + +class StatisticsCountOwnershipOrControlRecordStatements(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.entity_record_ids = [] + self.person_record_ids = [] + self.count_ownership_or_control_statement = 0 + self.count_ownership_or_control_statement_interested_party_with_person = 0 + self.count_ownership_or_control_statement_interested_party_with_entity = 0 + self.count_ownership_or_control_statement_interested_party_with_unspecified = 0 + self.count_ownership_or_control_statement_interested_party = 0 + self.count_ownership_or_control_statement_interest_statement_types = {} + for ( + value + ) in ( + schema_object.get_ownership_or_control_statement_interest_statement_types_list() + ): + self.count_ownership_or_control_statement_interest_statement_types[ + value + ] = 0 + self.count_ownership_or_control_statement_by_year = defaultdict(int) + self.subject_statement_ids_by_year = defaultdict(set) + self.count_ownership_or_control_statement_interested_party_by_year = ( + defaultdict(int) + ) + + def check_entity_statement_first_pass(self, statement): + if "recordId" in statement: + self.entity_record_ids.append(statement["recordId"]) + + def check_person_statement_first_pass(self, statement): + if "recordId" in statement: + self.person_record_ids.append(statement["recordId"]) + + def check_ownership_or_control_statement_first_pass(self, statement): + try: + year = int(statement.get("statementDate", "").split("-")[0]) + except (ValueError, AttributeError): + year = None + self.count_ownership_or_control_statement += 1 + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + interested_party = statement["recordDetails"].get("interestedParty") + if interested_party: + self.count_ownership_or_control_statement_interested_party += 1 + self.count_ownership_or_control_statement_interested_party_by_year[ + year + ] += 1 + if "interests" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["interests"], list + ): + for interest in statement["recordDetails"]["interests"]: + if isinstance(interest, dict): + if ( + "type" in interest + and isinstance(interest["type"], str) + and interest["type"] + in self.count_ownership_or_control_statement_interest_statement_types + ): + self.count_ownership_or_control_statement_interest_statement_types[ + interest["type"] + ] += 1 + if "subject" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["subject"], str + ): + self.subject_statement_ids_by_year[year].add( + statement["recordDetails"]["subject"] + ) + if "statementDate" in statement: + self.count_ownership_or_control_statement_by_year[year] += 1 + + def check_ownership_or_control_statement_second_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + interested_party = statement["recordDetails"].get("interestedParty") + if interested_party: + if interested_party in self.entity_record_ids: + self.count_ownership_or_control_statement_interested_party_with_entity += ( + 1 + ) + if interested_party in self.person_record_ids: + self.count_ownership_or_control_statement_interested_party_with_person += ( + 1 + ) + if isinstance(interested_party, dict): + self.count_ownership_or_control_statement_interested_party_with_unspecified += ( + 1 + ) + + def get_statistics(self): + data = { + "count_ownership_or_control_statement": self.count_ownership_or_control_statement, + "count_ownership_or_control_statement_interested_party_with_person": self.count_ownership_or_control_statement_interested_party_with_person, + "count_ownership_or_control_statement_interested_party_with_entity": self.count_ownership_or_control_statement_interested_party_with_entity, + "count_ownership_or_control_statement_interested_party_with_unspecified": self.count_ownership_or_control_statement_interested_party_with_unspecified, + "count_ownership_or_control_statement_interested_party": self.count_ownership_or_control_statement_interested_party, + "count_ownership_or_control_statement_interest_statement_types": self.count_ownership_or_control_statement_interest_statement_types, + "count_ownership_or_control_statement_by_year": self.count_ownership_or_control_statement_by_year, + "count_ownership_or_control_statement_subject_by_year": { + year: len(year_set) + for year, year_set in self.subject_statement_ids_by_year.items() + }, + "count_ownership_or_control_statement_interested_party_by_year": self.count_ownership_or_control_statement_interested_party_by_year, + } + return data + + +class StatisticsStatementsRecordStatus(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.records = {} + self.missing_new_records = {} + self.current_records_count = 0 + self.missing_new_records_count = 0 + + def check_statement_first_pass(self, statement): + if ( + isinstance(statement.get("recordStatus"), str) + and isinstance(statement.get("recordId"), str) + and statement.get("recordStatus") in ("new", "updated", "closed") + ): + if not statement.get("recordId") in self.records: + if not statement.get("recordStatus") == "new": + self.missing_new_records[statement.get("recordId")] = statement.get( + "statementId" + ) + self.records[statement.get("recordId")] = statement.get("recordStatus") + + def final_checks(self): + for record_id in self.records: + if not self.records[record_id] == "closed": + self.current_records_count += 1 + for record_id in self.missing_new_records: + self.missing_new_records_count += 1 + + def get_statistics(self): + data = { + "count_records_current": self.current_records_count, + "count_new_records_missing": self.missing_new_records_count, + } + return data + + +class StatisticRecordAddress(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.count_addresses = 0 + self.count_addresses_with_postcode = 0 + self.count_addresses_with_country = 0 + self.count_addresses_with_postcode_duplicated_in_address = 0 + + def check_entity_statement_first_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + if "addresses" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["addresses"], list + ): + for address in statement["recordDetails"]["addresses"]: + self._process_address(address) + + def check_person_statement_first_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + if "addresses" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["addresses"], list + ): + for address in statement["recordDetails"]["addresses"]: + self._process_address(address) + if "placeOfBirth" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["placeOfBirth"], dict + ): + self._process_address(statement["recordDetails"]["placeOfBirth"]) + + def _process_address(self, address): + self.count_addresses += 1 + if isinstance(address, dict): + if address.get("postCode"): + self.count_addresses_with_postcode += 1 + if address.get("country"): + self.count_addresses_with_country += 1 + if ( + address.get("postCode") + and address.get("address") + and isinstance(address.get("postCode"), str) + and isinstance(address.get("address"), str) + and address.get("postCode").lower() in address.get("address").lower() + ): + self.count_addresses_with_postcode_duplicated_in_address += 1 + + def get_statistics(self): + data = { + "count_addresses": self.count_addresses, + "count_addresses_with_postcode": self.count_addresses_with_postcode, + "count_addresses_with_country": self.count_addresses_with_country, + "count_addresses_with_postcode_duplicated_in_address": self.count_addresses_with_postcode_duplicated_in_address, + } + return data + + +class StatisticOwnershipOrControlRecordInterestDirectOrIndirect(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.count_ownership_or_control_statement_interest_direct_or_indirect = {} + for ( + value + ) in ( + schema_object.get_ownership_or_control_statement_interest_direct_or_indirect_list() + ): + self.count_ownership_or_control_statement_interest_direct_or_indirect[ + value + ] = 0 + + def check_ownership_or_control_statement_first_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + if "interests" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["interests"], list + ): + for interest in statement["recordDetails"]["interests"]: + if isinstance(interest, dict): + if ( + "directOrIndirect" in interest + and isinstance(interest["directOrIndirect"], str) + and interest["directOrIndirect"] + in self.count_ownership_or_control_statement_interest_direct_or_indirect + ): + self.count_ownership_or_control_statement_interest_direct_or_indirect[ + interest["directOrIndirect"] + ] += 1 + + def get_statistics(self): + return { + "count_ownership_or_control_statement_interest_direct_or_indirect": self.count_ownership_or_control_statement_interest_direct_or_indirect, + } + + +class StatisticOwnershipOrControlRecordWithAtLeastOneInterestBeneficial( + AdditionalCheck +): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self.stat = 0 + + def check_ownership_or_control_statement_first_pass(self, statement): + if "recordDetails" in statement and isinstance( + statement["recordDetails"], dict + ): + if "interests" in statement["recordDetails"] and isinstance( + statement["recordDetails"]["interests"], list + ): + interests_with_beneficialOwnershipOrControl = [ + i + for i in statement["recordDetails"]["interests"] + if isinstance(i, dict) and i.get("beneficialOwnershipOrControl") + ] + if interests_with_beneficialOwnershipOrControl: + self.stat += 1 + + def get_statistics(self): + return { + "count_ownership_or_control_statement_with_at_least_one_interest_beneficial": self.stat, + } + + +class StatisticDeclarationSubjects(AdditionalCheck): + @staticmethod + def does_apply_to_schema(lib_cove_bods_config, schema_object) -> bool: + return schema_object.is_schema_version_equal_to_or_greater_than("0.4") + + def __init__(self, lib_cove_bods_config, schema_object): + super().__init__(lib_cove_bods_config, schema_object) + self._declaration_subjects = {} + + def check_statement_first_pass(self, statement): + if ( + "recordId" in statement + and "declarationSubject" in statement + and statement["recordId"] == statement["declarationSubject"] + ): + self._declaration_subjects[statement["recordId"]] = 1 + + def get_statistics(self): + return { + "count_declaration_subjects": len(self._declaration_subjects), + } diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 2357282..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,11 +0,0 @@ -[tool.ruff] -lint.select = [ - "E", # pycodestyle errors - "W", # pycodestyle warnings - "F", # pyflakes - "I", # isort - "B", # flake8-bugbear - "C4", # flake8-comprehensions - "UP", # pyupgrade -] -line-length = 140 diff --git a/setup.py b/setup.py index a204aba..264f974 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="libcovebods", - version="0.16.0", + version="0.15.0", author="Open Data Services", author_email="code@opendataservices.coop", url="https://github.com/openownership/lib-cove-bods", @@ -14,10 +14,7 @@ "python-dateutil", "libcove2>=0.2.1", "packaging", - # Jsonschema 4.10 breaks the message - # 'missingPersonType' is a dependency of 'missingPersonReason' - # in tests/fixtures/0.1/badfile_all_validation_errors.json - "jsonschema==4.23.0", + "jsonschema>=4.23", "jscc==0.2.4", "pytz", "ijson", diff --git a/tests/test_stat_count_addresses_0_4.py b/tests/test_stat_count_addresses_0_4.py new file mode 100644 index 0000000..5dbdb64 --- /dev/null +++ b/tests/test_stat_count_addresses_0_4.py @@ -0,0 +1,29 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_stat_count_addresses_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "sample_300_statements.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + + assert results["statistics"]["count_addresses"] == 100 + assert results["statistics"]["count_addresses_with_postcode"] == 100 + assert results["statistics"]["count_addresses_with_country"] == 100 + assert ( + results["statistics"]["count_addresses_with_postcode_duplicated_in_address"] + == 0 + ) diff --git a/tests/test_stat_count_pep_0_4.py b/tests/test_stat_count_pep_0_4.py new file mode 100644 index 0000000..d27cd91 --- /dev/null +++ b/tests/test_stat_count_pep_0_4.py @@ -0,0 +1,30 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_sample_mode_valid_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "valid-schema", + "person_politicalExposure_object.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + + assert results["statistics"]["count_person_statements_have_pep_status"] == 1 + assert ( + results["statistics"]["count_person_statements_have_pep_status_statuses"][ + "isPep" + ] + == 1 + ) diff --git a/tests/test_stat_count_relationship_direct_or_indirect_0_4.py b/tests/test_stat_count_relationship_direct_or_indirect_0_4.py new file mode 100644 index 0000000..6059f4b --- /dev/null +++ b/tests/test_stat_count_relationship_direct_or_indirect_0_4.py @@ -0,0 +1,40 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_stat_count_relationship_direct_or_indirect_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "basic_1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + + assert ( + results["statistics"][ + "count_ownership_or_control_statement_interest_direct_or_indirect" + ]["direct"] + == 1 + ) + assert ( + results["statistics"][ + "count_ownership_or_control_statement_interest_direct_or_indirect" + ]["indirect"] + == 0 + ) + assert ( + results["statistics"][ + "count_ownership_or_control_statement_interest_direct_or_indirect" + ]["unknown"] + == 0 + ) diff --git a/tests/test_stat_count_relationship_interests_0_4.py b/tests/test_stat_count_relationship_interests_0_4.py new file mode 100644 index 0000000..fc7e6eb --- /dev/null +++ b/tests/test_stat_count_relationship_interests_0_4.py @@ -0,0 +1,28 @@ +import os +import tempfile + +from tests.api import bods_json_output + + +def test_stat_count_relationship_interests_1(): + + cove_temp_folder = tempfile.mkdtemp( + prefix="lib-cove-bods-tests-", dir=tempfile.gettempdir() + ) + json_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "0.4", + "basic_1.json", + ) + + results = bods_json_output(cove_temp_folder, json_filename) + + assert results["schema_version"] == "0.4" + + assert ( + results["statistics"][ + "count_ownership_or_control_statement_with_at_least_one_interest_beneficial" + ] + == 1 + ) From 3e10288209fc3346e3717de01659571a6c10b938 Mon Sep 17 00:00:00 2001 From: "Ed (ODSC)" Date: Thu, 19 Dec 2024 16:25:09 +0000 Subject: [PATCH 3/4] Minor updates to setup.py and CHANGELOG.md --- CHANGELOG.md | 2 ++ setup.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5307915..03bd81b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Update to handle new jsonschema version (Draft202012Validator) - Adapt infrastructure to handle BODS 0.4 (structure, statement types etc.) +- Default config value for bods_additional_checks_person_birthdate_min_year + has been increase from 1 to 1800 ### Added diff --git a/setup.py b/setup.py index 264f974..c28dee9 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ "libcove2>=0.2.1", "packaging", "jsonschema>=4.23", - "jscc==0.2.4", + "jscc>=0.2.4", "pytz", "ijson", # Required for jsonschema to validate URIs From f41a59ec2354939c2c553424f12a0677692d6f50 Mon Sep 17 00:00:00 2001 From: "Ed (ODSC)" Date: Tue, 7 Jan 2025 08:28:13 +0000 Subject: [PATCH 4/4] libcovebods/tasks: Add modules --- libcovebods/tasks/checks/__init__.py | 0 libcovebods/tasks/statistics/__init__.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 libcovebods/tasks/checks/__init__.py create mode 100644 libcovebods/tasks/statistics/__init__.py diff --git a/libcovebods/tasks/checks/__init__.py b/libcovebods/tasks/checks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/libcovebods/tasks/statistics/__init__.py b/libcovebods/tasks/statistics/__init__.py new file mode 100644 index 0000000..e69de29