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

Need Decimal Property for accounting/costing/monetary applications #235

Open
divinedeveloper opened this issue Feb 6, 2017 · 8 comments
Labels
enhancement feature Describes a new feature

Comments

@divinedeveloper
Copy link

divinedeveloper commented Feb 6, 2017

Hi There, Thanks for an awesome library and very helpful to us.

I am using python 2.7.9, django 1.8.9, neomodel 2.0.2 and neo4j 2.2.9 to create a monetary application. I am using FloatProperty but facing the issues related to using floats. Cost doesn't tally.

I am not using any round, format or any other functions. Python advocates using decimals for such applications

As I saw currently new properties were added like Email, Normal and Regex, This one can be helpful too.

It would be very helpful, if you suggest any workaround/trick to do this in neomodel 2.0.2

Thanks

@robinedwards
Copy link
Collaborator

robinedwards commented Feb 6, 2017 via email

@robinedwards
Copy link
Collaborator

I think something like this should do the trick.

Unless you are wanting to limit the precision of the stored values?

class DecimalProperty(Property):
    """
    Stores a python decimal.Decimal value
    """
    form_field_class = 'FloatField'

    @validator
    def inflate(self, value):
        return decimal.Decimal(value)

    @validator
    def deflate(self, value):
        return decimal.Decimal(value)

    def default_value(self):
        return decimal.Decimal(super(DecimalProperty, self).default_value())

@divinedeveloper
Copy link
Author

divinedeveloper commented Feb 7, 2017

Hi, Thanks for quick response. We started this app with neo4j 3.0, but neomodel wasn't supporting it back then, so had to fall back to 2.x. As soon as we finish this sprint, we will upgrade as per your suggestion

Unless you are wanting to limit the precision of the stored values?- Yes, we do need to show cents/paise upto 2 precision only.

I will try this subclassing property trick and will let you know.

Thanks. Really Appreciated.
God bless

@robinedwards
Copy link
Collaborator

I actually wrote a refund system earlier in my career and made the mistake of representing the cent as decimals. The rounding caused all kinds of issues. I think you are better off storing the cent as a full integer then moving the decimal point. For example 5.01 would be stored as 501 and just formatted when displayed.

However if you do want to persist to a certain level of decimal places you just need to add a call to round() in the deflate method above and possible inflate for consistency. I think you will still need to call getcontext() to set the precision though.

@divinedeveloper
Copy link
Author

I tried subclassing property trick and it works, and found same issues as you did. Even round(decimal.Decimal(value),2) and decimal.Decimal(format(value, '7.2f')) are not able to limit decimals to 2 for our calculations.

We are thinking of using the full Integer technique to store costs.

Thanks for your guidance.

@aanastasiou
Copy link
Collaborator

@divinedeveloper Would a seperate "decimals" property still be of interest here?

In addition to @robinedwards suggestion, another thing that could be done purely on floats (and therefore even as simple as an extension of FloatProperty is:

rounded_decimal = round(a_number * pow(10,dec_to_keep)) / pow(10,dec_to_keep)

Where:

  • a_number The number you are trying to convert to "decimal"
  • dec_to_keep The number of decimal digits you wish to preserve (e.g. 3). Obviously the pow(10,dec_to_keep) part can be pre-calculated.

This produces:

dec_to_keep=3
a_number = 4.89765678
dec_to_keep == 4.898

All the best

@divinedeveloper
Copy link
Author

@aanastasiou I believe a decimal property would be helpful but for our scenario we made it work using full integers. Thanks

@aanastasiou
Copy link
Collaborator

@divinedeveloper Thanks for responding, sounds good, a DecimalProperty is not too difficult to provide based on our discussion ohere, so you might find one in an upcoming release. All the best.

@AntonLydike AntonLydike added the feature Describes a new feature label Sep 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement feature Describes a new feature
Projects
None yet
Development

No branches or pull requests

4 participants