From 7ad3b4bdde704cf1affaef135655d98f13d280f9 Mon Sep 17 00:00:00 2001 From: Johan Vervloet Date: Tue, 12 Aug 2014 20:40:38 +0200 Subject: [PATCH] CRM-15104 - Consider all components of fee_level. * 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 | 78 ++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/api/v3/Participant.php b/api/v3/Participant.php index a746e8a00e..7a5bc7e216 100644 --- a/api/v3/Participant.php +++ b/api/v3/Participant.php @@ -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); + } + } } -- 2.25.1