Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the property logic to use payload #110

Merged
merged 8 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 68 additions & 60 deletions app/means_test/api.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
from app.api import cla_backend
from flask import session
from app.means_test.forms.income import IncomeForm
from app.means_test.forms.property import PropertiesPayload
from app.means_test.forms.benefits import BenefitsForm, AdditionalBenefitsForm
from app.means_test.forms.property import MultiplePropertiesForm
from app.means_test.money_interval import MoneyInterval
from tests.unit_tests.means_test.payload.test_cases import EligibilityData
from app.means_test.data import BenefitsData, AdditionalBenefitData


def deep_update(original, updates):
"""
Recursively updates a nested dictionary with values from another dictionary.
Only updates keys present in the `updates` dictionary.
"""
for key, value in updates.items():
if (
isinstance(value, dict)
and key in original
and isinstance(original[key], dict)
):
deep_update(original[key], value) # Recursive call for nested dict
else:
original[key] = value


def update_means_test(payload):
Expand Down Expand Up @@ -48,14 +32,6 @@ def is_eligible(reference):
def get_means_test_payload(eligibility_data: EligibilityData) -> dict:
about = eligibility_data.forms.get("about-you", {})

income_form = eligibility_data.forms.get("income", {})
property_form = eligibility_data.forms.get("property", {})
benefits = BenefitsData(**eligibility_data.forms.get("benefits", {})).to_payload()

additional_benefits = AdditionalBenefitData(
**eligibility_data.forms.get("additional-benefits", {})
).to_payload()

has_partner = eligibility_data.forms.get("about-you", {}).get(
"has_partner", False
) and not eligibility_data.forms.get("about-you", {}).get("in_dispute", False)
Expand All @@ -64,41 +40,50 @@ def get_means_test_payload(eligibility_data: EligibilityData) -> dict:
is_partner_employed = about.get("is_partner_employed", None)
is_partner_self_employed = about.get("is_partner_self_employed", None)

