1

I need to calculate product sell price as gross price * markup (i.e. 1.4) Gross price is stored in field_data_commerce_price table (standard commerce price field). Markup value should be associated with every single product, so I can manage it with views using filters and VBO. I have many product types, so maually created markup field is not a good solution.

Is there any out-of-the-box solution?

and if not:

What is the best way to add new product field using API? (should be added by default for all product types)

1 Answer 1

3

If you need a per product price modificator, your best solution is to have a field with this information, you can probably use a normal numeric field for this purpose.

You've got many examples on how to create a field using the API, for example, drupal commerce itself adds a price field every time a product type is generated by using hook_modules_enabled hook.

/**
 * Implements hook_modules_enabled().
 */
function commerce_product_modules_enabled($modules) {
  commerce_product_configure_product_fields($modules);
}

Then in this function

function commerce_product_configure_product_fields($modules = NULL) {
(...)
      // Loop through and configure the product types defined by the module.
      foreach ($product_types as $type => $product_type) {
        commerce_product_configure_product_type($type);
      }

Next

/**
 * Ensures a base price field is present on a product type bundle.
 */
function commerce_product_configure_product_type($type) {
  commerce_price_create_instance('commerce_price', 'commerce_product', $type, t('Price'), 0, 'calculated_sell_price');
}

And finally

function commerce_price_create_instance($field_name, $entity_type, $bundle, $label, $weight = 0, $calculation = FALSE, $display = array()) {
  // Look for or add the specified price field to the requested entity bundle.
  commerce_activate_field($field_name);
  field_cache_clear();

  $field = field_info_field($field_name);
  $instance = field_info_instance($entity_type, $field_name, $bundle);

  if (empty($field)) {
    $field = array(
      'field_name' => $field_name,
      'type' => 'commerce_price',
      'cardinality' => 1,
      'entity_types' => array($entity_type),
      'translatable' => FALSE,
      'locked' => TRUE,
    );
    $field = field_create_field($field);
  }

  if (empty($instance)) {
    $instance = array(
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'bundle' => $bundle,

      'label' => $label,
      'required' => TRUE,
      'settings' => array(),

      // Because this widget is locked, we need it to use the full price widget
      // since the currency option can't be adjusted at the moment.
      'widget' => array(
        'type' => 'commerce_price_full',
        'weight' => $weight,
        'settings' => array(
          'currency_code' => 'default',
        ),
      ),

      'display' => array(),
    );

    $entity_info = entity_get_info($entity_type);

    // Spoof the default view mode and node teaser so its display type is set.
    $entity_info['view modes'] += array(
      'default' => array(),
      'node_teaser' => array(),
    );

    foreach ($entity_info['view modes'] as $view_mode => $data) {
      $instance['display'][$view_mode] = $display + array(
        'label' => 'hidden',
        'type' => 'commerce_price_formatted_amount',
        'settings' => array(
          'calculation' => $calculation,
        ),
        'weight' => $weight,
      );
    }

    field_create_instance($instance);
  }
}

So you in summary can use hook_modules_enabled to react and loop the product types and create your field and instance. Another examples of this procedure can be found in commerce recurring, commerce discount, commerce coupon and more.

2
  • Thanks, pcambra, I've implemented suggested hook_modules_enabled and "markup" field appeared in all commerce_product bundles, but when I trying to modify entity values with VBO it treats every field instance (one for each bundle) as separate field, so I can't modify markup value for all bundles in one simple action without "crazy checkboxing": (dl.dropboxusercontent.com/u/42690200/VBO-checkboxes.PNG)
    – Artreaktor
    Commented Jul 16, 2014 at 8:21
  • 1
    Yeah, it depends on the number of fields/product types you've got. If that's not manageable, you can create your own action for VBO and select the field for each type (saving it in a variable, like commerce does for the customer profile address field), that'd give you a single checkbox.
    – pcambra
    Commented Jul 16, 2014 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.