diff --git a/ukgrantmaking/migrations/0142_auto_20260312_1713.py b/ukgrantmaking/migrations/0142_auto_20260312_1713.py new file mode 100644 index 0000000..4065ba9 --- /dev/null +++ b/ukgrantmaking/migrations/0142_auto_20260312_1713.py @@ -0,0 +1,27 @@ +# Generated by Django 5.2.8 on 2026-03-12 17:13 + +import django_db_views.migration_functions +import django_db_views.operations +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("ukgrantmaking", "0141_auto_20260309_1119"), + ] + + operations = [ + django_db_views.operations.ViewRunPython( + code=django_db_views.migration_functions.ForwardViewMigration( + "SELECT\n -- grant details\n g.grant_id, \n g.title, \n g.description, \n g.currency, \n g.amount_awarded, \n g.\"amount_awarded_GBP\" AS amount_awarded_gbp, \n g.award_date, \n g.regrant_type,\n\n -- duration details\n g.planned_dates_duration, \n g.\"planned_dates_startDate\" AS planned_dates_start_date, \n g.\"planned_dates_endDate\" AS planned_dates_end_date, \n g.inclusion,\n\n -- *** Duration Band ***\n CASE\n WHEN g.planned_dates_duration IS NULL OR g.planned_dates_duration = 0 THEN 'Unknown/0'\n WHEN g.planned_dates_duration > 0 AND g.planned_dates_duration <= 6 THEN 'Up to 6 months'\n WHEN g.planned_dates_duration > 6 AND g.planned_dates_duration <= 12 THEN '7-12 months'\n WHEN g.planned_dates_duration > 12 AND g.planned_dates_duration <= 35 THEN '13-35 months'\n WHEN g.planned_dates_duration >= 36 THEN '3+ years'\n ELSE 'Other'\n END AS duration_band,\n\n -- *** Grant Amount Band ***\n CASE\n WHEN g.\"amount_awarded_GBP\" IS NULL OR g.\"amount_awarded_GBP\" = 0 THEN 'Zero/unknown'\n WHEN g.\"amount_awarded_GBP\" > 0 AND g.\"amount_awarded_GBP\" < 1000 THEN 'Under £1k'\n WHEN g.\"amount_awarded_GBP\" >= 1000 AND g.\"amount_awarded_GBP\" < 10000 THEN '£1k - £10k'\n WHEN g.\"amount_awarded_GBP\" >= 10000 AND g.\"amount_awarded_GBP\" < 100000 THEN '£10k - £100k'\n WHEN g.\"amount_awarded_GBP\" >= 100000 AND g.\"amount_awarded_GBP\" <= 1000000 THEN '£100k - £1m'\n WHEN g.\"amount_awarded_GBP\" > 1000000 THEN 'Over £1m'\n ELSE 'Other'\n END AS grant_amount_band,\n\n -- recipient details (from grant table)\n g.recipient_id, \n g.recipient_organisation_id, \n g.recipient_organisation_name, \n g.recipient_type, -- g.recipient_type (original grant field)\n CASE \n WHEN g.recipient_type IN ('Charity', 'Overseas Charity') THEN 'Charity' \n WHEN g.recipient_type IN ('Local Authority', 'NHS') THEN 'Government' \n WHEN g.recipient_type = 'Individual' THEN 'Individual' \n WHEN g.recipient_type IN ('Community Interest Company', 'Mutual', 'Non-profit Company', 'Sports Club', 'Religious Organisation') THEN 'Other non-profit' \n WHEN g.recipient_type = 'Private Company' THEN 'Private Company' WHEN recipient_type IN ('Education', 'University') THEN 'University/Education' \n WHEN g.recipient_type IN ('Organisation', 'Unknown') THEN 'Unknown' \n ELSE 'Unknown' \n\t END AS recipient_type_grouped,\n\n -- recipient regulator details (from recipient table 'r')\n r.name AS regulator_name, \n r.type AS regulator_type, \n r.date_of_registration AS regulator_date_of_registration, \n r.scale AS regulator_scale, \n r.how AS regulator_how, \n r.who AS regulator_who, \n r.what AS regulator_what, \n r.london_aoo AS regulator_london_aoo, \n r.london_hq AS regulator_london_hq, \n r.ctry_hq_name AS regulator_ctry_hq_name, \n r.rgn_hq_name AS regulator_rgn_hq_name,\n r.la_hq_name AS regulator_la_hq_name,\n r.ctry_aoo_name AS regulator_ctry_aoo_name, \n r.rgn_aoo_name AS regulator_rgn_aoo_name,\n r.la_aoo_name AS regulator_la_aoo_name,\n\n -- recipient year regulator data - financials\n y.financial_year_end, \n y.income, \n y.spending, \n y.employees,\n\n -- *** Income Band (organisation size) ***\n CASE\n WHEN y.income IS NULL THEN 'Unknown'\n WHEN y.income < 10000 THEN 'Under £10k'\n WHEN y.income >= 10000 AND y.income <= 100000 THEN '£10k to £100k'\n WHEN y.income > 100000 AND y.income <= 1000000 THEN '£100k to £1m'\n WHEN y.income > 1000000 AND y.income <= 10000000 THEN '£1m to £10m'\n WHEN y.income > 10000000 THEN 'Over £10m'\n ELSE 'Other'\n END AS income_band,\n\n -- funder details\n g.funding_organisation_id, \n g.funding_organisation_name, \n g.funding_organisation_department,\n g.funder_id, \n g.funding_organisation_type, \n f.segment AS funder_segment, \n f.category AS funder_category,\n CASE \n WHEN f.category = 'Trusts and Foundations' THEN f.segment \n ELSE f.category \n END AS funder_type_grouped, \n f.name AS funder_name,\n f.la_hq_name AS funder_la_hq_name,\n f.rgn_hq_name AS funder_rgn_hq_name,\n f.ctry_hq_name AS funder_ctry_hq_name,\n f.la_aoo_name AS funder_la_aoo_name,\n f.rgn_aoo_name AS funder_rgn_aoo_name,\n f.ctry_aoo_name AS funder_ctry_aoo_name\n\n\n FROM ukgrantmaking_grant g\n LEFT JOIN ukgrantmaking_grantrecipient r\n ON g.recipient_id = r.recipient_id\n LEFT JOIN ukgrantmaking_grantrecipientyear y\n ON g.recipient_id = y.recipient_id\n AND g.financial_year_id = y.financial_year_id\n LEFT JOIN ukgrantmaking_funder f\n ON g.funder_id = f.org_id\n JOIN ukgrantmaking_financialyear ukgfy\n ON g.financial_year_id = ukgfy.fy\n WHERE ukgfy.current = TRUE", + "ukgrantmaking_grants_analysis_view", + engine="django.db.backends.postgresql", + ), + reverse_code=django_db_views.migration_functions.BackwardViewMigration( + "SELECT\n -- grant details\n g.grant_id, \n g.title, \n g.description, \n g.currency, \n g.amount_awarded, \n g.\"amount_awarded_GBP\" AS amount_awarded_gbp, \n g.award_date, \n g.regrant_type,\n\n -- duration details\n g.planned_dates_duration, \n g.\"planned_dates_startDate\" AS planned_dates_start_date, \n g.\"planned_dates_endDate\" AS planned_dates_end_date, \n g.inclusion,\n\n -- *** Duration Band ***\n CASE\n WHEN g.planned_dates_duration IS NULL OR g.planned_dates_duration = 0 THEN 'Unknown/0'\n WHEN g.planned_dates_duration > 0 AND g.planned_dates_duration <= 6 THEN 'Up to 6 months'\n WHEN g.planned_dates_duration > 6 AND g.planned_dates_duration <= 12 THEN '7-12 months'\n WHEN g.planned_dates_duration > 12 AND g.planned_dates_duration <= 35 THEN '13-35 months'\n WHEN g.planned_dates_duration >= 36 THEN '3+ years'\n ELSE 'Other'\n END AS duration_band,\n\n -- *** Grant Amount Band ***\n CASE\n WHEN g.\"amount_awarded_GBP\" IS NULL OR g.\"amount_awarded_GBP\" = 0 THEN 'Zero/unknown'\n WHEN g.\"amount_awarded_GBP\" > 0 AND g.\"amount_awarded_GBP\" < 1000 THEN 'Under £1k'\n WHEN g.\"amount_awarded_GBP\" >= 1000 AND g.\"amount_awarded_GBP\" < 10000 THEN '£1k - £10k'\n WHEN g.\"amount_awarded_GBP\" >= 10000 AND g.\"amount_awarded_GBP\" < 100000 THEN '£10k - £100k'\n WHEN g.\"amount_awarded_GBP\" >= 100000 AND g.\"amount_awarded_GBP\" <= 1000000 THEN '£100k - £1m'\n WHEN g.\"amount_awarded_GBP\" > 1000000 THEN 'Over £1m'\n ELSE 'Other'\n END AS grant_amount_band,\n\n -- recipient details (from grant table)\n g.recipient_id, \n g.recipient_organisation_id, \n g.recipient_organisation_name, \n g.recipient_type, -- g.recipient_type (original grant field)\n\n -- recipient regulator details (from recipient table 'r')\n r.name AS regulator_name, \n r.type AS regulator_type, \n r.date_of_registration AS regulator_date_of_registration, \n r.scale AS regulator_scale, \n r.how AS regulator_how, \n r.who AS regulator_who, \n r.what AS regulator_what, \n r.london_aoo AS regulator_london_aoo, \n r.london_hq AS regulator_london_hq, \n r.ctry_hq_name AS regulator_ctry_hq_name, \n r.rgn_hq_name AS regulator_rgn_hq_name,\n r.la_hq_name AS regulator_la_hq_name,\n r.ctry_aoo_name AS regulator_ctry_aoo_name, \n r.rgn_aoo_name AS regulator_rgn_aoo_name,\n r.la_aoo_name AS regulator_la_aoo_name,\n\n -- recipient year regulator data - financials\n y.financial_year_end, \n y.income, \n y.spending, \n y.employees,\n\n -- *** Income Band (organisation size) ***\n CASE\n WHEN y.income IS NULL THEN 'Unknown'\n WHEN y.income < 10000 THEN 'Under £10k'\n WHEN y.income >= 10000 AND y.income <= 100000 THEN '£10k to £100k'\n WHEN y.income > 100000 AND y.income <= 1000000 THEN '£100k to £1m'\n WHEN y.income > 1000000 AND y.income <= 10000000 THEN '£1m to £10m'\n WHEN y.income > 10000000 THEN 'Over £10m'\n ELSE 'Other'\n END AS income_band,\n\n -- funder details\n g.funding_organisation_id, \n g.funding_organisation_name, \n g.funding_organisation_department,\n g.funder_id, \n g.funding_organisation_type, \n f.segment AS funder_segment, \n f.category AS funder_category, \n f.name AS funder_name,\n f.la_hq_name AS funder_la_hq_name,\n f.rgn_hq_name AS funder_rgn_hq_name,\n f.ctry_hq_name AS funder_ctry_hq_name,\n f.la_aoo_name AS funder_la_aoo_name,\n f.rgn_aoo_name AS funder_rgn_aoo_name,\n f.ctry_aoo_name AS funder_ctry_aoo_name\n\n\n FROM ukgrantmaking_grant g\n LEFT JOIN ukgrantmaking_grantrecipient r\n ON g.recipient_id = r.recipient_id\n LEFT JOIN ukgrantmaking_grantrecipientyear y\n ON g.recipient_id = y.recipient_id\n AND g.financial_year_id = y.financial_year_id\n LEFT JOIN ukgrantmaking_funder f\n ON g.funder_id = f.org_id\n JOIN ukgrantmaking_financialyear ukgfy\n ON g.financial_year_id = ukgfy.fy\n WHERE ukgfy.current = TRUE", + "ukgrantmaking_grants_analysis_view", + engine="django.db.backends.postgresql", + ), + atomic=False, + ), + ] diff --git a/ukgrantmaking/models/views/grants_analysis.py b/ukgrantmaking/models/views/grants_analysis.py index 8518dc8..616c6eb 100644 --- a/ukgrantmaking/models/views/grants_analysis.py +++ b/ukgrantmaking/models/views/grants_analysis.py @@ -56,6 +56,12 @@ class GrantsAnalysisView(DBView): recipient_type = models.CharField( max_length=50, verbose_name="Recipient Type", null=True ) + recipient_type_grouped = models.CharField( + max_length=50, + verbose_name="Recipient Type Grouped", + db_column="recipient_type_grouped", + null=True, + ) regulator_name = models.CharField( max_length=255, verbose_name="Regulator Name", db_column="regulator_name" ) @@ -176,6 +182,11 @@ class GrantsAnalysisView(DBView): funder_category = models.CharField( max_length=50, db_column="category", verbose_name="Funder Category" ) + funder_type_grouped = models.CharField( + max_length=50, + db_column="funder_type_grouped", + verbose_name="Funder type grouped", + ) funder_name = models.CharField( max_length=255, db_column="funder_name", verbose_name="Funder Name" ) @@ -246,6 +257,15 @@ class GrantsAnalysisView(DBView): g.recipient_organisation_id, g.recipient_organisation_name, g.recipient_type, -- g.recipient_type (original grant field) + CASE + WHEN g.recipient_type IN ('Charity', 'Overseas Charity') THEN 'Charity' + WHEN g.recipient_type IN ('Local Authority', 'NHS') THEN 'Government' + WHEN g.recipient_type = 'Individual' THEN 'Individual' + WHEN g.recipient_type IN ('Community Interest Company', 'Mutual', 'Non-profit Company', 'Sports Club', 'Religious Organisation') THEN 'Other non-profit' + WHEN g.recipient_type = 'Private Company' THEN 'Private Company' WHEN recipient_type IN ('Education', 'University') THEN 'University/Education' + WHEN g.recipient_type IN ('Organisation', 'Unknown') THEN 'Unknown' + ELSE 'Unknown' + END AS recipient_type_grouped, -- recipient regulator details (from recipient table 'r') r.name AS regulator_name, @@ -288,7 +308,11 @@ class GrantsAnalysisView(DBView): g.funder_id, g.funding_organisation_type, f.segment AS funder_segment, - f.category AS funder_category, + f.category AS funder_category, + CASE + WHEN f.category = 'Trusts and Foundations' THEN f.segment + ELSE f.category + END AS funder_type_grouped, f.name AS funder_name, f.la_hq_name AS funder_la_hq_name, f.rgn_hq_name AS funder_rgn_hq_name,