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))
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))
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")
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 __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),