+
+
+
+
+ {{ department }}
+
+ {{ name }}
+
+
+
+ Entity information:
+ {{ intro }}
+
+
+ PFMA Schedule:
+ {{ public_entity.pfma }}
+
+
+ Total expenditure ({{ selected_financial_year }}):
+ R{{ public_entity.amount|intcomma }}
+
+
+ Total expenditure as % of {{ department }}:
+ {{ percentage_of_total_department_amount|stringformat:".2f%%" }}
+
+
+
+ Total expenditure as % of all entities:
+
+ {{ percentage_of_total_amount|stringformat:".2f%%" }}
+
+
+
+
+ {{ department }} expenditure:
+
+
+ {{ department }}
+
+ R{{ total_department_amount|intcomma }}
+
+
+
+
{{ name }}
-
-
- {{ department_location }} Public Entity Budget for {{ selected_financial_year }}
-
- {% if website_url %}
-
- {{ website_url }}
-
- {% endif %}
- {% include 'components/department-budgets/IntroSection/index.html' with description=intro datasets=treasury_datasets location=department_location %}
-
-
- The Budget Cycle
-
-
-
- {% include 'components/department-budgets/ArrowButtons/index.html' with link_1="#section-plan" link_2="#section-implement" link_3="#section-review" %}
-
-
-
-
- Plan
-
-
-
-
- {{ selected_financial_year }} Budget
-
- The {{ source_type_revenue }} ({{ source_type_revenue_short }}) is a book published along with the
- tabling of the budget for the new financial year.
-
-
- {% assign "View the "|add:source_type_revenue_short|add:" chapter for "|add:chapter_name|add:" (PDF)" as text1 %}
- {% assign "View tables in the "|add:source_type_revenue_short|add:" chapter (Excel)" as text2 %}
-
- {% if pdf_link or excel_link %}
-
- {% include 'components/LinksList/item.html' with text=text1 url=pdf_link type="download" %}
-
- {% include 'components/LinksList/item.html' with text=text2 url=excel_link type="download" %}
-
- {% endif %}
-
-
-
- {% include 'scenes/department/ProgrammesSection/index.html' with source_type=source_type year=selected_financial_year pdf=pdf excel=excel guide=guide %}
+
-
-
- {% include 'scenes/department/EconClassPackedCircles/econ-class-packed-circles.html' with source_type=source_type year=selected_financial_year pdf=pdf excel=excel guide=guide %}
-
-
-
- {% include 'scenes/department/ProgramEconSmallMultiples/programme-econ-small-muls.html' with source_type=source_type year=selected_financial_year pdf=pdf excel=excel guide=guide %}
-
-
- {{ selected_financial_year }} Adjusted Budget
-
- The {{ source_type_adjusted }} ({{ source_type_adjusted_short }}) is a book published along with the
- tabling of the adjusted budget.
-
-
- {% assign "View the "|add:source_type_adjusted_short|add:" chapter for "|add:chapter_name|add:" (PDF)." as text1 %}
- {% assign "View tables in the "|add:source_type_adjusted_short|add:" chapter (Excel)." as text2 %}
-
- {% if pdf_link_adjusted or excel_link_adjusted %}
-
- {% include 'components/LinksList/item.html' with text=text1 url=pdf_link_adjusted type="download" %}
- {% include 'components/LinksList/item.html' with text=text2 url=excel_link_adjusted type="download" %}
-
- {% else %}
-
- {% if excel_link_adjusted %}
-
-
- {% include 'components/Icon/index.html' with type="info" %}
-
- Please note
-
-
- The {{ source_type_adjusted_short }} chapter
- for {{ chapter_name }} (PDF) is not available yet
-
-
- {% elif pdf_link_adjusted %}
-
-
- {% include 'components/Icon/index.html' with type="info" %}
-
- Please note
-
-
- The tables in {{ source_type_revenue_short }}
- chapter (Excel) is not available yet
-
-
- {% else %}
- {% assign "The "|add:source_type_revenue_short|add:" chapter for "|add:chapter_name|add:" (PDF) is not available yet" as info2 %}
- {% assign "The tables in "|add:source_type_revenue_short|add:" chapter (Excel)" as info3 %}
-
-
-
- {% include 'components/Icon/index.html' with type="info" %}
-
- Please note
-
-
- The adjusted budget documents are not
- available yet on vulekamali.gov.za
-
-
- {% endif %}
- {% endif %}
-
-
- {% if government.slug == 'south-africa' %}
-
- {% include 'scenes/department/AdjustedSection/index.html' with type="adjusted" items=adjusted_budget_summary source_type=source_type source_type_adjusted=source_type_adjusted year=selected_financial_year pdf=pdf excel=excel pdf_adjusted=pdf_link_adjusted excel_adjusted=excel_link_adjusted csv=adjusted_budget_summary.department_data_csv dataset=adjusted_budget_summary.dataset_detail_page parliament=parliament title="Programme budgets" subtitle=subtitle description="Activities of this department" %}
-
- {% endif %}
-
- {% if procurement_resource_links %}
-
- {% include 'scenes/department/ResourceLinks/resource-links.html' with resource_links=procurement_resource_links section_title="Procurement resources" more_link="/datasets/procurement-portals-and-resources" %}
-
- {% endif %}
-
-
-
- Implement
-
-
-
- {% if infra_enabled %}
-
- Department infrastructure projects
-
- Largest infrastructure projects by this department.
-
-
-
-
- Project name
- Status
- Estimated completion date
-
- {% for project in projects %}
-
-
-
- {{ project.name }}
-
-
- {{ project.status|default:"Not available" }}
- {{ project.estimated_completion_date|default:"Not available" }}
-
- {% empty %}
-
- No projects available for this department.
-
- {% endfor %}
-
-
-
-
-
-
- {% endif %}
-
- {% if in_year_monitoring_resource_links %}
-
- {% include 'scenes/department/ResourceLinks/resource-links.html' with resource_links=in_year_monitoring_resource_links section_title="In-year monitoring resources" %}
-
- {% endif %}
-
- {% if performance_resource_links %}
-
- {% include 'scenes/department/ResourceLinks/resource-links.html' with resource_links=performance_resource_links section_title="Performance monitoring resources" %}
-
- {% endif %}
-
- {% if eqprs_data_enabled %}
-
- {% endif %}
-
- {% if not infra_enabled and not in_year_monitoring_resource_links and not performance_resource_links %}
-
-
- {% include 'components/Icon/index.html' with type="info" size="l" %}
-
- Please note
-
-
- Implementation data coming soon.
-
- {% endif %}
-
-
-
- Review
-
-
-
- {% if expenditure_over_time %}
-
- {% include 'scenes/department/ExpenditureSection/index.html' with items=expenditure_over_time.expenditure cpi=global_values.cpi_dataset_url source_type=source_type year=selected_financial_year dataset=expenditure_over_time.dataset_detail_page pdf=pdf_link excel=excel csv=expenditure_over_time.department_data_csv guide=guide color="purple" title="Planned compared to historical expenditure" subtitle=subtitle description="Expenditure changes over time" %}
-
- {% endif %}
-
- {% with ""|add:department_location|add:" "|add:name|add:" Department" as text %}
-
- {% if budget_actual %}
-
- {% include 'scenes/department/ExpenditurePhaseSection/index.html' with items=budget_actual.expenditure cpi=global_values.cpi_dataset_url source_type="Expenditure Time Series" year=selected_financial_year dataset=budget_actual.dataset_detail_page csv=budget_actual.department_data_csv color="purple" description="Budgeted and Actual Expenditure comparison" subtitle=review_subtitle notices=budget_actual.notices website_url=website_url %}
-
- {% endif %}
-
- {% if budget_actual_programmes %}
-
- {% include 'scenes/department/ExpenditureMultiplesSection/index.html' with items=budget_actual_programmes.programmes cpi=global_values.cpi_dataset_url source_type="Expenditure Time Series" year=selected_financial_year dataset=budget_actual_programmes.dataset_detail_page csv=budget_actual_programmes.department_data_csv color="purple" subtitle=review_subtitle description="Budgeted and Actual Expenditure comparison by Programme" notices=budget_actual_programmes.notices %}
-
- {% endif %}
- {% endwith %}
-
-
-
-
+
-
+
+
+
+
+ Detailed financial information:
+
+
+
+
+ Consol indi
+ Classification 1
+ Classification 2
+ Classification 3
+ Classification 4
+ Classification 5
+ Classification 6
+ Budget phase
+ Amount
+
+
+
+ {% for expenditure in public_entity_expenditure %}
+
+ {{ expenditure.consol_indi }}
+ {{ expenditure.economic_classification1|truncatechars:40 }}
+ {{ expenditure.economic_classification2|truncatechars:40 }}
+ {{ expenditure.economic_classification3|truncatechars:40 }}
+ {{ expenditure.economic_classification4|truncatechars:40 }}
+ {{ expenditure.economic_classification5|truncatechars:40 }}
+ {{ expenditure.economic_classification6|truncatechars:40 }}
+ {{ expenditure.budget_phase|truncatechars:40 }}
+ {{ expenditure.amount|intcomma }}
+
+ {% endfor %}
+
+
+
{% endblock %}
diff --git a/budgetportal/views.py b/budgetportal/views.py
index f772a3b3d..f12216e23 100644
--- a/budgetportal/views.py
+++ b/budgetportal/views.py
@@ -1,3 +1,4 @@
+import simplejson
import json
import logging
from csv import DictWriter
@@ -39,7 +40,7 @@
Video,
ShowcaseItem,
)
-from .models.government import PublicEntity
+from .models.government import PublicEntity, PublicEntityExpenditure
from .summaries import (
InYearSpending,
DepartmentProgrammesEcon4,
@@ -509,7 +510,9 @@ def department_page(
context["public_entities"] = []
- for public_entity in PublicEntity.objects.filter(department__slug=department_slug, government=department.government):
+ for public_entity in PublicEntity.objects.filter(
+ department__slug=department_slug, government=department.government
+ ):
context["public_entities"].append(
{
"name": public_entity.name,
@@ -523,62 +526,79 @@ def department_page(
def public_entity_page(
request, financial_year_id, sphere_slug, government_slug, public_entity_slug
):
- raise()
- public_entity = None
+ # Get public entity by public_entity_slug
+ selected_public_entity = PublicEntity.objects.filter(
+ slug=public_entity_slug
+ ).first()
selected_year = get_object_or_404(FinancialYear, slug=financial_year_id)
- years = FinancialYear.get_available_years()
- for year in years:
- if year.slug == financial_year_id:
- selected_year = year
- sphere = selected_year.spheres.filter(slug=sphere_slug).first()
- government = sphere.governments.filter(slug=government_slug).first()
- public_entity = government.public_entities.filter(
- slug=public_entity_slug
- ).first()
-
- financial_years_context = []
- for year in years:
- closest_match, closest_is_exact = year.get_closest_match(public_entity)
- financial_years_context.append(
- {
- "id": year.slug,
- "is_selected": year.slug == financial_year_id,
- "closest_match": {
- "url_path": closest_match.get_url_path(),
- "is_exact_match": closest_is_exact,
- },
- }
+ # Total up public entityies amount
+ total_amount = 0
+ for government in (
+ selected_year.spheres.filter(slug="national").first().governments.all()
+ ):
+ for public_entity in government.public_entities.all():
+ total_amount += public_entity.amount
+
+ # Total up public entities in same department
+ total_department_amount = 0
+ department_public_entities = []
+ chart_data = []
+ for department_public_entity in PublicEntity.objects.filter(
+ department=selected_public_entity.department
+ ):
+ total_department_amount += department_public_entity.amount
+ department_public_entities.append(department_public_entity)
+ # if department_public_entity is selected_public_entity then color_group = 2 else 1
+ colour_group = 2 if department_public_entity == selected_public_entity else 1
+ chart_data.append(
+ [
+ colour_group,
+ simplejson.dumps(department_public_entity.amount, use_decimal=True),
+ department_public_entity.name,
+ simplejson.dumps(department_public_entity.id),
+ department_public_entity.slug,
+ ]
)
- govt_label = "National"
+ # Get public entity expenditure
+ public_entity_expenditure = PublicEntityExpenditure.objects.filter(
+ public_entity=selected_public_entity
+ )
+
+ # Public entity amount percentage of total department amount
+ percentage_of_total_department_amount = (
+ selected_public_entity.amount / total_department_amount
+ ) * 100
+
+ # Public entity amount percentage of total amount
+ percentage_of_total_amount = (selected_public_entity.amount / total_amount) * 100
context = {
- "comments_enabled": settings.COMMENTS_ENABLED,
- "financial_years": financial_years_context,
- "government": {
- "name": public_entity.government.name,
- "label": govt_label,
- "slug": str(public_entity.government.slug),
- },
- "intro": public_entity.intro,
- "name": public_entity.name,
- "slug": str(public_entity.slug),
- "sphere": {
- "name": public_entity.government.sphere.name,
- "slug": public_entity.government.sphere.slug,
- },
+ "public_entity_id": selected_public_entity.id,
+ "intro": selected_public_entity.intro,
+ "name": selected_public_entity.name,
+ "department": selected_public_entity.department.name,
+ "department_slug": selected_public_entity.department.slug,
+ "slug": str(selected_public_entity.slug),
"selected_financial_year": financial_year_id,
"selected_tab": "public_entities",
- "title": "%s budget %s - vulekamali"
- % (public_entity.name, selected_year.slug),
- "description": "%s public entity: %s budget data for the %s financial year %s"
+ "title": "%s expenditure %s - vulekamali"
+ % (selected_public_entity.name, selected_year.slug),
+ "description": "%s public entity: Expenditure data for the %s financial year %s"
% (
- govt_label,
- public_entity.name,
+ selected_public_entity.name,
selected_year.slug,
COMMON_DESCRIPTION_ENDING,
),
+ "public_entity": selected_public_entity,
+ "total_amount": total_amount,
+ "total_department_amount": total_department_amount,
+ "percentage_of_total_amount": percentage_of_total_amount,
+ "percentage_of_total_department_amount": percentage_of_total_department_amount,
+ "department_public_entities": department_public_entities,
+ "chart_data": chart_data,
+ "public_entity_expenditure": public_entity_expenditure,
}
context["navbar"] = MainMenuItem.objects.prefetch_related("children").all()
context["latest_year"] = FinancialYear.get_latest_year().slug
@@ -586,7 +606,7 @@ def public_entity_page(
str(settings.ROOT_DIR.path("_data/global_values.yaml"))
)
context["admin_url"] = reverse(
- "admin:budgetportal_department_change", args=(public_entity.pk,)
+ "admin:budgetportal_department_change", args=(selected_public_entity.pk,)
)
return render(request, "public_entity.html", context)
@@ -1157,7 +1177,7 @@ def department_list(request, financial_year_id):
def latest_public_entity_list(request):
- department = request.GET.get('department', None)
+ department = request.GET.get("department", None)
url = reverse("public-entity-list", args=(FinancialYear.get_latest_year().slug,))
url = f"{url}?department={department}" if department else url
return redirect(url, permanent=False)
diff --git a/import_plublic_entities_expenditure.py b/import_plublic_entities_expenditure.py
new file mode 100644
index 000000000..10ac82437
--- /dev/null
+++ b/import_plublic_entities_expenditure.py
@@ -0,0 +1,186 @@
+import csv
+from budgetportal.models import (
+ FinancialYear,
+ Sphere,
+ Government,
+ Department,
+)
+
+from budgetportal.models.government import PublicEntity, PublicEntityExpenditure
+
+
+def make_financial_year(year):
+ # Check if the input is a valid year
+ try:
+ year = int(year)
+ except ValueError:
+ return "Invalid year format"
+
+ financial_year_str = f"{year - 1}-{str(year)[2:]}"
+
+ return financial_year_str
+
+
+# Open the CSV file
+with open("ENT_ENE_CashFlow_202324 - Data.csv", newline="") as csvfile:
+ # Create a DictReader object with named columns
+ csvreader = csv.DictReader(csvfile)
+
+ foundGovernments = []
+ notFoundFinancialYears = []
+ notFoundGovernments = []
+ notFoundDepartments = []
+ notFoundSpheres = []
+ alreadyFoundDepartments = []
+ notFoundPublicEntities = []
+
+ count = 0
+ # Loop through each row in the CSV file
+ for row in csvreader:
+ if count >= 100000:
+ break
+
+ # Increment the counter
+ count += 1
+ # Access each column by its name
+ vote = row["Vote"]
+ department = row["Department"]
+ entity_name = row["EntityName"]
+ consol_indi = row["ConsolIndi"]
+ pfma = row["PFMA"]
+ type_ = row["Type"]
+ economic_classification1 = row["EconomicClassification1"]
+ economic_classification2 = row["EconomicClassification2"]
+ economic_classification3 = row["EconomicClassification3"]
+ economic_classification4 = row["EconomicClassification4"]
+ economic_classification5 = row["EconomicClassification5"]
+ economic_classification6 = row["EconomicClassification6"]
+ function_group1 = row["FunctionGroup1"]
+ function_group2 = row["FunctionGroup2"]
+ financial_year = row["FinancialYear"]
+ budget_phase = row["BudgetPhase"]
+ amount_r_thou = row["Amount (R-Thou)"]
+ amount = row["Amount"]
+
+ financial_year_slug = make_financial_year(financial_year)
+ financialYears = FinancialYear.objects.filter(slug=financial_year_slug)
+
+ if financialYears:
+ selectedFinancialYear = financialYears.first()
+ spheres = Sphere.objects.filter(
+ slug="national", financial_year=selectedFinancialYear
+ )
+
+ if spheres:
+ selectedSphere = spheres.first()
+ governments = Government.objects.filter(sphere=selectedSphere)
+
+ if governments:
+ selectedGovernment = governments.first()
+ foundGovernments.append(selectedGovernment)
+
+ departments = Department.objects.filter(
+ name=department, government=selectedGovernment
+ )
+ selectedDepartment = None
+
+ if departments:
+ selectedDepartment = departments.first()
+ else:
+ notFoundDepartments.append(
+ f"Department {department} for financial year {financial_year_slug} does not exist"
+ )
+ try:
+ selectedDepartment = Department.objects.create(
+ name=department,
+ government=selectedGovernment,
+ vote_number=vote,
+ )
+ except:
+ alreadyFoundDepartments.append(
+ f"Department {department} for financial year {financial_year_slug} already exists"
+ )
+ if selectedDepartment:
+ publicEntities = PublicEntity.objects.filter(
+ name=entity_name,
+ department=selectedDepartment,
+ government=selectedGovernment,
+ pfma=pfma,
+ functiongroup1=function_group1,
+ )
+ selectedPublicEntity = None
+
+ if publicEntities:
+ selectedPublicEntity = publicEntities.first()
+ else:
+ selectedPublicEntity = PublicEntity.objects.create(
+ name=entity_name,
+ department=selectedDepartment,
+ government=selectedGovernment,
+ pfma=pfma,
+ functiongroup1=function_group1,
+ )
+
+ if selectedPublicEntity:
+ selectedPublicEntityExpenditure = (
+ PublicEntityExpenditure.objects.create(
+ public_entity=selectedPublicEntity,
+ amount=amount,
+ budget_phase=budget_phase,
+ expenditure_type=type_,
+ economic_classification1=economic_classification1,
+ economic_classification2=economic_classification2,
+ economic_classification3=economic_classification3,
+ economic_classification4=economic_classification4,
+ economic_classification5=economic_classification5,
+ economic_classification6=economic_classification6,
+ consol_indi=consol_indi,
+ )
+ )
+
+ else:
+ notFoundPublicEntities.append(
+ f"Public entity {entity_name} for department {department} for financial year {financial_year_slug} does not exist/not created"
+ )
+
+ else:
+ notFoundGovernments.append(
+ f"Government for financial year {financial_year_slug} does not exist"
+ )
+ else:
+ notFoundSpheres.append(
+ f"National sphere for financial year {financial_year_slug} does not exist"
+ )
+ else:
+ notFoundFinancialYears.append(
+ f"Financial year {financial_year_slug} does not exist"
+ )
+
+ print("-------------------------------------")
+ print(foundGovernments)
+ print("-------------------------------------")
+ print(notFoundFinancialYears)
+ print("-------------------------------------")
+ print(notFoundSpheres)
+ print("-------------------------------------")
+ print(notFoundGovernments)
+ print("-------------------------------------")
+ print(notFoundDepartments)
+ print("-------------------------------------")
+ print(alreadyFoundDepartments)
+ print("-------------------------------------")
+ print(notFoundPublicEntities)
+
+
+# Add up publicExpenditure for each publicEntity
+for publicEntity in PublicEntity.objects.all():
+ totalExpenditure = 0
+ for publicEntityExpenditure in PublicEntityExpenditure.objects.filter(
+ public_entity=publicEntity
+ ):
+ totalExpenditure += publicEntityExpenditure.amount
+ publicEntity.amount = totalExpenditure
+ publicEntity.save()
+ print(
+ f"Public entity {publicEntity.name} has total expenditure of {publicEntity.amount}"
+ )
+ {{ department }} +
+{{ name }}
+Entity information:
+{{ intro }}
+PFMA Schedule: | +{{ public_entity.pfma }} | +
Total expenditure ({{ selected_financial_year }}): | +R{{ public_entity.amount|intcomma }} | +
Total expenditure as % of {{ department }}: | +{{ percentage_of_total_department_amount|stringformat:".2f%%" }} | +
+ Total expenditure as % of all entities: + | +{{ percentage_of_total_amount|stringformat:".2f%%" }} | +
{{ department }} expenditure:
+
+ {{ department }}
+
+ R{{ total_department_amount|intcomma }}
+
+ {{ name }} - - - {{ department_location }} Public Entity Budget for {{ selected_financial_year }} - - {% if website_url %} - - {{ website_url }} - - {% endif %} - {% include 'components/department-budgets/IntroSection/index.html' with description=intro datasets=treasury_datasets location=department_location %} - -
{{ selected_financial_year }} Budget
-- The {{ source_type_revenue }} ({{ source_type_revenue_short }}) is a book published along with the - tabling of the budget for the new financial year. -
- - {% assign "View the "|add:source_type_revenue_short|add:" chapter for "|add:chapter_name|add:" (PDF)" as text1 %} - {% assign "View tables in the "|add:source_type_revenue_short|add:" chapter (Excel)" as text2 %} - - {% if pdf_link or excel_link %} --
- {% include 'components/LinksList/item.html' with text=text1 url=pdf_link type="download" %}
-
- {% include 'components/LinksList/item.html' with text=text2 url=excel_link type="download" %}
-
{{ selected_financial_year }} Adjusted Budget
-- The {{ source_type_adjusted }} ({{ source_type_adjusted_short }}) is a book published along with the - tabling of the adjusted budget. -
- - {% assign "View the "|add:source_type_adjusted_short|add:" chapter for "|add:chapter_name|add:" (PDF)." as text1 %} - {% assign "View tables in the "|add:source_type_adjusted_short|add:" chapter (Excel)." as text2 %} - - {% if pdf_link_adjusted or excel_link_adjusted %} --
- {% include 'components/LinksList/item.html' with text=text1 url=pdf_link_adjusted type="download" %}
- {% include 'components/LinksList/item.html' with text=text2 url=excel_link_adjusted type="download" %}
-
Department infrastructure projects
- -Largest infrastructure projects by this department.
- -Project name | -Status | -Estimated completion date | -|
---|---|---|---|
- - {{ project.name }} - - | -{{ project.status|default:"Not available" }} | -{{ project.estimated_completion_date|default:"Not available" }} | -|
No projects available for this department. | -
Detailed financial information:
+Consol indi | +Classification 1 | +Classification 2 | +Classification 3 | +Classification 4 | +Classification 5 | +Classification 6 | +Budget phase | +Amount | +
---|---|---|---|---|---|---|---|---|
{{ expenditure.consol_indi }} | +{{ expenditure.economic_classification1|truncatechars:40 }} | +{{ expenditure.economic_classification2|truncatechars:40 }} | +{{ expenditure.economic_classification3|truncatechars:40 }} | +{{ expenditure.economic_classification4|truncatechars:40 }} | +{{ expenditure.economic_classification5|truncatechars:40 }} | +{{ expenditure.economic_classification6|truncatechars:40 }} | +{{ expenditure.budget_phase|truncatechars:40 }} | +{{ expenditure.amount|intcomma }} | +