def to_python(self, value):

        try:
            if isinstance(value, dict):
                mi = MoneyInterval.from_dict(value)
            elif isinstance(value, MoneyInterval):
                mi = value
            else:
                mi = MoneyInterval("per_month", pennies=value)
            return mi
        except (TypeError, ValueError):
            raise exceptions.ValidationError(self.error_messages["invalid"],
                                             code="invalid",
                                             params={"value": value})
    def test_patch_with_partial_finances(self):
        """
        PATCH should change only given finances fields whilst keeping the others.
        """
        # setting existing values that should NOT change after the patch
        existing_your_finances_values = {
            'savings':{
                'bank_balance': 0,
                'investment_balance': 0,
                'asset_balance': 0,
                'credit_balance': 0,
            },
            'income':{
                'earnings': MoneyInterval('per_month', pennies=2200),
                'self_employment_drawings': MoneyInterval('per_month', pennies=2201),
                'child_benefits': MoneyInterval('per_month', pennies=2202),
                'benefits': MoneyInterval('per_month', pennies=2203),
                'tax_credits': MoneyInterval('per_month', pennies=2204),
                'maintenance_received': MoneyInterval('per_month', pennies=2205),
                'pension': MoneyInterval('per_month', pennies=2206),
                'other_income': MoneyInterval('per_month', pennies=0),
                'self_employed': False,
            },

        }

        self.resource.you.income = Income(id=self.resource.you.income.id, **existing_your_finances_values['income'])
        self.resource.you.income.save()

        self.resource.you.savings = Savings(id=self.resource.you.savings.id, **existing_your_finances_values['savings'])
        self.resource.you.savings.save()

        # new values that should change after the patch
        data={
            'you': {
                'deductions': {
                    "income_tax": mi_dict_generator(600),
                    "national_insurance": mi_dict_generator(100),
                    "maintenance": mi_dict_generator(710),
                    "childcare": mi_dict_generator(715),
                    "mortgage": mi_dict_generator(620),
                    "rent": mi_dict_generator(100),
                    "criminal_legalaid_contributions": 730
                }
            }
        }
        response = self.client.patch(
            self.detail_url, data, format='json',
            HTTP_AUTHORIZATION=self.get_http_authorization()
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        # only given finances props should have changed
        expected_your_finances_values = {'you': copy.deepcopy(existing_your_finances_values)}
        expected_your_finances_values['you'].update(data['you'])
        self.resource.you = Person.from_dict(expected_your_finances_values['you'])

        self.assertEligibilityCheckEqual(response.data, self.resource)
    def contribute_to_class(self, cls, name):
        # first, create the hidden fields. It is *crucial* that these
        # fields appears *before* the actual 'value' field (i.e. self) in
        # the models _meta.fields - to achieve this, we need to change it's
        # creation_counter class variable.
        interval_period_field = MoneyIntervalAutoCharField(
            max_length=50,
            choices=MoneyInterval.get_intervals_for_widget(),
            editable=False,
            null=True,
            blank=True)
        # setting the counter to the same value as the date field itself will
        # ensure the precision field appear first - it is added first after all,
        # and when the date field is added later, it won't be sorted before it.
        interval_period_field.creation_counter = self.creation_counter
        cls.add_to_class(_interval_period_field_name(name),
                         interval_period_field)

        per_interval_value_field = MoneyIntervalAutoBigIntegerField(
            editable=False, null=True, blank=True)
        # setting the counter to the same value as the date field itself will
        # ensure the precision field appear first - it is added first after all,
        # and when the date field is added later, it won't be sorted before it.
        per_interval_value_field.creation_counter = self.creation_counter
        cls.add_to_class(_per_interval_value_field_name(name),
                         per_interval_value_field)

        # add the date field as normal
        super(MoneyIntervalField, self).contribute_to_class(cls, name)

        # as we are not using SubfieldBase (see intro), we need to do it's job
        # ourselves. we don't need to be generic, so don't use a metaclass, but
        # just assign the descriptor object here.
        setattr(cls, self.name, MoneyIntervalFieldCreator(self))
Esempio n. 4
0
    def contribute_to_class(self, cls, name):
        # first, create the hidden fields. It is *crucial* that these
        # fields appears *before* the actual 'value' field (i.e. self) in
        # the models _meta.fields - to achieve this, we need to change it's
        # creation_counter class variable.
        interval_period_field = MoneyIntervalAutoCharField(max_length=50,
            choices=MoneyInterval.get_intervals_for_widget(), editable=False,
            null=True, blank=True)
        # setting the counter to the same value as the date field itself will
        # ensure the precision field appear first - it is added first after all,
        # and when the date field is added later, it won't be sorted before it.
        interval_period_field.creation_counter = self.creation_counter
        cls.add_to_class(_interval_period_field_name(name), interval_period_field)

        per_interval_value_field = MoneyIntervalAutoBigIntegerField(editable=False,
                                                          null=True, blank=True)
        # setting the counter to the same value as the date field itself will
        # ensure the precision field appear first - it is added first after all,
        # and when the date field is added later, it won't be sorted before it.
        per_interval_value_field.creation_counter = self.creation_counter
        cls.add_to_class(_per_interval_value_field_name(name), per_interval_value_field)


        # add the date field as normal
        super(MoneyIntervalField, self).contribute_to_class(cls, name)

        # as we are not using SubfieldBase (see intro), we need to do it's job
        # ourselves. we don't need to be generic, so don't use a metaclass, but
        # just assign the descriptor object here.
        setattr(cls, self.name, MoneyIntervalFieldCreator(self))
Esempio n. 5
0
 def set_value(self, val, field):
     if val == "" and field.empty_strings_allowed and not field.null:
         val = ""
     elif val in field.empty_values:
         val = None
     elif isinstance(field, MoneyIntervalField):
         val = MoneyInterval.from_dict(json.loads(val))
     elif isinstance(field, JSONField):
         val = json.dumps(val)
     elif RE_DATE.match(val):
         val = datetime.strptime(val, "%Y-%m-%d").date()
     elif RE_DATETIME.match(val):
         val = parse_datetime(val)
     return val
 def set_value(self, val, field):
     if val == "" and field.empty_strings_allowed and not field.null:
         val = ""
     elif val in field.empty_values:
         val = None
     elif isinstance(field, MoneyIntervalField):
         val = MoneyInterval.from_dict(json.loads(val))
     elif isinstance(field, JSONField):
         val = json.dumps(val)
     elif RE_DATE.match(val):
         val = datetime.strptime(val, "%Y-%m-%d").date()
     elif RE_DATETIME.match(val):
         val = parse_datetime(val)
     return val
    def __get__(self, obj, type=None):
        if obj is None:
            raise AttributeError("Can only be accessed via an instance.")

        value = obj.__dict__[self.field.name]
        if value is None:
            return None
        elif isinstance(value, dict):
            try:
                mi = MoneyInterval.from_dict(value)
            except Exception:
                pass
            return mi
        elif isinstance(value, MoneyInterval):
            return value
        elif hasattr(obj, self.interval_period_field_name) and hasattr(
                obj, self.per_interval_value_field_name):
            mi = MoneyInterval(getattr(obj, self.interval_period_field_name),
                               pennies=getattr(
                                   obj, self.per_interval_value_field_name))
            return mi
        else:
            raise Exception(
                "probably needs to instantiate from something else")
Esempio n. 8
0
    def to_python(self, value):

        try:
            if isinstance(value, dict):
                mi = MoneyInterval.from_dict(value)
            elif isinstance(value, MoneyInterval):
                mi = value
            else:
                mi = MoneyInterval('per_month', pennies=value)
            return mi
        except (TypeError, ValueError):
            raise exceptions.ValidationError(
                self.error_messages['invalid'],
                code='invalid',
                params={'value': value},
            )
Esempio n. 9
0
    def __get__(self, obj, type=None):
        if obj is None:
            raise AttributeError('Can only be accessed via an instance.')

        value = obj.__dict__[self.field.name]
        if value is None: return None
        elif isinstance(value, dict):
            try:
                mi = MoneyInterval.from_dict(value)
            except:
                pass
            return mi
        elif isinstance(value, MoneyInterval):
            return value
        elif hasattr(obj, self.interval_period_field_name) and hasattr(obj, self.per_interval_value_field_name):
            mi = MoneyInterval(getattr(obj, self.interval_period_field_name),\
                               pennies=getattr(obj, self.per_interval_value_field_name))
            return mi
        else:
            raise Exception("probably needs to instantiate from something else")
def mi_as_monthly(data):
    if not data:
        return data

    mi = MoneyInterval.from_dict(data)
    return mi.as_monthly()
    Person,
    ThirdPartyDetails,
    AdaptationDetails,
    MatterType,
    MediaCode,
    MediaCodeGroup,
    CaseNotesHistory,
    EODDetails,
    EODDetailsCategory,
)

category = Recipe(Category, name=seq("Name"), code=seq("Code"), order=seq(0))

income = Recipe(
    Income,
    earnings=MoneyInterval("per_month", pennies=2200),
    self_employment_drawings=MoneyInterval("per_month", pennies=0),
    benefits=MoneyInterval("per_month", pennies=0),
    tax_credits=MoneyInterval("per_month", pennies=0),
    child_benefits=MoneyInterval("per_month", pennies=0),
    maintenance_received=MoneyInterval("per_month", pennies=0),
    pension=MoneyInterval("per_month", pennies=0),
    other_income=MoneyInterval("per_week", pennies=2200),
)
savings = Recipe(Savings)
deductions = Recipe(
    Deductions,
    income_tax=MoneyInterval("per_week", pennies=2200),
    national_insurance=MoneyInterval("per_4week", pennies=2200),
    maintenance=MoneyInterval("per_year", pennies=2200),
    childcare=MoneyInterval("per_week", pennies=2200),
Esempio n. 12
0
def mi_as_monthly(data):
    if not data:
        return data

    mi = MoneyInterval.from_dict(data)
    return mi.as_monthly()