On your demo site, I added a mug to the cart, and set the quantity to be 10000000000. Updating the cart resulted in this:
PDOException: SQLSTATE[22003]: Numeric value out of range: 1264 Out of range value adjusted for column 'commerce_total_amount' at row 1: INSERT INTO {field_data_commerce_total} (entity_type, entity_id, revision_id, bundle, delta, language, commerce_total_amount, commerce_total_currency_code, commerce_total_data) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8); Array ( [:db_insert_placeholder_0] => commerce_line_item [:db_insert_placeholder_1] => 136 [:db_insert_placeholder_2] => 136 [:db_insert_placeholder_3] => product [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => und [:db_insert_placeholder_6] => 10000000000 [:db_insert_placeholder_7] => USD [:db_insert_placeholder_8] => a:1:{s:10:"components";a:2:{i:0;a:3:{s:4:"name";s:10:"base_price";s:5:"price";a:3:{s:6:"amount";i:100000000;s:13:"currency_code";s:3:"USD";s:4:"data";a:1:{s:10:"components";a:0:{}}}s:8:"included";b:1;}i:1;a:3:{s:4:"name";s:13:"tax|sales_tax";s:5:"price";a:3:{s:6:"amount";d:8.0E+6;s:13:"currency_code";s:3:"USD";s:4:"data";a:1:{s:8:"tax_rate";a:11:{s:4:"name";s:9:"sales_tax";s:13:"display_title";s:14:"Sales tax (8%)";s:11:"description";s:0:"";s:4:"rate";s:3:".08";s:4:"type";s:9:"sales_tax";s:15:"rules_component";s:1:"1";s:15:"price_component";s:13:"tax|sales_tax";s:20:"calculation_callback";s:27:"commerce_tax_rate_calculate";s:6:"module";s:15:"commerce_tax_ui";s:5:"title";s:9:"Sales tax";s:10:"admin_list";b:1;}}}s:8:"included";b:0;}}} ) in field_sql_storage_field_storage_write() (line 425 of /srv/demo-commerceguys/www/dc/modules/field/modules/field_sql_storage/field_sql_storage.module).
Comments
Comment #1
pcambraPlease see #1035180: Setting quantity to a very high number induce errors
Comment #2
rszrama commentedOooh, interesting. The previous issue chose a maximum quantity of 99999999 that we figured would be sufficiently high, but perhaps we left it too high. The error here is actually that the amount is too high for that column. The variables we can address here are:
I guess we may as well just lower the quantity further, but that won't help if the product price is $10,000,000. : P
Comment #3
pcambraTagging
Comment #4
brst t commentedHow about fractional quantities?
For hourly service rates, 0.5 kg of peanut butter.. etc.
Or does the existing quantity method have to be completely disabled to accomplish this?
Comment #5
brst t commentedComment #6
rszrama commentedFractional quantities are currently supported to two decimal places in the database, but the form by default validates them to be integers. This is being mediated through a custom property of the quantity box's form element called #datatype. We initialize it to integer, but if you remove it or set it to something else, the integer validation won't happen. You could set it to decimal but you'd need to ensure that you don't accept fractional quantities to a greater precision than the database can handle.
Comment #7
brst t commentedSo the setting is either integer or decimal?
In setting as a decimal for 0.5 kg of peanut butter (mass, length etc.), there'd be risk of someone ordering 1.4 coconuts?
Comment #8
pcambraYou could only alter the quantity form field of the form for the types/categories you want.
Comment #9
brst t commentedDo you mean by altering the field type and widget at admin/commerce/config/line-items/product/fields ?
Quantity is hard-coded.
Comment #10
rszrama commentedYeah, the only recognized setting right now for #datatype is integer. If you change it to something else, you can check for it in a custom validate handler. So you could set it to a custom decimal string and then provide a validate handler for the quantity element that ensures it's a multiple of .5. You'd have to do this all custom through hook_form_alter(), though - there is no UI for this.
Comment #11
rszrama commentedI'm going to commit the change that has been live on the demo for a while but slightly improved. The cart form and order edit form now default the maxlength of the quantity field to 4 but will grow it if the current quantity is larger so quantities aren't hosed.
Comment #13
davidwhthomas commentedIt looks like there's still a bit of work to do on this one as setting quantity can cause a PDO exception / fatal error.
Steps to reproduce.
1. Set quantity to 4 digits in cart, update order
2. Set quantity to new maxlength ( 7? ) , update order
3. Set quantity to new maxlength ( 10? ), update order
4. Fatal error
Looks like it needs some additional validation to ensure the final quantity isn't outside the range that can be stored in the database field.
DT
Comment #14
davidwhthomas commentedJust a temporary form_alter workaround I use for this, in case useful, another way would be to add a custom validate hook.
This snippet lets you choose a global maxlength for quantity and enforces it on the cart form.
cheers,
DT
P.S Awesome module set by the way, really nicely done and taking shape well.
Comment #15
rszrama commentedGood thoughts on a solution for this, but ultimately if someone is altering a form, they're responsible for the consequences. For example, you could alter away the SKU textfield on the product form and break things just as badly. I raised the idea in another issue on deleting default fields breaking Views that maybe we need a documentation place where we can say "alter this at your own risk" and outline why. That would be a good enough solution from my standpoint.
Comment #16
davidwhthomas commentedThanks rszrama, though a final validation to make sure the 10 digit quantity doesn't break the db field constraint at some point would be good, I'm ok with altering the form for now.
cheers,
DT