Repository navigation
Conversation
ramonski
force-pushed
the
fix/decimal-field-manager
branch
3 times, most recently
from
October 7, 2026 05:44
783cece to
3173cf6
Compare
A `zope.schema.Decimal` only accepts a `decimal.Decimal`, and JSON has no type for one. A price arrived as a string, a float or an integer and every one of them failed the field's own validation, so a Decimal field could not be written through the API at all. The new DecimalFieldManager coerces those three on set and serializes back to a string, which is the only JSON form that keeps the exact value. A value that is not a number is handed on untouched, so the field reports it rather than this adapter raising an error of its own. The manager also joins NORMALIZING_FIELD_MANAGERS. Without that the data manager prefers the content type's own set<Name> mutator, which stores the value exactly as it arrives: `setAnalysisProfilePrice` calls its mutator with the raw string, and the object then fails validation with "wrong type". This is the same reason UID references and durations are in that list. `analysis_profile_price` and `analysis_profile_vat` on AnalysisProfile are the only Decimal fields in the stack today, and neither setter does anything beyond calling its mutator, so nothing is lost by going through the field manager instead.
ramonski
force-pushed
the
fix/decimal-field-manager
branch
from
October 7, 2026 06:30
3173cf6 to
c7503b7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A
zope.schema.Decimalfield could not be written through the API at all. JSON has no type for adecimal.Decimal, and a string, a float and an integer all fail the field's own validation.Description of the issue/feature this PR addresses
analysis_profile_priceandanalysis_profile_vatonAnalysisProfileare the only Decimal fields in the stack today. Setting either of them returned{"analysis_profile_price": "wrong type"}, so a profile's package price could only be entered through the browser form.Current behavior before PR
Two things went wrong, and the second one hid behind the first.
The generic
ZopeSchemaFieldManagervalidates the raw JSON value, which a Decimal field refuses. But the value never got that far:DexterityDataManager.setprefers the content type's ownset<Name>mutator over the field manager, andsetAnalysisProfilePricepasses the value straight to its mutator:The raw string therefore landed in the field, and the object failed
api.validateafterwards withwrong type. Registering an adapter alone does not fix this, which is whyNORMALIZING_FIELD_MANAGERSexists.Desired behavior after PR is merged
DecimalFieldManagercoerces a string, an integer or a float toDecimalon set, and serializes back to a string, the only JSON form that keeps the exact value:A value that is not a number is handed on untouched, so the field reports it rather than this adapter raising an error of its own.
The manager also joins
NORMALIZING_FIELD_MANAGERS, alongside UID references and durations, so the data manager goes through it instead of the setter. Neither Decimal setter does anything beyond calling its mutator, so nothing is lost by that route.This is the same shape as #102 for Duration and #100 for UID references.
Verification
bin/test-senaite -s senaite.jsonapi: 38 tests, 0 failures, 0 errors.createdoctest gained the Decimal case: a price as a string and a VAT as a plain integer both arrive asDecimal, and the field manager reads the price back as'24.00'.AnalysisProfileover the API: before the change the request came back with{"analysis_profile_price": "wrong type"}. The end-to-end re-check on that instance is still outstanding, because the data manager change needs a restart to take effect.I confirm I have tested the PR thoroughly and coded it according to PEP8 standards.