CRM-15104 - Consider all components of fee_level.
authorJohan Vervloet <johan.vervloet@gmail.com>
Tue, 12 Aug 2014 18:40:38 +0000 (20:40 +0200)
committerJohan Vervloet <johan.vervloet@gmail.com>
Tue, 12 Aug 2014 20:06:32 +0000 (22:06 +0200)
* Support for multiple line items.
* Support for a quantity greater than one.

----------------------------------------
* CRM-15104: Line item issues when creating a participant using the API
  https://issues.civicrm.org/jira/browse/CRM-15104

api/v3/Participant.php

index a746e8a00e999523fac43a04dcbe942d3600a264..7a5bc7e216c8168ba16d06c8fe866ec13755393a 100644 (file)
@@ -81,31 +81,59 @@ function civicrm_api3_participant_create($params) {
  * Create a default participant line item
  */
 function _civicrm_api3_participant_createlineitem(&$params, $participant){
-  $sql = "
-SELECT      ps.id AS setID, pf.id AS priceFieldID, pfv.id AS priceFieldValueID
-FROM  civicrm_price_set_entity cpse
-LEFT JOIN civicrm_price_set ps ON cpse.price_set_id = ps.id AND cpse.entity_id = {$params['event_id']} AND cpse.entity_table = 'civicrm_event'
-LEFT JOIN   civicrm_price_field pf ON pf.`price_set_id` = ps.id
-LEFT JOIN   civicrm_price_field_value pfv ON pfv.price_field_id = pf.id and pfv.label = '{$params['fee_level']}'
-where ps.id is not null
-";
-
-  $dao = CRM_Core_DAO::executeQuery($sql);
-  if ($dao->fetch()) {
-    $amount = CRM_Utils_Array::value('fee_amount', $params, 0);
-    $lineItemparams = array(
-      'price_field_id' => $dao->priceFieldID,
-      'price_field_value_id' => $dao->priceFieldValueID,
-      'entity_table' => 'civicrm_participant',
-      'entity_id' => $participant->id,
-      'label' => $params['fee_level'],
-      'qty' => 1,
-      'participant_count' => 0,
-      'unit_price' => $amount,
-      'line_total' => $amount,
-      'version' => 3,
-    );
-    civicrm_api('line_item', 'create', $lineItemparams);
+  // it is possible that a fee level contains information about multiple
+  // price field values.
+
+  $priceFieldValueDetails = explode(
+    CRM_Core_DAO::VALUE_SEPARATOR,
+    $params["fee_level"]);
+
+  foreach($priceFieldValueDetails as $detail) {
+    if (empty($detail)) continue;
+
+
+    if (preg_match('/- ([0-9]+)$/', $detail, $matches)) {
+      // it is possible that a price field value is payd for multiple times.
+      // (FIXME: if the price field value ends in minus followed by whitespace
+      // and a number, things will go wrong.)
+
+      $qty = $matches[1];
+      preg_match('/^(.*) - [0-9]+$/', $detail, $matches);
+      $label = $matches[1];
+    }
+    else {
+      $label = $detail;
+      $qty = 1;
+    }
+
+    // TODO: I think we might have troubles with SQL injection below.
+
+    $sql = "
+      SELECT      ps.id AS setID, pf.id AS priceFieldID, pfv.id AS priceFieldValueID, pfv.amount AS amount
+      FROM  civicrm_price_set_entity cpse
+      LEFT JOIN civicrm_price_set ps ON cpse.price_set_id = ps.id AND cpse.entity_id = {$params['event_id']} AND cpse.entity_table = 'civicrm_event'
+      LEFT JOIN   civicrm_price_field pf ON pf.`price_set_id` = ps.id
+      LEFT JOIN   civicrm_price_field_value pfv ON pfv.price_field_id = pf.id and pfv.label = '{$label}'
+      where ps.id is not null
+    ";
+
+    $dao = CRM_Core_DAO::executeQuery($sql);
+    if ($dao->fetch()) {
+      $lineItemparams = array(
+        'price_field_id' => $dao->priceFieldID,
+        'price_field_value_id' => $dao->priceFieldValueID,
+        'entity_table' => 'civicrm_participant',
+        'entity_id' => $participant->id,
+        'label' => $label,
+        'qty' => $qty,
+        'participant_count' => 0,
+        'unit_price' => $dao->amount,
+        'line_total' => $qty*$dao->amount,
+        'version' => 3,
+      );
+      civicrm_api('line_item', 'create', $lineItemparams);
+    }
+
   }
 }