function uc_product_kit_update in Ubercart 6.2
Same name and namespace in other branches
- 5 uc_product_kit/uc_product_kit.module \uc_product_kit_update()
- 7.3 uc_product_kit/uc_product_kit.module \uc_product_kit_update()
Implements hook_update().
Updates information in {uc_products} as well as {uc_product_kits}. Because component products are known when the form is loaded, discount information can be input and saved.
Parameters
&$node: The node to be updated.
See also
File
- uc_product_kit/
uc_product_kit.module, line 193 - The product kit module for Ubercart.
Code
function uc_product_kit_update(&$node) {
$obj = new stdClass();
$obj->vid = $node->vid;
$obj->nid = $node->nid;
$obj->model = '';
$obj->list_price = 0;
$obj->cost = 0;
$obj->sell_price = 0;
$obj->weight = 0;
$obj->weight_units = variable_get('uc_weight_unit', 'lb');
$obj->default_qty = $node->default_qty;
$obj->ordering = $node->ordering;
$obj->shippable = FALSE;
if (!isset($node->kit_total) && isset($node->synchronized) && isset($node->sell_price)) {
$override_discounts = !$node->synchronized;
$node->kit_total = $node->sell_price;
}
else {
$override_discounts = isset($node->kit_total) && is_numeric($node->kit_total);
}
$product_count = count($node->products);
// Usually, $node is $form_state['values'] cast as an object.
// However, there could be times where node_save() is called with an
// actual product kit node. $node->products is an array of objects and
// $node->items doesn't exist then, so we create it.
foreach ($node->products as $nid) {
if (is_numeric($nid)) {
// For an actual form submission, ensure that the qty is numeric.
$product = node_load($nid, NULL, TRUE);
if (is_null($node->items[$nid]['qty']) || $node->items[$nid]['qty'] === '') {
$node->items[$nid]['qty'] = 1;
}
}
else {
// When $product is an object, populate the items array.
$product = $nid;
$nid = $product->nid;
$node->items[$nid] = (array) $product;
}
}
// Get the price of all the products without any discounts. This number is
// used if a total kit price was specified to calculate the individual
// product discounts.
if ($override_discounts) {
$base_price = 0;
foreach ($node->items as $nid => $item) {
$product = node_load($nid, NULL, TRUE);
$base_price += $product->sell_price * $item['qty'];
}
}
$values = array();
$placeholders = array();
foreach ($node->products as $nid) {
if (is_numeric($nid)) {
$product = node_load($nid);
}
else {
$product = $nid;
$nid = $product->nid;
}
$values[] = $node->vid;
$values[] = $node->nid;
$values[] = $nid;
$values[] = $node->mutable;
// When a total kit price is specified, calculate the individual product
// discounts needed to reach it, taking into account the product quantities
// and their relative prices. More expensive products should be given a
// proportionally higher discount.
if ($override_discounts) {
// After all the algebra that went into finding this formula, it's
// surprising how simple it is.
$discount = ($node->kit_total - $base_price) * $product->sell_price / $base_price;
}
else {
$discount = $node->items[$nid]['discount'];
}
if (is_null($node->items[$nid]['qty']) || $node->items[$nid]['qty'] === '') {
$node->items[$nid]['qty'] = 1;
}
$product->qty = $node->items[$nid]['qty'];
// Discounts are always saved, but they are only applied if the kit can't
// be changed by the customer.
if ($node->mutable != UC_PRODUCT_KIT_MUTABLE) {
$product->sell_price += $discount;
}
$values[] = $product->qty;
$values[] = $discount;
$values[] = $node->items[$nid]['ordering'];
$values[] = !$override_discounts;
$placeholders[] = '(%d, %d, %d, %d, %d, %f, %d, %d)';
$obj->model .= $product->model . ' / ';
$obj->list_price += $product->list_price * $product->qty;
$obj->cost += $product->cost * $product->qty;
$obj->sell_price += $product->sell_price * $product->qty;
$obj->weight += $product->weight * $product->qty * uc_weight_conversion($product->weight_units, $obj->weight_units);
if ($product->shippable) {
$obj->shippable = TRUE;
}
}
$obj->model = rtrim($obj->model, ' / ');
if ($node->mutable == UC_PRODUCT_KIT_MUTABLE && $discount) {
drupal_set_message(t('Product kit discounts are not applied because the customer can remove components from their cart.'));
}
// If we're not making a new revision, delete information for the current
// revision so we can overwrite it.
if (empty($node->revision)) {
db_query("DELETE FROM {uc_product_kits} WHERE vid = %d", $node->vid);
}
db_query("INSERT INTO {uc_product_kits} (vid, nid, product_id, mutable, qty, discount, ordering, synchronized) VALUES " . implode(',', $placeholders), $values);
if (!empty($node->revision)) {
db_query("INSERT INTO {uc_products} (vid, nid, model, list_price, cost, sell_price, weight, weight_units, default_qty, unique_hash, ordering, shippable) VALUES (%d, %d, '%s', %f, %f, %f, %f, '%s', %d, '%s', %d, %d)", $obj->vid, $obj->nid, $obj->model, $obj->list_price, $obj->cost, $obj->sell_price, $obj->weight, $obj->weight_units, $obj->default_qty, md5($obj->vid . $obj->nid . $obj->model . $obj->list_price . $obj->cost . $obj->sell_price . $obj->weight . $obj->weight_units . $obj->default_qty . $obj->ordering . time()), $obj->ordering, $obj->shippable);
}
else {
db_query("UPDATE {uc_products} SET model = '%s', list_price = %f, cost = %f, sell_price = %f, weight = %f, weight_units = '%s', default_qty = %d, ordering = %d, shippable = %d WHERE vid = %d", $obj->model, $obj->list_price, $obj->cost, $obj->sell_price, $obj->weight, $obj->weight_units, $obj->default_qty, $obj->ordering, $obj->shippable, $obj->vid);
if (!db_affected_rows()) {
@db_query("INSERT INTO {uc_products} (vid, nid, model, list_price, cost, sell_price, weight, weight_units, default_qty, unique_hash, ordering, shippable) VALUES (%d, %d, '%s', %f, %f, %f, %f, '%s', %d, '%s', %d, %d)", $obj->vid, $obj->nid, $obj->model, $obj->list_price, $obj->cost, $obj->sell_price, $obj->weight, $obj->weight_units, $obj->default_qty, md5($obj->vid . $obj->nid . $obj->model . $obj->list_price . $obj->cost . $obj->sell_price . $obj->weight . $obj->weight_units . $obj->default_qty . $obj->ordering . $obj->shippable . time()), $obj->ordering, $obj->shippable);
}
}
// When a kit is updated, remove matching kits from the cart, as there is no
// simple way to handle product addition or removal at this point.
if (module_exists('uc_cart')) {
db_query("DELETE FROM {uc_cart_products} WHERE data LIKE '%%s:6:\"kit_id\";s:%d:\"%s\";%%'", strlen($node->nid), $node->nid);
}
}