Here is a working code example that contains computed fields in
unlimited type multigroups and a computed field outside of the
multigroup. It is for a work order system. The user enters
in hours and hourly rate for labor and they enter qty and unit price
for parts. The materials and labor costs all get totalled up:

I have a content type called Work Order that contains two
unlimited value multigroups, Labor and Parts.
The Labor multigroup contains four
fields:

  • Hours - Decimal - field_hours_work_order
  • Description - Text
  • Per Hour - Decimal - field_per_hour_work_order
  • Total - Computed - field_total_labor_work_order
    • Computed Code that multiplies hours and hourly rate
      • foreach (array_keys($node->field_hours_work_order) as $delta) {
          if (isset($node->field_hours_work_order[$delta]['value']) && isset($node->field_per_hour_work_order[$delta]['value'])) {
            $node_field[$delta]['value'] = $node->field_hours_work_order[$delta]['value'] * $node->field_per_hour_work_order[$delta]['value'];
          }
        };
    • Data Type
      • Decimal
    • Not Null

The Parts multigroup also contains four fields:

  • Qty - Decimal - field_quantity_parts_work_order
  • Description - Text
  • Unit Price - Decimal - field_unit_price_work_order
  • Total - Computed - field_total_parts_work_order
    • Computed Code that multiplies Qty and Price
      • foreach (array_keys($node->field_quantity_parts_work_order) as $delta) {
          if (isset($node->field_quantity_parts_work_order[$delta]['value']) && isset($node->field_unit_price_work_order[$delta]['value'])) {
            $node_field[$delta]['value'] = $node->field_quantity_parts_work_order[$delta]['value'] * $node->field_unit_price_work_order[$delta]['value'];
          }
        };
    • Data Type
      • Decimal
    • Not Null

Next, I have a field called Total
that adds up all the Labor and Parts totals:

  • Computed Code that adds up all Labor and Parts totals for a grand total
    • $laborpartstotal = 0;
      foreach (array_keys($node->field_total_labor_work_order) as $delta) {
        if (isset($node->field_total_labor_work_order[$delta]['value'])) {
          global $laborpartstotal;
          $laborpartstotal += $node->field_total_labor_work_order[$delta]['value'];
        }
      };
      
      foreach (array_keys($node->field_total_parts_work_order) as $delta) {
        if (isset($node->field_total_parts_work_order[$delta]['value'])) {
          global $laborpartstotal;
          $laborpartstotal += $node->field_total_parts_work_order[$delta]['value'];
        }
      };
      
      $node_field[0]['value'] = $laborpartstotal;
      
  • Data Type
    • Decimal
  • Not Null

As a final step, I load up the Manage Fields page of my Work Order in a
browser with javascript turned off so I can make sure the field weights
are ok as they determine the order which the calculations take
place. I use a Firefox plugin called QuickJava to switch
javascript off. Then I make sure that the computed fields have
higher number weights than the fields they reference or the
calculations will require multiple node saves to calculate everything
(Which is unacceptable for accounting stuff.)

Hope this helps someone. Let me know if I need to
clarify anything by sending me a PM here on drupal.org.

Peace, Jeff aka loopduplicate

Comments

tomsm’s picture

This example helped me a lot. Thank you !

mautumn’s picture

This very clear example saved me the trouble of figuring it out myself. Much appreciated.

GlossyIbis

loopduplicate’s picture

Glad it helped you. It took me awhile to figure out myself. I learn everything from people who share so I thought I'd do the same.
Jeff Mahoney aka loopduplicate

tomsm’s picture

When I edit and preview an existing node, I get the following error:

number_format() expects parameter 1 to be double, string given in /home/fysiomed/domains/fysiomed.com/public_html/sites/all/modules/computed_field/computed_field.module(362) : eval()'d code on line 1.

Any idea how to solve this?

Update: Fixed, I changed my Display Format code from:
$display = '€ '.number_format($node_field_item['value'],2,",",".");

to:

if ($node_field_item['value'] != NULL)
{$display = '€ '.number_format($node_field_item['value'],2,",",".");
};
krisrobinson’s picture

Thanks, great example of Computed fields and multigroups - was a big help to me.

kaizerking’s picture

I have a field collection which has computed field with a value, it works fine,How ever i have another field in the field collection which will determine category and it is a user selectable taxonomy term, i require another two computed fields out side the field collection which will have the total of each category ,how this can be achieved?

one_hoopy_frood’s picture

Fantastic documentation. It demonstrates the 2 things one is likely to do with multigroup and computed fields. Thanks for taking the time to write it out. -Chris

albert9000’s picture

Example of a subtotal:

$how_many = field_get_items($entity_type, $entity, 'field_hours_work_order');
$how_much = field_get_items($entity_type, $entity, 'field_per_hour_work_order');

foreach (array_keys($how_many) as $delta) {
  if (isset($how_many[$delta]['value']) && isset($how_much[$delta]['value'])) {
    $entity_field[$delta]['value'] = $how_many[$delta]['value'] * $how_much[$delta]['value'];
  }
};

Example of getting a grand total:

$subtotal = field_get_items($entity_type, $entity, 'field_total_labor_work_order');

$laborpartstotal = 0;
foreach (array_keys($subtotal) as $delta) {
  if (isset($subtotal[$delta]['value'])) {
    global $laborpartstotal;
    $laborpartstotal += $subtotal[$delta]['value'];
  }
};

$entity_field[0]['value'] = $laborpartstotal;
wilks’s picture

Awesome, worked perfectly.

vmevada102’s picture

I am in. Need of calculation for the multi field and calculated field module in Drupal 7.

In my content type I had created the content type "invoice" with the following fields

Customer
Invoice num
Date
Products (multi field) subfield : description, price, quantity and amount.
Subtotal (computed field)

Now my problem is, I could not sum up the different values of the field_amount field.... Which is the subfield of the field_product main field.

Please let me know how can I sum up all my values which are array of all value as Subtotal field in my content type.

Thanking you