I'm trying to define a default rule in a small module based on Commerce Price Table and Commerce Rules Extra. The rule is to set price based on the quantity of produtcs that contains a partial sku in the current order and the price table of the line item.
I'm new to Rules... and commerce. I'm not sure if I set the default rule correctly to get the current order or if the error is in the definition of the action (or if it's to late at night for me to see it!).
The error I got : Error: Missing configuration for parameter commerce_order.
Here is the current state of the code:
/**
* Based on Commerce Price Table and Commerce Rules Extra
*/
/**
* Implements hook_default_rules_configuration().
*/
function commerce_price_table_sku_contains_default_rules_configuration() {
$rules = array();
// Add a reaction rule to update a shopping cart order's status to "Shopping
// cart" when a product is added to or removed from the order.
$rule = rules_reaction_rule();
$rule->label = t('Override price with price table if sku contains');
$rule->active = TRUE;
$rule
->event('commerce_product_calculate_sell_price')
->condition('entity_has_field', array(
'entity:select' => 'commerce-line-item',
'field' => 'commerce_product',
))
->condition('entity_has_field', array(
'entity:select' => 'commerce-line-item:commerce-product',
'field' => 'field_price_table',
))
->action('commerce_price_table_sku_contains_set_price', array(
'site:current-cart-order' => 'commerce_order', // Wrong? Error: Missing configuration for parameter commerce_order.
'product_id' => '',
'commerce_line_item:select' => 'commerce-line-item',
'price_table:select' => 'commerce-line-item:commerce-product:field-price-table',
'component_name' => 'base_price',
));
$rule->weight = -9;
$rules['commerce_price_table_sku_contains_override_price'] = $rule;
return $rules;
}
/**
* Implements hook_rules_action_info().
*/
function commerce_price_table_sku_contains_rules_action_info() {
$actions = array();
$actions['commerce_price_table_sku_contains_set_price'] = array(
'label' => t('Set the unit price to a table based price'),
'parameter' => array(
'commerce_order' => array( // Wrong? Error: Missing configuration for parameter commerce_order.
'type' => 'commerce_order',
'label' => t('Order'),
'description' => t('The order whose line items should be checked for the specified product. If the specified order does not exist, the quantity is 0.'),
),
'product_id' => array(
'type' => 'text',
'label' => t('Product(s) SKU(s)'),
'description' => t('The SKU of the product must contain this information. Each SKUs on a newline'),
),
'commerce_line_item' => array(
'type' => 'commerce_line_item',
'label' => t('Line item'),
),
'price_table' => array(
'label' => t('Price table'),
'type' => 'list<commerce_price_table>',
),
'component_name' => array(
'type' => 'text',
'label' => t('Price component type'),
'description' => t('Price components track changes to prices made during the price calculation process, and they are carried over from the unit price to the total price of a line item. When an order total is calculated, it combines all the components of every line item on the order. When the unit price is altered by this action, the selected type of price component will be added to its data array and reflected in the order total display when it is formatted with components showing. Defaults to base price, which displays as the order Subtotal.'),
'options list' => 'commerce_line_item_price_component_options_list',
'default value' => 'base_price',
),
),
'group' => t('Commerce price table sku contains'),
);
return $actions;
}
/**
* Rules callback: executes the "Replace the price for a price table" action.
*/
function commerce_price_table_sku_contains_set_price($order, $sku, $line_item, $price_table, $component_name) {
// If the line item contains a product...
if (in_array($line_item->type, commerce_product_line_item_types())) {
// Load its referenced product.
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
$product = $line_item_wrapper->commerce_product->value();
// Bail now if the unit price is unset.
$unit_price = commerce_price_wrapper_value($line_item_wrapper, 'commerce_unit_price');
if (empty($unit_price)) {
return;
}
// Fetch the quantity of product that contains the partials skus in the order.
$quantity = commerce_price_table_sku_contains_partial_sku($order, $sku);
// Fetch the table based price for the current product quantity.
$table_price = commerce_price_table_get_amount_qty($product, $quantity, $price_table);
// If we got a valid table price...
if (!empty($table_price)) {
// If the currency is different from the current currency, convert it.
if ($unit_price['currency_code'] != $table_price['currency_code']) {
$line_item_wrapper->commerce_unit_price->amount = commerce_currency_convert($unit_price['amount'], $unit_price['currency_code'], $table_price['currency_code']);
$line_item_wrapper->commerce_unit_price->currency_code = $table_price['currency_code'];
// Convert the currency code of the price's components.
if (!empty($unit_price['data']['components'])) {
foreach ($unit_price['data']['components'] as $key => &$component) {
$component['price']['amount'] = commerce_currency_convert($component['price']['amount'], $component['price']['currency_code'], $table_price['currency_code']);
$component['price']['currency_code'] = $table_price['currency_code'];
}
$wrapper->commerce_unit_price->data = $unit_price['data'];
}
}
// Calculate the difference between the current unit price amount and the
// table price and create a price array representing the difference.
$current_amount = $unit_price['amount'];
$updated_amount = $table_price['amount'];
$difference = array(
'amount' => $updated_amount - $current_amount,
'currency_code' => $table_price['currency_code'],
'data' => array(),
);
// Set the amount of the unit price and add the difference as a component.
$line_item_wrapper->commerce_unit_price->amount = $updated_amount;
$line_item_wrapper->commerce_unit_price->data = commerce_price_component_add(
$line_item_wrapper->commerce_unit_price->value(),
$component_name,
$difference,
TRUE
);
}
}
}
/**
* Checks to see if a particular products exists on an order
* and calculates the total quantity, based on a sku fragment.
*/
function commerce_price_table_sku_contains_partial_sku($order, $skus) {
// Initialize
$total_quantity = 0;
// Don't do anything without a valid order.
if (!empty($order)) {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
// Populate the array of the quantities of the products on the order.
foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
if (in_array($line_item_wrapper->type->value(), commerce_product_line_item_types())) {
// Extract SKU and quantity from line item.
$line_item_sku = $line_item_wrapper->commerce_product->sku->value();
$quantity = $line_item_wrapper->quantity->value();
// Does the SKU exist partially in the order SKU?
// multiple skus on newlines
$sku = strtok($skus, PHP_EOL);
while ($sku !== false) {
if (strpos($line_item_sku, $sku) !== FALSE) {
// Update quantity.
$total_quantity += $quantity;
}
$sku = strtok( PHP_EOL );
}
}
}
}
return $total_quantity;
}
Thx!