Hello all,
I am trying to get the uc_products module to work with a decimal value at the product prices, instead of a point. this to local usage of the decimal seperator. the 3 main functions to alter are:
/**
* Implementation of hook_validate().
*
* Ensure that prices, weight, dimensions, and quantity are positive numbers.
*/
function uc_product_validate($node) {
$pattern = '/^\d*(\'.drupal_get_variable('uc_currency_dec','.').'\d*)?$/';
$price_error = t('Price must be in a valid number format. No commas and only one decimal point.');
if (!empty($node->list_price) && !is_numeric($node->list_price) && !preg_match($pattern, $node->list_price)) {
form_set_error('list_price', $price_error);
}
if (!empty($node->cost) && !is_numeric($node->cost) && !preg_match($pattern, $node->cost)) {
form_set_error('cost', $price_error);
}
if (!is_numeric($node->sell_price) && !preg_match($pattern, $node->sell_price)) {
form_set_error('sell_price', $price_error);
}
foreach (array('weight', 'length', 'width', 'height') as $property) {
if (!empty($node->$property) && (!is_numeric($node->$property) || $node->$property < 0)) {
form_set_error($property, t('@property must be a positive number. No commas and only one decimal point.', array('@property' => ucfirst($property))));
}
}
if ($node->default_qty) {
if (!is_numeric($node->default_qty)) {
form_set_error('default_qty', t('Quantities should be numeric.'));
}
elseif ($node->default_qty < 0) {
form_set_error('default_qty', t("Adding negative items to the cart doesn't make sense, so don't make it easy."));
}
}
}
/**
* Implementation of hook_insert().
*/
function uc_product_insert($node) {
if (!isset($node->unique_hash)) {
$node->unique_hash = md5($node->vid . $node->nid . $node->model . $node->list_price . $node->cost . $node->sell_price . $node->weight . $node->weight_units . $node->dim_length . $node->dim_width . $node->dim_height . $node->length_units . $node->pkg_qty . $node->default_qty . $node->shippable . time());
}
db_query("INSERT INTO {uc_products} (vid, nid, model, list_price, cost, sell_price, weight, weight_units, length, width, height, length_units, pkg_qty, default_qty, unique_hash, ordering, shippable) VALUES (%d, %d, '%s', %f, %f, %f, %f, '%s', %f, %f, %f, '%s', %d, %d, '%s', %d, %d)",
$node->vid, $node->nid, $node->model, $node->list_price, $node->cost, $node->sell_price, $node->weight, $node->weight_units, $node->dim_length, $node->dim_width, $node->dim_height, $node->length_units, $node->pkg_qty, $node->default_qty, $node->unique_hash, $node->ordering, $node->shippable
);
}
/**
* Implementation of hook_update().
*/
function uc_product_update($node) {
if ($node->revision) {
db_query("INSERT INTO {uc_products} (vid, nid, model, list_price, cost, sell_price, weight, weight_units, length, width, height, length_units, pkg_qty, default_qty, unique_hash, ordering, shippable) VALUES (%d, %d, '%s', %f, %f, %f, %f, '%s', %f, %f, %f, '%s', %d, %d, '%s', %d, %d)",
$node->vid, $node->nid, $node->model, $node->list_price, $node->cost, $node->sell_price, $node->weight, $node->weight_units, $node->dim_length, $node->dim_width, $node->dim_height, $node->length_units, $node->pkg_qty, $node->default_qty, $node->unique_hash, $node->ordering, $node->shippable
);
}
else {
//drupal_set_message('<pre>'. print_r($node, TRUE) .'</pre>');drupal_set_message('<pre>'. print_r($node, TRUE) .'</pre>');
db_query("UPDATE {uc_products} SET model = '%s', list_price = %f, cost = %f, sell_price = %f, weight = %f, weight_units = '%s', length = %f, width = %f, height = %f, length_units = '%s', pkg_qty = %d, default_qty = %d, ordering = %d, shippable = %d WHERE vid = %d",
$node->model, $node->list_price, $node->cost, $node->sell_price, $node->weight, $node->weight_units, $node->dim_length, $node->dim_width, $node->dim_height, $node->length_units, $node->pkg_qty, $node->default_qty, $node->ordering, $node->shippable, $node->vid);
}
}
to the following:
/**
* Implementation of hook_validate().
*
* Ensure that prices, weight, dimensions, and quantity are positive numbers.
*/
function uc_product_validate($node) {
$pattern = '/^\d*(\'.drupal_get_variable('uc_currency_dec','.').'\d*)?$/'; /*Altered to add the variable for the decimal seperator as found in admin/store/settings/store/edit/format */
$price_error = t('Price must be in a valid number format. No commas and only one decimal point.');
if (!empty($node->list_price) && !is_numeric($node->list_price) && !preg_match($pattern, $node->list_price)) {
form_set_error('list_price', $price_error);
}
if (!empty($node->cost) && !is_numeric($node->cost) && !preg_match($pattern, $node->cost)) {
form_set_error('cost', $price_error);
}
if (!is_numeric($node->sell_price) && !preg_match($pattern, $node->sell_price)) {
form_set_error('sell_price', $price_error);
}
foreach (array('weight', 'length', 'width', 'height') as $property) {
if (!empty($node->$property) && (!is_numeric($node->$property) || $node->$property < 0)) {
form_set_error($property, t('@property must be a positive number. No commas and only one decimal point.', array('@property' => ucfirst($property))));
}
}
if ($node->default_qty) {
if (!is_numeric($node->default_qty)) {
form_set_error('default_qty', t('Quantities should be numeric.'));
}
elseif ($node->default_qty < 0) {
form_set_error('default_qty', t("Adding negative items to the cart doesn't make sense, so don't make it easy."));
}
}
}
/**
* Implementation of hook_insert().
*/
function uc_product_insert($node) {
$node->cost = str_replace(',', '.', $node->cost); /*Added by KoffieSchaap*/
$node->list_price = str_replace(',', '.', $node->list_price); /*Added by KoffieSchaap*/
$node->sell_price str_replace(',', '.', $node->sell_price); /*Added by KoffieSchaap*/
if (!isset($node->unique_hash)) {
$node->unique_hash = md5($node->vid . $node->nid . $node->model . $node->list_price . $node->cost . $node->sell_price . $node->weight . $node->weight_units . $node->dim_length . $node->dim_width . $node->dim_height . $node->length_units . $node->pkg_qty . $node->default_qty . $node->shippable . time());
}
db_query("INSERT INTO {uc_products} (vid, nid, model, list_price, cost, sell_price, weight, weight_units, length, width, height, length_units, pkg_qty, default_qty, unique_hash, ordering, shippable) VALUES (%d, %d, '%s', %f, %f, %f, %f, '%s', %f, %f, %f, '%s', %d, %d, '%s', %d, %d)",
$node->vid, $node->nid, $node->model, $node->list_price, $node->cost, $node->sell_price, $node->weight, $node->weight_units, $node->dim_length, $node->dim_width, $node->dim_height, $node->length_units, $node->pkg_qty, $node->default_qty, $node->unique_hash, $node->ordering, $node->shippable
);
}
/**
* Implementation of hook_update().
*/
function uc_product_update($node) {
$node->cost = str_replace(',', '.', $node->cost); /*Added by KoffieSchaap*/
$node->list_price = str_replace(',', '.', $node->list_price); /*Added by KoffieSchaap*/
$node->sell_price str_replace(',', '.', $node->sell_price); /*Added by KoffieSchaap*/
if ($node->revision) {
db_query("INSERT INTO {uc_products} (vid, nid, model, list_price, cost, sell_price, weight, weight_units, length, width, height, length_units, pkg_qty, default_qty, unique_hash, ordering, shippable) VALUES (%d, %d, '%s', %f, %f, %f, %f, '%s', %f, %f, %f, '%s', %d, %d, '%s', %d, %d)",
$node->vid, $node->nid, $node->model, $node->list_price, $node->cost, $node->sell_price, $node->weight, $node->weight_units, $node->dim_length, $node->dim_width, $node->dim_height, $node->length_units, $node->pkg_qty, $node->default_qty, $node->unique_hash, $node->ordering, $node->shippable
);
}
else {
//drupal_set_message('<pre>'. print_r($node, TRUE) .'</pre>');drupal_set_message('<pre>'. print_r($node, TRUE) .'</pre>');
db_query("UPDATE {uc_products} SET model = '%s', list_price = %f, cost = %f, sell_price = %f, weight = %f, weight_units = '%s', length = %f, width = %f, height = %f, length_units = '%s', pkg_qty = %d, default_qty = %d, ordering = %d, shippable = %d WHERE vid = %d",
$node->model, $node->list_price, $node->cost, $node->sell_price, $node->weight, $node->weight_units, $node->dim_length, $node->dim_width, $node->dim_height, $node->length_units, $node->pkg_qty, $node->default_qty, $node->ordering, $node->shippable, $node->vid);
}
}
ofcourse, this also needs to be done to reading the values into the form, which could be done by altering the "uc_store_format_price_field_value" function in uc_store.module to change the point to a comma there.
function uc_store_format_price_field_value($price) {
$exact = rtrim(number_format($price, 6, '.', ''), '0');
$round = number_format($price, variable_get('uc_currency_prec', 2), '.', '');
if ($exact == rtrim($round, '0')) {
return $round;
}
else {
return $exact;
}
}
to
function uc_store_format_price_field_value($price) {
$exact = rtrim(number_format($price, 6, '.', ''), '0');
$round = str_replace('.', ',', number_format($price, variable_get('uc_currency_prec', 2), '.', ''));
if ($exact == rtrim($round, '0')) {
return $round;
}
else {
return $exact;
}
}
is there any potential to implement this?
Comments
Comment #1
koffieschaap commentedsmall typing error:
$pattern = '/^\d*(\'.drupal_get_variable('uc_currency_dec','.').'d*)?$/'; should be $pattern = '/^\d*(\\'.drupal_get_variable('uc_currency_dec','.').'d*)?$/';
Comment #2
longwaveCan you post your changes as a .patch file instead? This will make it easier to review and comment on.
Comment #3
longwaveSee also #1091000: uc_store_format_price_field_value() does not respect decimal marker
Comment #4
koffieschaap commentedofcourse, uc_Store_format_price_field_value could be changed to:
$exact = rtrim(number_format($price, 6, variable_get('uc_currency_dec','.'), ''), '0');
$round = number_format($price, variable_get('uc_currency_prec', 2), variable_get('uc_currency_dec','.'), '');
Comment #5
koffieschaap commentedim horrible with creating patch files, but i will try
Comment #6
koffieschaap commentedpatchfile attached
Comment #7
koffieschaap commented#1091000: uc_store_format_price_field_value() does not respect decimal marker is also needed for this, but i think a patchfile is created there. so i did not include that code in my patch.
Comment #8
koffieschaap commentedComment #10
longwaveTesting failed because the patch is buggy:
Also, shouldn't that str_replace() be using uc_currency_dec instead of hard coding a comma?
Comment #11
koffieschaap commentedas far as i know, the database values are a float value. this means we need to use the point there. if people enter the value with a point decimal seperator all is ok, but if they use a comma seperator it needs to be altered to a point.
ofcourse, if there is a better way to convert the decimal to a float than str_replace thats ok, but this works for me.
this means we do not need the uc_currence_dec variable in there, its about database storage.
sorry for the error in the patch, here is a corrected one
Comment #13
longwaveYour code supports using comma as the decimal separator, but what if someone configures something other than dot or comma as the separator? That should be supported as well...
Comment #14
koffieschaap commentednot right now, but i do not think there are any other ways for seperating the decimals besides comma and point.
i was watching the testresults and i kinda dont get why it didnt pass the test, can anyone clarify?
Comment #15
koffieschaap commentedi must be as blind as a bat, i was using drupal_get_variable instead of variable_get
i also added a line to modify for any other seperators as noted in #13, and changed the lines with drupal_get_variable
Comment #17
longwaveYou missed one:
You should probably test these patches yourself before uploading ;)
Comment #18
koffieschaap commentedComment #20
longwaveI think the remaining failures are due to the fact UC 2.x requires token, but testbot does not handle dependencies properly.
Comment #21
longwaveAttached patch fixes a couple of issues with the above regarding coding style and use of preg_quote() to escape the decimal marker, and incorporates #1091000: uc_store_format_price_field_value() does not respect decimal marker to initially format prices in the same way.
This however does not address other price fields, namely order editing and attribute price adjustments, which should be treated the same way, so marking as needs work. I think perhaps we should introduce a new 'uc_price' Form API element which can handle formatting and conversion for us.
Comment #22
tr commentedNow that we have a uc_price Form API element, maybe this can be reworked for D7.
Comment #23
tr commented