income_data: dict[str, dict] = IncomeForm(**income_form).get_payload(
benefits_data = BenefitsForm.get_payload(eligibility_data.forms.get("benefits", {}))
additional_benefits_data = AdditionalBenefitsForm.get_payload(
eligibility_data.forms.get("additional-benefits", {})
)
income_data = IncomeForm(**eligibility_data.forms.get("income", {})).get_payload(
employed=is_employed,
self_employed=is_self_employed,
partner_employed=is_partner_employed,
partner_self_employed=is_partner_self_employed,
)

you_income = income_data.get("you", {}).get("income", {})
you_income.update(
{
"benefits": additional_benefits["benefits"],
"child_benefits": benefits["child_benefits"],
}
)
partner_income = income_data.get("partner", {}).get("income", {})
partner_income.update(
{
"benefits": additional_benefits["benefits"],
"child_benefits": benefits["child_benefits"],
}
property_data = MultiplePropertiesForm.get_payload(
eligibility_data.forms.get("property", {})
)

# Remove rent field from property set and setup payload
if eligibility_data.forms.get("about-you", {}).get("own_property"):
property_payload = PropertiesPayload(property_form)
for property_item in property_payload.get("property_set", []):
property_item.pop("rent", None)
# Sums rent to the other income field for you
other_income = MoneyInterval(
property_data.get("you").get("income", {}).get("other_income", 0)
) + income_data.get("you").get("income", {}).get("other_income", 0)

payload = {
"category": eligibility_data.category,
"your_problem_notes": "",
"notes": "",
"property_set": [],
"property_set": property_data.get("property_set"),
"you": {
"income": you_income,
"income": {
"earnings": income_data.get("you", {})
.get("income", {})
.get("earnings"),
"self_employment_drawings": income_data.get("you", {})
.get("income", {})
.get("self_employment_drawings"),
"tax_credits": income_data.get("you", {})
.get("income", {})
.get("tax_credits"),
"maintenance_received": income_data.get("you", {})
.get("income", {})
.get("maintenance_received"),
"pension": income_data.get("you", {}).get("income", {}).get("pension"),
"other_income": other_income,
"self_employed": is_self_employed,
"benefits": additional_benefits_data.get("benefits"),
"child_benefits": benefits_data.get("child_benefits"),
},
"savings": {
"bank_balance": None,
"investment_balance": None,
Expand All @@ -121,10 +106,7 @@ def get_means_test_payload(eligibility_data: EligibilityData) -> dict:
"per_interval_value": None,
"interval_period": "per_month",
},
"mortgage": {
"per_interval_value": None,
"interval_period": "per_month",
},
"mortgage": property_data.get("deductions", {}).get("mortgage", {}),
"rent": {
"per_interval_value": None,
"interval_period": "per_month",
Expand All @@ -133,7 +115,37 @@ def get_means_test_payload(eligibility_data: EligibilityData) -> dict:
},
},
"partner": {
"income": partner_income,
"income": {
"earnings": income_data.get("partner", {})
.get("income", {})
.get("earnings"),
"self_employment_drawings": income_data.get("partner", {})
.get("income", {})
.get("self_employment_drawings"),
"tax_credits": income_data.get("partner", {})
.get("income", {})
.get("tax_credits"),
"maintenance_received": income_data.get("partner", {})
.get("income", {})
.get("maintenance_received"),
"pension": income_data.get("partner", {})
.get("income", {})
.get("pension"),
"other_income": income_data.get("partner", {})
.get("income", {})
.get("other_income"),
"self_employed": "0",
"benefits": {
"per_interval_value": 0,
"per_interval_value_pounds": None,
"interval_period": "per_month",
},
"child_benefits": {
"per_interval_value": 0,
"per_interval_value_pounds": None,
"interval_period": "per_month",
},
},
"savings": {
"bank_balance": None,
"investment_balance": None,
Expand Down Expand Up @@ -174,16 +186,12 @@ def get_means_test_payload(eligibility_data: EligibilityData) -> dict:
else 0,
"is_you_or_your_partner_over_60": about.get("aged_60_or_over", False),
"has_partner": has_partner,
"on_passported_benefits": benefits["on_passported_benefits"],
"on_nass_benefits": additional_benefits["on_nass_benefits"],
"specific_benefits": benefits["specific_benefits"],
"on_passported_benefits": benefits_data["on_passported_benefits"],
"on_nass_benefits": additional_benefits_data["on_nass_benefits"],
"specific_benefits": benefits_data["specific_benefits"],
"disregards": [],
}

# Add in the property payload
if eligibility_data.forms.get("about-you", {}).get("own_property"):
deep_update(payload, property_payload)

if not has_partner:
del payload["partner"]

Expand Down
68 changes: 0 additions & 68 deletions app/means_test/data.py

This file was deleted.

78 changes: 77 additions & 1 deletion app/means_test/forms/benefits.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,51 @@
ValidateIf,
ValidateIfType,
)
from app.means_test.data import BenefitsData
from app.means_test import YES, NO

from dataclasses import dataclass, field


@dataclass
class BenefitsData:
BENEFITS_CHOICES = [
("child_benefit", _("Child Benefit")),
("pension_credit", _("Guarantee Credit")),
("income_support", _("Income Support")),
("job_seekers_allowance", _("Income-based Jobseeker's Allowance")),
("employment_support", _("Income-related Employment and Support Allowance")),
("universal_credit", _("Universal Credit")),
("other-benefit", _("Any other benefits")),
]
benefits: list = field(default_factory=list)
child_benefits: dict = field(default_factory=dict)

@property
def passported_benefits(self):
others = ["child_benefit", "other-benefit"]
return [name for name, label in self.BENEFITS_CHOICES if name not in others]

@property
def specific_benefits(self):
return {
"pension_credit": "pension_credit" in self.benefits,
"job_seekers_allowance": "job_seekers_allowance" in self.benefits,
"employment_support": "employment_support" in self.benefits,
"universal_credit": "universal_credit" in self.benefits,
"income_support": "income_support" in self.benefits,
}

@property
def is_passported(self) -> bool:
return bool(set(self.benefits).intersection(self.passported_benefits))


@dataclass
class AdditionalBenefitData:
benefits: list = field(default_factory=list)
other_benefits: list = field(default_factory=list)
total_other_benefit: dict = field(default_factory=dict)


def get_benefits_choices():
choices = BenefitsData.BENEFITS_CHOICES.copy()
Expand Down Expand Up @@ -81,6 +123,27 @@ def data(self):
def should_show(cls) -> bool:
return session.get("eligibility").on_benefits

def get_payload(self) -> dict:
"""Returns the benefits payload for the user and the partner.
If a field can not be found the default of MoneyField(0) will be used.
"""
payload = {
"specific_benefits": {
"pension_credit": "pension_credit" in self.get("benefits", []),
"job_seekers_allowance": "job_seekers_allowance"
in self.get("benefits", []),
"employment_support": "employment_support" in self.get("benefits", []),
"universal_credit": "universal_credit" in self.get("benefits", []),
"income_support": "income_support" in self.get("benefits", []),
},
"on_passported_benefits": session.get(
"eligibility"
).has_passported_benefits,
"child_benefits": self.get("child_benefits", {}),
}

return payload


class AdditionalBenefitsForm(BaseMeansTestForm):
title = _("Your additional benefits")
Expand Down Expand Up @@ -164,3 +227,16 @@ def data(self):
def should_show(cls) -> bool:
data = session.get("eligibility").forms.get("benefits")
return data and "other-benefit" in data["benefits"]

def get_payload(
self,
) -> dict:
"""Returns the additional benefits payload for the user and the partner.
If a field can not be found the default of MoneyField(0) will be used.
"""
payload = {
"on_nass_benefits": False,
"benefits": self.get("total_other_benefit"),
}

return payload
4 changes: 1 addition & 3 deletions app/means_test/forms/income.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,7 @@ def get_payload(
self.data.get("maintenance_received", 0)
),
"pension": MoneyInterval(self.data.get("pension", 0)),
"other_income": MoneyInterval(
self.data.get("other_income", 0)
), # TODO: Add income from rent here
"other_income": MoneyInterval(self.data.get("other_income", 0)),
"self_employed": self_employed,
},
"deductions": {
Expand Down
11 changes: 11 additions & 0 deletions app/means_test/forms/property.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,14 @@ def should_show(cls) -> bool:
)

template = "means_test/property.html"

def get_payload(
self,
has_property: bool | None = False,
) -> dict:
"""Returns the property payload for the user and the partner.
If a field can not be found the default of MoneyField(0) will be used.
"""
payload = PropertiesPayload(self)

return payload
2 changes: 1 addition & 1 deletion app/means_test/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class MeansTest(View):
forms = {
"about-you": AboutYouForm,
"benefits": BenefitsForm,
"property": MultiplePropertiesForm,
"additional-benefits": AdditionalBenefitsForm,
"property": MultiplePropertiesForm,
"income": IncomeForm,
}

Expand Down
Empty file.
Loading
Loading