Merge pull request #4764 from rohankatkar/CRM-15615
[civicrm-core.git] / CRM / Price / BAO / PriceSet.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
06b69b18 4 | CiviCRM version 4.5 |
6a488035 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
32 * $Id$
33 *
34 */
35
36/**
37 * Business object for managing price sets
38 *
39 */
9da8dc8c 40class CRM_Price_BAO_PriceSet extends CRM_Price_DAO_PriceSet {
6a488035 41
71ba92c4 42 /**
100fef9d 43 * Static field for default price set details
71ba92c4
PN
44 *
45 * @var array
46 * @static
47 */
48 static $_defaultPriceSet = NULL;
49
6a488035 50 /**
100fef9d 51 * Class constructor
6a488035
TO
52 */
53 function __construct() {
54 parent::__construct();
55 }
56
57 /**
100fef9d 58 * Takes an associative array and creates a price set object
6a488035
TO
59 *
60 * @param array $params (reference) an assoc array of name/value pairs
61 *
c490a46a 62 * @return CRM_Price_DAO_PriceSet object
6a488035
TO
63 * @access public
64 * @static
65 */
66 static function create(&$params) {
e0c1764e
EM
67 if(empty($params['id']) && empty($params['name'])) {
68 $params['name'] = CRM_Utils_String::munge($params['title'], '_', 242);
69 }
9da8dc8c 70 $priceSetBAO = new CRM_Price_BAO_PriceSet();
6a488035
TO
71 $priceSetBAO->copyValues($params);
72 if (self::eventPriceSetDomainID()) {
73 $priceSetBAO->domain_id = CRM_Core_Config::domainID();
74 }
75 return $priceSetBAO->save();
76 }
77
78 /**
c490a46a 79 * Fetch object based on array of properties
6a488035
TO
80 *
81 * @param array $params (reference ) an assoc array of name/value pairs
82 * @param array $defaults (reference ) an assoc array to hold the flattened values
83 *
c490a46a 84 * @return CRM_Price_DAO_PriceSet object
6a488035
TO
85 * @access public
86 * @static
87 */
88 static function retrieve(&$params, &$defaults) {
9da8dc8c 89 return CRM_Core_DAO::commonRetrieve('CRM_Price_DAO_PriceSet', $params, $defaults);
6a488035
TO
90 }
91
92 /**
100fef9d 93 * Update the is_active flag in the db
6a488035 94 *
6c8f6e67
EM
95 * @param int $id id of the database record
96 * @param $isActive
97 *
98 * @internal param bool $is_active value we want to set the is_active field
6a488035
TO
99 *
100 * @return Object DAO object on sucess, null otherwise
101 * @static
102 * @access public
103 */
104 static function setIsActive($id, $isActive) {
9da8dc8c 105 return CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceSet', $id, 'is_active', $isActive);
6a488035
TO
106 }
107
108 /**
109 * Calculate the default price set id
110 * assigned to the contribution/membership etc
111 *
112 * @param string $entity
113 *
e0c1764e 114 * @return array $defaultPriceSet default price set
6a488035
TO
115 *
116 * @access public
117 * @static
118 *
119 */
120 public static function getDefaultPriceSet($entity = 'contribution') {
71ba92c4
PN
121 if (!empty(self::$_defaultPriceSet[$entity])) {
122 return self::$_defaultPriceSet[$entity];
123 }
e0c1764e
EM
124 $entityName = 'default_contribution_amount';
125 if ($entity == 'membership') {
6a488035
TO
126 $entityName = 'default_membership_type_amount';
127 }
128
129 $sql = "
82cc6775 130SELECT ps.id AS setID, pfv.price_field_id AS priceFieldID, pfv.id AS priceFieldValueID, pfv.name, pfv.label, pfv.membership_type_id, pfv.amount, pfv.financial_type_id
6a488035
TO
131FROM civicrm_price_set ps
132LEFT JOIN civicrm_price_field pf ON pf.`price_set_id` = ps.id
133LEFT JOIN civicrm_price_field_value pfv ON pfv.price_field_id = pf.id
134WHERE ps.name = '{$entityName}'
135";
136
137 $dao = CRM_Core_DAO::executeQuery($sql);
71ba92c4 138 self::$_defaultPriceSet[$entity] = array();
6a488035 139 while ($dao->fetch()) {
71ba92c4
PN
140 self::$_defaultPriceSet[$entity][$dao->priceFieldValueID] = array(
141 'setID' => $dao->setID,
142 'priceFieldID' => $dao->priceFieldID,
143 'name' => $dao->name,
144 'label' => $dao->label,
145 'priceFieldValueID' => $dao->priceFieldValueID,
146 'membership_type_id' => $dao->membership_type_id,
147 'amount' => $dao->amount,
148 'financial_type_id' => $dao->financial_type_id,
149 );
6a488035
TO
150 }
151
71ba92c4 152 return self::$_defaultPriceSet[$entity];
6a488035
TO
153 }
154
155 /**
156 * Get the price set title.
157 *
158 * @param int $id id of price set
159 *
160 * @return string title
161 *
162 * @access public
163 * @static
164 *
165 */
166 public static function getTitle($id) {
9da8dc8c 167 return CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $id, 'title');
6a488035
TO
168 }
169
170 /**
171 * Return a list of all forms which use this price set.
172 *
da6b46f4 173 * @param int $id id of price set
e0c1764e 174 * @param bool|string $simpleReturn - get raw data. Possible values: 'entity', 'table'
6a488035
TO
175 *
176 * @return array
177 */
178 public static function &getUsedBy($id, $simpleReturn = FALSE) {
179 $usedBy = $forms = $tables = array();
180 $queryString = "
181SELECT entity_table, entity_id
182FROM civicrm_price_set_entity
183WHERE price_set_id = %1";
184 $params = array(1 => array($id, 'Integer'));
185 $crmFormDAO = CRM_Core_DAO::executeQuery($queryString, $params);
186
187 while ($crmFormDAO->fetch()) {
188 $forms[$crmFormDAO->entity_table][] = $crmFormDAO->entity_id;
189 $tables[] = $crmFormDAO->entity_table;
190 }
191 // Return only tables
192 if ($simpleReturn == 'table') {
193 return $tables;
194 }
195 if (empty($forms)) {
196 $queryString = "
197SELECT cli.entity_table, cli.entity_id
198FROM civicrm_line_item cli
199LEFT JOIN civicrm_price_field cpf ON cli.price_field_id = cpf.id
200WHERE cpf.price_set_id = %1";
201 $params = array(1 => array($id, 'Integer'));
202 $crmFormDAO = CRM_Core_DAO::executeQuery($queryString, $params);
203 while ($crmFormDAO->fetch()) {
204 $forms[$crmFormDAO->entity_table][] = $crmFormDAO->entity_id;
205 $tables[] = $crmFormDAO->entity_table;
206 }
207 if (empty($forms)) {
208 return $usedBy;
209 }
210 }
211 // Return only entity data
212 if ($simpleReturn == 'entity') {
213 return $forms;
214 }
215 foreach ($forms as $table => $entities) {
216 switch ($table) {
217 case 'civicrm_event':
218 $ids = implode(',', $entities);
c34e4bb4 219 $queryString = "SELECT ce.id as id, ce.title as title, ce.is_public as isPublic, ce.start_date as startDate, ce.end_date as endDate, civicrm_option_value.label as eventType, ce.is_template as isTemplate, ce.template_title as templateTitle
6a488035
TO
220FROM civicrm_event ce
221LEFT JOIN civicrm_option_value ON
222 ( ce.event_type_id = civicrm_option_value.value )
223LEFT JOIN civicrm_option_group ON
224 ( civicrm_option_group.id = civicrm_option_value.option_group_id )
225WHERE
226 civicrm_option_group.name = 'event_type' AND
6a488035
TO
227 ce.id IN ($ids) AND
228 ce.is_active = 1;";
229 $crmDAO = CRM_Core_DAO::executeQuery($queryString);
230 while ($crmDAO->fetch()) {
c34e4bb4
PJ
231 if ($crmDAO->isTemplate) {
232 $usedBy['civicrm_event_template'][$crmDAO->id]['title'] = $crmDAO->templateTitle;
233 $usedBy['civicrm_event_template'][$crmDAO->id]['eventType'] = $crmDAO->eventType;
234 $usedBy['civicrm_event_template'][$crmDAO->id]['isPublic'] = $crmDAO->isPublic;
235 }
236 else {
237 $usedBy[$table][$crmDAO->id]['title'] = $crmDAO->title;
238 $usedBy[$table][$crmDAO->id]['eventType'] = $crmDAO->eventType;
239 $usedBy[$table][$crmDAO->id]['startDate'] = $crmDAO->startDate;
240 $usedBy[$table][$crmDAO->id]['endDate'] = $crmDAO->endDate;
241 $usedBy[$table][$crmDAO->id]['isPublic'] = $crmDAO->isPublic;
242 }
6a488035
TO
243 }
244 break;
245
246 case 'civicrm_contribution_page':
247 $ids = implode(',', $entities);
248 $queryString = "SELECT cp.id as id, cp.title as title, cp.start_date as startDate, cp.end_date as endDate,ct.name as type
249FROM civicrm_contribution_page cp, civicrm_financial_type ct
cde484fd 250WHERE ct.id = cp.financial_type_id AND
6a488035
TO
251 cp.id IN ($ids) AND
252 cp.is_active = 1;";
253 $crmDAO = CRM_Core_DAO::executeQuery($queryString);
254 while ($crmDAO->fetch()) {
255 $usedBy[$table][$crmDAO->id]['title'] = $crmDAO->title;
256 $usedBy[$table][$crmDAO->id]['type'] = $crmDAO->type;
257 $usedBy[$table][$crmDAO->id]['startDate'] = $crmDAO->startDate;
258 $usedBy[$table][$crmDAO->id]['endDate'] = $crmDAO->endDate;
259 }
260 break;
261
262 case 'civicrm_contribution':
263 case 'civicrm_membership':
264 case 'civicrm_participant':
265 $usedBy[$table] = 1;
266 break;
267
268 default:
269 CRM_Core_Error::fatal("$table is not supported in PriceSet::usedBy()");
270 break;
271 }
272 }
273
274 return $usedBy;
275 }
276
277 /**
278 * Delete the price set
279 *
280 * @param int $id Price Set id
281 *
282 * @return boolean false if fields exist for this set, true if the
283 * set could be deleted
284 *
285 * @access public
286 * @static
287 */
288 public static function deleteSet($id) {
289 // remove from all inactive forms
290 $usedBy = self::getUsedBy($id);
291 if (isset($usedBy['civicrm_event'])) {
292 foreach ($usedBy['civicrm_event'] as $eventId => $unused) {
293 $eventDAO = new CRM_Event_DAO_Event();
294 $eventDAO->id = $eventId;
295 $eventDAO->find();
296 while ($eventDAO->fetch()) {
297 self::removeFrom('civicrm_event', $eventDAO->id);
298 }
299 }
300 }
301
302 // delete price fields
9da8dc8c 303 $priceField = new CRM_Price_DAO_PriceField();
6a488035
TO
304 $priceField->price_set_id = $id;
305 $priceField->find();
306 while ($priceField->fetch()) {
307 // delete options first
9da8dc8c 308 CRM_Price_BAO_PriceField::deleteField($priceField->id);
6a488035
TO
309 }
310
9da8dc8c 311 $set = new CRM_Price_DAO_PriceSet();
6a488035
TO
312 $set->id = $id;
313 return $set->delete();
314 }
315
316 /**
317 * Link the price set with the specified table and id
318 *
319 * @param string $entityTable
320 * @param integer $entityId
321 * @param integer $priceSetId
322 *
323 * @return bool
324 */
325 public static function addTo($entityTable, $entityId, $priceSetId) {
326 // verify that the price set exists
9da8dc8c 327 $dao = new CRM_Price_DAO_PriceSet();
6a488035
TO
328 $dao->id = $priceSetId;
329 if (!$dao->find()) {
330 return FALSE;
331 }
332 unset($dao);
333
9da8dc8c 334 $dao = new CRM_Price_DAO_PriceSetEntity();
6a488035
TO
335 // find if this already exists
336 $dao->entity_id = $entityId;
337 $dao->entity_table = $entityTable;
338 $dao->find(TRUE);
339
340 // add or update price_set_id
341 $dao->price_set_id = $priceSetId;
342 return $dao->save();
343 }
344
345 /**
346 * Delete price set for the given entity and id
347 *
348 * @param string $entityTable
349 * @param integer $entityId
77b97be7
EM
350 *
351 * @return mixed
6a488035
TO
352 */
353 public static function removeFrom($entityTable, $entityId) {
9da8dc8c 354 $dao = new CRM_Price_DAO_PriceSetEntity();
6a488035
TO
355 $dao->entity_table = $entityTable;
356 $dao->entity_id = $entityId;
357 return $dao->delete();
358 }
359
360 /**
361 * Find a price_set_id associatied with the given table, id and usedFor
362 * Used For value for events:1, contribution:2, membership:3
363 *
364 * @param string $entityTable
77b97be7
EM
365 * @param int $entityId
366 * @param int $usedFor ( price set that extends/used for particular component )
367 *
368 * @param null $isQuickConfig
369 * @param null $setName
6a488035
TO
370 *
371 * @return integer|false price_set_id, or false if none found
372 */
373 public static function getFor($entityTable, $entityId, $usedFor = NULL, $isQuickConfig = NULL, &$setName = NULL) {
374 if (!$entityTable || !$entityId) {
375 return FALSE;
376 }
377
378 $sql = 'SELECT ps.id as price_set_id, ps.name as price_set_name
379 FROM civicrm_price_set ps
380 INNER JOIN civicrm_price_set_entity pse ON ps.id = pse.price_set_id
381 WHERE pse.entity_table = %1 AND pse.entity_id = %2 ';
382 if ($isQuickConfig) {
383 $sql .= ' AND ps.is_quick_config = 0 ';
384 }
385 $params = array(1 => array($entityTable, 'String'),
386 2 => array($entityId, 'Integer'),
387 );
388 if ($usedFor) {
389 $sql .= " AND ps.extends LIKE '%%3%' ";
390 $params[3] = array($usedFor, 'Integer');
391 }
392
393 $dao = CRM_Core_DAO::executeQuery($sql, $params);
394 $dao->fetch();
395 $setName = (isset($dao->price_set_name)) ? $dao->price_set_name : FALSE;
396 return (isset($dao->price_set_id)) ? $dao->price_set_id : FALSE;
397 }
398
399 /**
e0c1764e 400 * Find a price_set_id associated with the given option value or field ID
6a488035
TO
401 *
402 * @param array $params (reference) an assoc array of name/value pairs
403 * array may contain either option id or
404 * price field id
405 *
e0c1764e 406 * @return integer|NULL price set id on success, null otherwise
6a488035
TO
407 * @static
408 * @access public
409 */
410 public static function getSetId(&$params) {
411 $fid = NULL;
412
413 if ($oid = CRM_Utils_Array::value('oid', $params)) {
9da8dc8c 414 $fieldValue = new CRM_Price_DAO_PriceFieldValue();
6a488035
TO
415 $fieldValue->id = $oid;
416 if ($fieldValue->find(TRUE)) {
417 $fid = $fieldValue->price_field_id;
418 }
419 }
420 else {
421 $fid = CRM_Utils_Array::value('fid', $params);
422 }
423
424 if (isset($fid)) {
9da8dc8c 425 return CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $fid, 'price_set_id');
6a488035
TO
426 }
427
428 return NULL;
429 }
430
431 /**
432 * Return an associative array of all price sets
433 *
77b97be7
EM
434 * @param bool $withInactive whether or not to include inactive entries
435 * @param bool|string $extendComponentName name of the component like 'CiviEvent','CiviContribute'
6a488035
TO
436 *
437 * @return array associative array of id => name
438 */
439 public static function getAssoc($withInactive = FALSE, $extendComponentName = FALSE) {
440 $query = '
441 SELECT
442 DISTINCT ( price_set_id ) as id, title
443 FROM
444 civicrm_price_field,
445 civicrm_price_set
446 WHERE
447 civicrm_price_set.id = civicrm_price_field.price_set_id AND is_quick_config = 0 ';
448
449 if (!$withInactive) {
450 $query .= ' AND civicrm_price_set.is_active = 1 ';
451 }
452
453 if (self::eventPriceSetDomainID()) {
454 $query .= ' AND civicrm_price_set.domain_id = ' . CRM_Core_Config::domainID();
455 }
456
457 $priceSets = array();
458
459 if ($extendComponentName) {
460 $componentId = CRM_Core_Component::getComponentID($extendComponentName);
461 if (!$componentId) {
462 return $priceSets;
463 }
464 $query .= " AND civicrm_price_set.extends LIKE '%$componentId%' ";
465 }
466
467 $dao = CRM_Core_DAO::executeQuery($query);
468 while ($dao->fetch()) {
469 $priceSets[$dao->id] = $dao->title;
470 }
471 return $priceSets;
472 }
473
474 /**
475 * Get price set details
476 *
477 * An array containing price set details (including price fields) is returned
478 *
100fef9d 479 * @param int $setID
2a6da8d7
EM
480 * @param bool $required
481 * @param bool $validOnly
482 *
483 * @internal param int $setId - price set id whose details are needed
6a488035
TO
484 *
485 * @return array $setTree - array consisting of field details
486 */
487 public static function getSetDetail($setID, $required = TRUE, $validOnly = FALSE) {
488 // create a new tree
489 $setTree = array();
6a488035
TO
490
491 $priceFields = array(
492 'id',
493 'name',
494 'label',
495 'html_type',
496 'is_enter_qty',
497 'help_pre',
498 'help_post',
499 'weight',
500 'is_display_amounts',
501 'options_per_line',
502 'is_active',
503 'active_on',
504 'expire_on',
505 'javascript',
506 'visibility_id',
507 'is_required',
508 );
509 if ($required == TRUE) {
510 $priceFields[] = 'is_required';
511 }
512
513 // create select
514 $select = 'SELECT ' . implode(',', $priceFields);
515 $from = ' FROM civicrm_price_field';
516
517 $params = array();
518 $params[1] = array($setID, 'Integer');
519 $where = '
520WHERE price_set_id = %1
521AND is_active = 1
522';
523 $dateSelect = '';
524 if ($validOnly) {
525 $currentTime = date('YmdHis');
526 $dateSelect = "
527AND ( active_on IS NULL OR active_on <= {$currentTime} )
528AND ( expire_on IS NULL OR expire_on >= {$currentTime} )
529";
530 }
531
532 $orderBy = ' ORDER BY weight';
533
534 $sql = $select . $from . $where . $dateSelect . $orderBy;
535
536 $dao = CRM_Core_DAO::executeQuery($sql, $params);
537
538 $visibility = CRM_Core_PseudoConstant::visibility('name');
539 while ($dao->fetch()) {
540 $fieldID = $dao->id;
541
542 $setTree[$setID]['fields'][$fieldID] = array();
543 $setTree[$setID]['fields'][$fieldID]['id'] = $fieldID;
544
545 foreach ($priceFields as $field) {
546 if ($field == 'id' || is_null($dao->$field)) {
547 continue;
548 }
549
550 if ($field == 'visibility_id') {
551 $setTree[$setID]['fields'][$fieldID]['visibility'] = $visibility[$dao->$field];
552 }
553 $setTree[$setID]['fields'][$fieldID][$field] = $dao->$field;
554 }
9da8dc8c 555 $setTree[$setID]['fields'][$fieldID]['options'] = CRM_Price_BAO_PriceField::getOptions($fieldID, FALSE);
6a488035
TO
556 }
557
558 // also get the pre and post help from this price set
559 $sql = "
560SELECT extends, financial_type_id, help_pre, help_post, is_quick_config
561FROM civicrm_price_set
562WHERE id = %1";
563 $dao = CRM_Core_DAO::executeQuery($sql, $params);
564 if ($dao->fetch()) {
565 $setTree[$setID]['extends'] = $dao->extends;
157b21d8 566 $setTree[$setID]['financial_type_id'] = $dao->financial_type_id;
6a488035
TO
567 $setTree[$setID]['help_pre'] = $dao->help_pre;
568 $setTree[$setID]['help_post'] = $dao->help_post;
569 $setTree[$setID]['is_quick_config'] = $dao->is_quick_config;
570 }
571 return $setTree;
572 }
573
85020e43
EM
574 /**
575 * Get the Price Field ID. We call this function when more than one being present would represent an error
576 * starting format derived from current(CRM_Price_BAO_PriceSet::getSetDetail($priceSetId))
577 * @param array $priceSet
578 *
579 * @throws CRM_Core_Exception
580 * @return int
581 */
582 static function getOnlyPriceFieldID(array $priceSet) {
583 if(count($priceSet['fields']) > 1) {
584 throw new CRM_Core_Exception(ts('expected only one price field to be in priceset but multiple are present'));
585 }
586 return (int) implode('_', array_keys($priceSet['fields']));
587 }
588
589 /**
590 * Get the Price Field Value ID. We call this function when more than one being present would represent an error
591 * current(CRM_Price_BAO_PriceSet::getSetDetail($priceSetId))
592 * @param array $priceSet
593 *
594 * @throws CRM_Core_Exception
595 * @return int
596 */
597 static function getOnlyPriceFieldValueID(array $priceSet) {
598 $priceFieldID = self::getOnlyPriceFieldID($priceSet);
599 if(count($priceSet['fields'][$priceFieldID]['options']) > 1) {
600 throw new CRM_Core_Exception(ts('expected only one price field to be in priceset but multiple are present'));
601 }
602 return (int) implode('_', array_keys($priceSet['fields'][$priceFieldID]['options']));
603 }
604
605
ffd93213 606 /**
e0c1764e 607 * @param CRM_Core_Form $form
100fef9d 608 * @param int $id
ffd93213
EM
609 * @param string $entityTable
610 * @param bool $validOnly
100fef9d 611 * @param int $priceSetId
ffd93213
EM
612 *
613 * @return bool|false|int|null
614 */
6a488035
TO
615 static function initSet(&$form, $id, $entityTable = 'civicrm_event', $validOnly = FALSE, $priceSetId = NULL) {
616 if (!$priceSetId) {
617 $priceSetId = self::getFor($entityTable, $id);
618 }
619
620 //check if priceset is is_config
621 if (is_numeric($priceSetId)) {
9da8dc8c 622 if (CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'is_quick_config') && $form->getVar('_name') != 'Participant') {
6a488035
TO
623 $form->assign('quickConfig', 1);
624 }
625 }
626 // get price info
627 if ($priceSetId) {
628 if ($form->_action & CRM_Core_Action::UPDATE) {
629 $entityId = $entity = NULL;
630
631 switch ($entityTable) {
632 case 'civicrm_event':
633 $entity = 'participant';
634 if (CRM_Utils_System::getClassName($form) == 'CRM_Event_Form_Participant') {
635 $entityId = $form->_id;
636 }
637 else {
638 $entityId = $form->_participantId;
639 }
640 break;
641
642 case 'civicrm_contribution_page':
643 case 'civicrm_contribution':
644 $entity = 'contribution';
645 $entityId = $form->_id;
646 break;
647 }
648
649 if ($entityId && $entity) {
650 $form->_values['line_items'] = CRM_Price_BAO_LineItem::getLineItems($entityId, $entity);
651 }
652 $required = FALSE;
653 }
654 else {
655 $required = TRUE;
656 }
657
658 $form->_priceSetId = $priceSetId;
659 $priceSet = self::getSetDetail($priceSetId, $required, $validOnly);
660 $form->_priceSet = CRM_Utils_Array::value($priceSetId, $priceSet);
661 $form->_values['fee'] = CRM_Utils_Array::value('fields', $form->_priceSet);
662
663 //get the price set fields participant count.
664 if ($entityTable == 'civicrm_event') {
665 //get option count info.
666 $form->_priceSet['optionsCountTotal'] = self::getPricesetCount($priceSetId);
667 if ($form->_priceSet['optionsCountTotal']) {
668 $optionsCountDeails = array();
669 if (!empty($form->_priceSet['fields'])) {
670 foreach ($form->_priceSet['fields'] as $field) {
671 foreach ($field['options'] as $option) {
672 $count = CRM_Utils_Array::value('count', $option, 0);
673 $optionsCountDeails['fields'][$field['id']]['options'][$option['id']] = $count;
674 }
675 }
676 }
677 $form->_priceSet['optionsCountDetails'] = $optionsCountDeails;
678 }
679
680 //get option max value info.
681 $optionsMaxValueTotal = 0;
682 $optionsMaxValueDetails = array();
683
684 if (!empty($form->_priceSet['fields'])) {
685 foreach ($form->_priceSet['fields'] as $field) {
686 foreach ($field['options'] as $option) {
687 $maxVal = CRM_Utils_Array::value('max_value', $option, 0);
688 $optionsMaxValueDetails['fields'][$field['id']]['options'][$option['id']] = $maxVal;
689 $optionsMaxValueTotal += $maxVal;
690 }
691 }
692 }
693
694 $form->_priceSet['optionsMaxValueTotal'] = $optionsMaxValueTotal;
695 if ($optionsMaxValueTotal) {
696 $form->_priceSet['optionsMaxValueDetails'] = $optionsMaxValueDetails;
697 }
698 }
699 $form->set('priceSetId', $form->_priceSetId);
700 $form->set('priceSet', $form->_priceSet);
701
702 return $priceSetId;
703 }
704 return FALSE;
705 }
706
ffd93213
EM
707 /**
708 * @param $fields
c490a46a 709 * @param array $params
ffd93213
EM
710 * @param $lineItem
711 * @param string $component
712 */
6a488035
TO
713 static function processAmount(&$fields, &$params, &$lineItem, $component = '') {
714 // using price set
dc428161 715 $totalPrice = $totalTax = 0;
6a488035
TO
716 $radioLevel = $checkboxLevel = $selectLevel = $textLevel = array();
717 if ($component) {
718 $autoRenew = array();
719 $autoRenew[0] = $autoRenew[1] = $autoRenew[2] = 0;
720 }
721 foreach ($fields as $id => $field) {
a7488080 722 if (empty($params["price_{$id}"]) ||
6a488035
TO
723 (empty($params["price_{$id}"]) && $params["price_{$id}"] == NULL)
724 ) {
725 // skip if nothing was submitted for this field
726 continue;
727 }
728
729 switch ($field['html_type']) {
730 case 'Text':
be45c8b4
EM
731 $firstOption = reset($field['options']);
732 $params["price_{$id}"] = array($firstOption['id'] => $params["price_{$id}"]);
6a488035 733 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
dc428161 734 if (CRM_Utils_Array::value('tax_rate', $field['options'][key($field['options'])])) {
735 $lineItem = self::setLineItem($field, $lineItem, key($field['options']));
736 $totalTax += $field['options'][key($field['options'])]['tax_amount'] * $lineItem[key($field['options'])]['qty'];
737 }
049db839 738 if (CRM_Utils_Array::value('name', $field['options'][key($field['options'])]) == 'contribution_amount') {
739 $taxRates = CRM_Core_PseudoConstant::getTaxRates();
740 if (array_key_exists($params['financial_type_id'], $taxRates)) {
741 $field['options'][key($field['options'])]['tax_rate'] = $taxRates[$params['financial_type_id']];
742 $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($field['options'][key($field['options'])]['amount'], $field['options'][key($field['options'])]['tax_rate']);
cce6ec9f 743 $field['options'][key($field['options'])]['tax_amount'] = round($taxAmount['tax_amount'], 2);
049db839 744 $lineItem = self::setLineItem($field, $lineItem, key($field['options']));
745 $totalTax += $field['options'][key($field['options'])]['tax_amount'] * $lineItem[key($field['options'])]['qty'];
746 }
747 }
3b5db8ce 748 $totalPrice += $lineItem[$firstOption['id']]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[key($field['options'])]);
6a488035
TO
749 break;
750
751 case 'Radio':
752 //special case if user select -none-
753 if ($params["price_{$id}"] <= 0) {
754 continue;
755 }
756 $params["price_{$id}"] = array($params["price_{$id}"] => 1);
757 $optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);
758 $optionLabel = CRM_Utils_Array::value('label', $field['options'][$optionValueId]);
759 $params['amount_priceset_level_radio'] = array();
760 $params['amount_priceset_level_radio'][$optionValueId] = $optionLabel;
761 if (isset($radioLevel)) {
762 $radioLevel = array_merge($radioLevel,
763 array_keys($params['amount_priceset_level_radio'])
764 );
765 }
766 else {
767 $radioLevel = array_keys($params['amount_priceset_level_radio']);
768 }
769 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
dc428161 770 if (CRM_Utils_Array::value('tax_rate', $field['options'][$optionValueId])) {
771 $lineItem = self::setLineItem($field, $lineItem, $optionValueId);
772 $totalTax += $field['options'][$optionValueId]['tax_amount'];
c40e1ff4 773 if (CRM_Utils_Array::value('field_title', $lineItem[$optionValueId]) == 'Membership Amount') {
774 $lineItem[$optionValueId]['line_total'] = $lineItem[$optionValueId]['unit_price'] = CRM_Utils_Rule::cleanMoney($lineItem[$optionValueId]['line_total'] - $lineItem[$optionValueId]['tax_amount']);
775 }
dc428161 776 }
c40e1ff4 777 $totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
cde484fd
DL
778 if (
779 $component &&
a6c4ca20 780 // auto_renew exists and is empty in some workflows, which php treat as a 0
28156120 781 // and hence we explicitly check to see if auto_renew is numeric
cde484fd
DL
782 isset($lineItem[$optionValueId]['auto_renew']) &&
783 is_numeric($lineItem[$optionValueId]['auto_renew'])
784 ) {
6a488035
TO
785 $autoRenew[$lineItem[$optionValueId]['auto_renew']] += $lineItem[$optionValueId]['line_total'];
786 }
787 break;
788
789 case 'Select':
790 $params["price_{$id}"] = array($params["price_{$id}"] => 1);
791 $optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);
792 $optionLabel = $field['options'][$optionValueId]['label'];
793 $params['amount_priceset_level_select'] = array();
794 $params['amount_priceset_level_select'][CRM_Utils_Array::key(1, $params["price_{$id}"])] = $optionLabel;
795 if (isset($selectLevel)) {
796 $selectLevel = array_merge($selectLevel, array_keys($params['amount_priceset_level_select']));
797 }
798 else {
799 $selectLevel = array_keys($params['amount_priceset_level_select']);
800 }
801 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
dc428161 802 if (CRM_Utils_Array::value('tax_rate', $field['options'][$optionValueId])) {
803 $lineItem = self::setLineItem($field, $lineItem, $optionValueId);
804 $totalTax += $field['options'][$optionValueId]['tax_amount'];
805 }
c40e1ff4 806 $totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
cde484fd
DL
807 if (
808 $component &&
809 isset($lineItem[$optionValueId]['auto_renew']) &&
810 is_numeric($lineItem[$optionValueId]['auto_renew'])
811 ) {
6a488035
TO
812 $autoRenew[$lineItem[$optionValueId]['auto_renew']] += $lineItem[$optionValueId]['line_total'];
813 }
814 break;
815
816 case 'CheckBox':
817 $params['amount_priceset_level_checkbox'] = $optionIds = array();
818 foreach ($params["price_{$id}"] as $optionId => $option) {
819 $optionIds[] = $optionId;
820 $optionLabel = $field['options'][$optionId]['label'];
821 $params['amount_priceset_level_checkbox']["{$field['options'][$optionId]['id']}"] = $optionLabel;
822 if (isset($checkboxLevel)) {
823 $checkboxLevel = array_unique(array_merge(
824 $checkboxLevel,
825 array_keys($params['amount_priceset_level_checkbox'])
826 )
827 );
828 }
829 else {
830 $checkboxLevel = array_keys($params['amount_priceset_level_checkbox']);
831 }
832 }
833 CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem);
834 foreach ($optionIds as $optionId) {
dc428161 835 if (CRM_Utils_Array::value('tax_rate', $field['options'][$optionId])) {
836 $lineItem = self::setLineItem($field, $lineItem, $optionId);
837 $totalTax += $field['options'][$optionId]['tax_amount'];
838 }
c40e1ff4 839 $totalPrice += $lineItem[$optionId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionId]);
cde484fd
DL
840 if (
841 $component &&
842 isset($lineItem[$optionId]['auto_renew']) &&
843 is_numeric($lineItem[$optionId]['auto_renew'])
844 ) {
6a488035
TO
845 $autoRenew[$lineItem[$optionId]['auto_renew']] += $lineItem[$optionId]['line_total'];
846 }
847 }
848 break;
849 }
850 }
851
852 $amount_level = array();
853 $totalParticipant = 0;
854 if (is_array($lineItem)) {
855 foreach ($lineItem as $values) {
856 $totalParticipant += $values['participant_count'];
857 if ($values['html_type'] == 'Text') {
858 $amount_level[] = $values['label'] . ' - ' . $values['qty'];
859 continue;
860 }
861 $amount_level[] = $values['label'];
862 }
863 }
864
865 $displayParticipantCount = '';
866 if ($totalParticipant > 0) {
867 $displayParticipantCount = ' Participant Count -' . $totalParticipant;
868 }
869 $params['amount_level'] = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $amount_level) . $displayParticipantCount . CRM_Core_DAO::VALUE_SEPARATOR;
870 $params['amount'] = $totalPrice;
dc428161 871 $params['tax_amount'] = $totalTax;
6a488035
TO
872 if ($component) {
873 foreach ($autoRenew as $dontCare => $eachAmount) {
874 if (!$eachAmount) {
cde484fd 875 unset($autoRenew[$dontCare]);
6a488035
TO
876 }
877 }
878 if (count($autoRenew) > 1 ) {
879 $params['autoRenew'] = $autoRenew;
880 }
881 }
882 }
883
884 /**
100fef9d 885 * Build the price set form.
6a488035 886 *
e0c1764e 887 * @param CRM_Core_Form $form
dd244018 888 *
355ba699 889 * @return void
6a488035
TO
890 * @access public
891 */
892 static function buildPriceSet(&$form) {
893 $priceSetId = $form->get('priceSetId');
6a488035
TO
894 if (!$priceSetId) {
895 return;
896 }
897
898 $validFieldsOnly = TRUE;
899 $className = CRM_Utils_System::getClassName($form);
900 if (in_array($className, array(
901 'CRM_Contribute_Form_Contribution', 'CRM_Member_Form_Membership'))) {
902 $validFieldsOnly = FALSE;
903 }
904
905 $priceSet = self::getSetDetail($priceSetId, TRUE, $validFieldsOnly);
906 $form->_priceSet = CRM_Utils_Array::value($priceSetId, $priceSet);
883e4763 907 $validPriceFieldIds = array_keys($form->_priceSet['fields']);
6a488035 908 $form->_quickConfig = $quickConfig = 0;
9da8dc8c 909 if (CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'is_quick_config')) {
6a488035
TO
910 $quickConfig = 1;
911 }
912
913 $form->assign('quickConfig', $quickConfig);
914 if ($className == 'CRM_Contribute_Form_Contribution_Main') {
915 $form->_quickConfig = $quickConfig;
916 }
917 $form->assign('priceSet', $form->_priceSet);
918
919 $component = 'contribution';
920 if ($className == 'CRM_Member_Form_Membership') {
921 $component = 'membership';
922 }
923
924 if ($className == 'CRM_Contribute_Form_Contribution_Main') {
925 $feeBlock = &$form->_values['fee'];
926 if (!empty($form->_useForMember)) {
927 $component = 'membership';
928 }
929 }
930 else {
931 $feeBlock = &$form->_priceSet['fields'];
932 }
933
934 // call the hook.
935 CRM_Utils_Hook::buildAmount($component, $form, $feeBlock);
936
c7b3d063
DG
937 // CRM-14492 Admin price fields should show up on event registration if user has 'administer CiviCRM' permissions
938 $adminFieldVisible = false;
939 if (CRM_Core_Permission::check('administer CiviCRM')) {
77b97be7 940 $adminFieldVisible = true;
c7b3d063 941 }
77b97be7 942
883e4763 943 foreach ($feeBlock as $id => $field) {
6a488035 944 if (CRM_Utils_Array::value('visibility', $field) == 'public' ||
c7b3d063 945 (CRM_Utils_Array::value('visibility', $field) == 'admin' && $adminFieldVisible == true) ||
6a488035
TO
946 !$validFieldsOnly
947 ) {
948 $options = CRM_Utils_Array::value('options', $field);
949 if ($className == 'CRM_Contribute_Form_Contribution_Main' && $component = 'membership') {
cc509891 950 $userid = $form->getVar('_membershipContactID');
6a488035
TO
951 $checklifetime = self::checkCurrentMembership($options, $userid);
952 if ($checklifetime) {
953 $form->assign('ispricelifetime', TRUE);
954 }
955 }
883e4763 956 if (!is_array($options) || !in_array($id, $validPriceFieldIds)) {
6a488035
TO
957 continue;
958 }
9da8dc8c 959 CRM_Price_BAO_PriceField::addQuickFormElement($form,
6a488035
TO
960 'price_' . $field['id'],
961 $field['id'],
962 FALSE,
963 CRM_Utils_Array::value('is_required', $field, FALSE),
964 NULL,
965 $options
966 );
967 }
968 }
969 }
970
971 /**
100fef9d 972 * Check the current Membership
6a488035
TO
973 * having end date null.
974 */
975 static function checkCurrentMembership(&$options, $userid) {
976 if (!$userid || empty($options)) {
977 return;
978 }
979 static $_contact_memberships = array();
980 $checklifetime = FALSE;
981 foreach ($options as $key => $value) {
a7488080 982 if (!empty($value['membership_type_id'])) {
6a488035
TO
983 if (!isset($_contact_memberships[$userid][$value['membership_type_id']])) {
984 $_contact_memberships[$userid][$value['membership_type_id']] = CRM_Member_BAO_Membership::getContactMembership($userid, $value['membership_type_id'], FALSE);
985 }
986 $currentMembership = $_contact_memberships[$userid][$value['membership_type_id']];
8cc574cf 987 if (!empty($currentMembership) && empty($currentMembership['end_date'])) {
6a488035
TO
988 unset($options[$key]);
989 $checklifetime = TRUE;
990 }
991 }
992 }
993 if ($checklifetime) {
994 return TRUE;
995 }
996 else {
997 return FALSE;
998 }
999 }
1000
1001 /**
100fef9d 1002 * Set daefult the price set fields.
6a488035 1003 *
c490a46a 1004 * @param CRM_Core_Form $form
fd31fa4c
EM
1005 * @param $defaults
1006 *
6a488035
TO
1007 * @return array $defaults
1008 * @access public
1009 */
1010 static function setDefaultPriceSet(&$form, &$defaults) {
1011 if (!isset($form->_priceSet) || empty($form->_priceSet['fields'])) {
1012 return $defaults;
1013 }
1014
1015 foreach ($form->_priceSet['fields'] as $key => $val) {
1016 foreach ($val['options'] as $keys => $values) {
1017 if ($values['is_default']) {
1018 if ($val['html_type'] == 'CheckBox') {
1019 $defaults["price_{$key}"][$keys] = 1;
1020 }
1021 else {
1022 $defaults["price_{$key}"] = $keys;
1023 }
1024 }
1025 }
1026 }
1027 return $defaults;
1028 }
1029
b2cdd843
EM
1030 /**
1031 * Supports event create function by setting up required price sets, not tested but expect
1032 * it will work for contribution page
1033 * @param array $params as passed to api/bao create fn
1034 * @param CRM_Core_DAO $entity object for given entity
1035 * @param string $entityName name of entity - e.g event
1036 */
1037 static function setPriceSets(&$params, $entity, $entityName) {
1038 if(empty($params['price_set_id']) || !is_array($params['price_set_id'])) {
1039 return;
1040 }
1041 // CRM-14069 note that we may as well start by assuming more than one.
1042 // currently the form does not pass in as an array & will be skipped
1043 // test is passing in as an array but I feel the api should have a metadata that allows
1044 // transform of single to array - seems good for managing transitions - in which case all api
1045 // calls that set price_set_id will hit this
1046 // e.g in getfields 'price_set_id' => array('blah', 'bao_type' => 'array') - causing
1047 // all separated values, strings, json half-separated values (in participant we hit this)
1048 // to be converted to json @ api layer
1049 $pse = new CRM_Price_DAO_PriceSetEntity();
1050 $pse->entity_table = 'civicrm_' . $entityName;
1051 $pse->entity_id = $entity->id;
1052 while ($pse->fetch()) {
1053 if(!in_array($pse->price_set_id, $params['price_set_id'])) {
1054 // note an even more aggressive form of this deletion currently happens in event form
1055 // past price sets discounts are made inaccessible by this as the discount_id is set to NULL
1056 // on the participant record
1057 if (CRM_Price_BAO_PriceSet::removeFrom('civicrm_' . $entityName, $entity->id)) {
07102c2c 1058 CRM_Core_BAO_Discount::del($entity->id,'civicrm_' . $entityName);
b2cdd843
EM
1059 }
1060 }
1061 }
1062 foreach ($params['price_set_id'] as $priceSetID) {
1063 CRM_Price_BAO_PriceSet::addTo('civicrm_' . $entityName, $entity->id, $priceSetID);
1064 //@todo - how should we do this - copied from form
1065 //if (CRM_Utils_Array::value('price_field_id', $params)) {
1066 // $priceSetID = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $params['price_field_id'], 'price_set_id');
1067 // CRM_Price_BAO_PriceSet::setIsQuickConfig($priceSetID, 0);
1068 //}
1069 }
1070 }
6a488035
TO
1071 /**
1072 * Get field ids of a price set
1073 *
e0c1764e 1074 * @param int $id Price Set id
6a488035
TO
1075 *
1076 * @return array of the field ids
1077 *
1078 * @access public
1079 * @static
1080 */
1081 public static function getFieldIds($id) {
9da8dc8c 1082 $priceField = new CRM_Price_DAO_PriceField();
6a488035
TO
1083 $priceField->price_set_id = $id;
1084 $priceField->find();
1085 while ($priceField->fetch()) {
1086 $var[] = $priceField->id;
1087 }
1088 return $var;
1089 }
1090
1091 /**
1092 * This function is to make a copy of a price set, including
1093 * all the fields
1094 *
1095 * @param int $id the price set id to copy
1096 *
1097 * @return the copy object
1098 * @access public
1099 * @static
1100 */
1101 static function copy($id) {
1102 $maxId = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_price_set");
1103
1104 $title = ts('[Copy id %1]', array(1 => $maxId + 1));
1105 $fieldsFix = array(
1106 'suffix' => array('title' => ' ' . $title,
1107 'name' => '__Copy_id_' . ($maxId + 1) . '_',
1108 ),
1109 );
1110
9da8dc8c 1111 $copy = &CRM_Core_DAO::copyGeneric('CRM_Price_DAO_PriceSet',
6a488035
TO
1112 array('id' => $id),
1113 NULL,
1114 $fieldsFix
1115 );
1116
1117 //copying all the blocks pertaining to the price set
9da8dc8c 1118 $copyPriceField = &CRM_Core_DAO::copyGeneric('CRM_Price_DAO_PriceField',
6a488035
TO
1119 array('price_set_id' => $id),
1120 array('price_set_id' => $copy->id)
1121 );
1122 if (!empty($copyPriceField)) {
1123 $price = array_combine(self::getFieldIds($id), self::getFieldIds($copy->id));
1124
1125 //copy option group and values
1126 foreach ($price as $originalId => $copyId) {
9da8dc8c 1127 CRM_Core_DAO::copyGeneric('CRM_Price_DAO_PriceFieldValue',
6a488035
TO
1128 array('price_field_id' => $originalId),
1129 array('price_field_id' => $copyId)
1130 );
1131 }
1132 }
1133 $copy->save();
1134
1135 CRM_Utils_Hook::copy('Set', $copy);
1136 return $copy;
1137 }
1138
1139 /**
1140 * This function is to check price set permission
1141 *
1142 * @param int $sid the price set id
77b97be7
EM
1143 *
1144 * @return bool
6a488035 1145 */
44c8822b
DL
1146 static function checkPermission($sid) {
1147 if ($sid && self::eventPriceSetDomainID()) {
9da8dc8c 1148 $domain_id = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $sid, 'domain_id', 'id');
6a488035 1149 if (CRM_Core_Config::domainID() != $domain_id) {
0499b0ad 1150 CRM_Core_Error::fatal(ts('You do not have permission to access this page.'));
6a488035
TO
1151 }
1152 }
1153 return TRUE;
1154 }
1155
1156 /**
1157 * Get the sum of participant count
1158 * for all fields of given price set.
1159 *
1160 * @param int $sid the price set id
1161 *
77b97be7
EM
1162 * @param bool $onlyActive
1163 *
1164 * @return int|null|string
6a488035
TO
1165 * @access public
1166 * @static
1167 */
1168 public static function getPricesetCount($sid, $onlyActive = TRUE) {
1169 $count = 0;
1170 if (!$sid) {
1171 return $count;
1172 }
1173
1174 $where = NULL;
1175 if ($onlyActive) {
1176 $where = 'AND value.is_active = 1 AND field.is_active = 1';
1177 }
1178
1179 static $pricesetFieldCount = array();
1180 if (!isset($pricesetFieldCount[$sid])) {
1181 $sql = "
1182 SELECT sum(value.count) as totalCount
1183 FROM civicrm_price_field_value value
1184INNER JOIN civicrm_price_field field ON ( field.id = value.price_field_id )
1185INNER JOIN civicrm_price_set pset ON ( pset.id = field.price_set_id )
1186 WHERE pset.id = %1
1187 $where";
1188
1189 $count = CRM_Core_DAO::singleValueQuery($sql, array(1 => array($sid, 'Positive')));
1190 $pricesetFieldCount[$sid] = ($count) ? $count : 0;
1191 }
1192
1193 return $pricesetFieldCount[$sid];
1194 }
1195
ffd93213
EM
1196 /**
1197 * @param $ids
1198 *
1199 * @return array
1200 */
6a488035
TO
1201 public static function getMembershipCount($ids) {
1202 $queryString = "
1203SELECT count( pfv.id ) AS count, pfv.id AS id
1204FROM civicrm_price_field_value pfv
1205INNER JOIN civicrm_membership_type mt ON mt.id = pfv.membership_type_id
1206WHERE pfv.id IN ( $ids )
1207GROUP BY mt.member_of_contact_id";
1208
1209 $crmDAO = CRM_Core_DAO::executeQuery($queryString);
1210 $count = array();
1211
1212 while ($crmDAO->fetch()) {
1213 $count[$crmDAO->id] = $crmDAO->count;
1214 }
1215
1216 return $count;
1217 }
1218
1219 /**
100fef9d 1220 * Check if auto renew option should be shown
6a488035
TO
1221 *
1222 * @param int $priceSetId price set id
1223 *
1224 * @return int $autoRenewOption ( 0:hide, 1:optional 2:required )
1225 */
1226 public static function checkAutoRenewForPriceSet($priceSetId) {
1227 // auto-renew option should be visible if membership types associated with all the fields has
1228 // been set for auto-renew option
1229 // Auto renew checkbox should be frozen if for all the membership type auto renew is required
1230
1231 // get the membership type auto renew option and check if required or optional
1232 $query = 'SELECT mt.auto_renew, mt.duration_interval, mt.duration_unit
1233 FROM civicrm_price_field_value pfv
1234 INNER JOIN civicrm_membership_type mt ON pfv.membership_type_id = mt.id
1235 INNER JOIN civicrm_price_field pf ON pfv.price_field_id = pf.id
1236 WHERE pf.price_set_id = %1
1237 AND pf.is_active = 1
1238 AND pfv.is_active = 1';
1239
1240 $params = array(1 => array($priceSetId, 'Integer'));
1241
1242 $dao = CRM_Core_DAO::executeQuery($query, $params);
1243 $autoRenewOption = 2;
1244 $interval = $unit = array();
1245 while ($dao->fetch()) {
1246 if (!$dao->auto_renew) {
1247 $autoRenewOption = 0;
1248 break;
1249 }
1250 if ($dao->auto_renew == 1) {
1251 $autoRenewOption = 1;
1252 }
1253
1254 $interval[$dao->duration_interval] = $dao->duration_interval;
1255 $unit[$dao->duration_unit] = $dao->duration_unit;
1256 }
1257
1258 if (count($interval) == 1 && count($unit) == 1 && $autoRenewOption > 0) {
1259 return $autoRenewOption;
1260 }
1261 else {
1262 return 0;
1263 }
1264 }
1265
1266 /**
100fef9d 1267 * Retrieve auto renew frequency and interval
6a488035
TO
1268 *
1269 * @param int $priceSetId price set id
1270 *
1271 * @return array associate array of frequency interval and unit
1272 * @static
1273 * @access public
1274 */
1275 public static function getRecurDetails($priceSetId) {
1276 $query = 'SELECT mt.duration_interval, mt.duration_unit
1277 FROM civicrm_price_field_value pfv
1278 INNER JOIN civicrm_membership_type mt ON pfv.membership_type_id = mt.id
1279 INNER JOIN civicrm_price_field pf ON pfv.price_field_id = pf.id
1280 WHERE pf.price_set_id = %1 LIMIT 1';
1281
1282 $params = array(1 => array($priceSetId, 'Integer'));
1283 $dao = CRM_Core_DAO::executeQuery($query, $params);
1284 $dao->fetch();
1285 return array($dao->duration_interval, $dao->duration_unit);
1286 }
1287
ffd93213
EM
1288 /**
1289 * @return object
1290 */
6a488035
TO
1291 static function eventPriceSetDomainID() {
1292 return CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MULTISITE_PREFERENCES_NAME,
1293 'event_price_set_domain_id',
1294 NULL, FALSE
1295 );
1296 }
1297
1298 /**
100fef9d 1299 * Update the is_quick_config flag in the db
6a488035
TO
1300 *
1301 * @param int $id id of the database record
1302 * @param boolean $isQuickConfig value we want to set the is_quick_config field
1303 *
1304 * @return Object DAO object on sucess, null otherwise
1305 * @static
1306 * @access public
1307 */
1308 static function setIsQuickConfig($id, $isQuickConfig) {
9da8dc8c 1309 return CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceSet', $id, 'is_quick_config', $isQuickConfig);
6a488035
TO
1310 }
1311
1312 /**
cde484fd 1313 * Check if price set id provides option for
6a488035
TO
1314 * user to select both auto-renew and non-auto-renew memberships
1315 *
cde484fd 1316 * @access public
6a488035
TO
1317 * @static
1318 *
1319 */
1320 public static function checkMembershipPriceSet($id) {
cde484fd 1321 $query =
6a488035
TO
1322"
1323SELECT pfv.id, pfv.price_field_id, pfv.name, pfv.membership_type_id, pf.html_type, mt.auto_renew
1324FROM civicrm_price_field_value pfv
1325LEFT JOIN civicrm_price_field pf ON pf.id = pfv.price_field_id
1326LEFT JOIN civicrm_price_set ps ON ps.id = pf.price_set_id
1327LEFT JOIN civicrm_membership_type mt ON mt.id = pfv.membership_type_id
1328WHERE ps.id = %1
1329";
1330
1331 $params = array(1 => array($id, 'Integer'));
1332 $dao = CRM_Core_DAO::executeQuery($query, $params);
1333
1334 $autoRenew = array();
1335 //FIXME: do a comprehensive check of whether
1336 //2 membership types can be selected
1337 //instead of comparing all of them
1338 while ($dao->fetch()) {
cde484fd 1339 //temp fix for #CRM-10370
6a488035
TO
1340 //if its NULL consider it '0' i.e. 'No auto-renew option'
1341 $daoAutoRenew = $dao->auto_renew;
1342 if ($daoAutoRenew === NULL) {
1343 $daoAutoRenew = 0;
1344 }
1345 if (!empty($autoRenew) && !in_array($daoAutoRenew, $autoRenew)) {
1346 return true;
1347 }
1348 $autoRenew[] = $daoAutoRenew;
1349 }
1350 return false;
1351 }
1352
e0c1764e 1353 /**
c6914066
PN
1354 * Copy priceSet when event/contibution page is copied
1355 *
c490a46a
CW
1356 * @param string $baoName BAO name
1357 * @param int $id old event/contribution page id
1358 * @param int $newId newly created event/contribution page id
c6914066
PN
1359 */
1360 static function copyPriceSet($baoName, $id, $newId) {
9da8dc8c 1361 $priceSetId = CRM_Price_BAO_PriceSet::getFor($baoName, $id);
c6914066 1362 if ($priceSetId) {
9da8dc8c 1363 $isQuickConfig = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'is_quick_config');
c6914066 1364 if($isQuickConfig) {
9da8dc8c 1365 $copyPriceSet = &CRM_Price_BAO_PriceSet::copy($priceSetId);
1366 CRM_Price_BAO_PriceSet::addTo($baoName, $newId, $copyPriceSet->id);
44c8822b 1367 }
c6914066 1368 else {
9da8dc8c 1369 $copyPriceSet = &CRM_Core_DAO::copyGeneric('CRM_Price_DAO_PriceSetEntity',
c6914066
PN
1370 array(
1371 'entity_id' => $id,
1372 'entity_table' => $baoName,
1373 ),
1374 array('entity_id' => $newId)
1375 );
1376 }
1377 // copy event discount
1378 if ($baoName == 'civicrm_event') {
1379 $discount = CRM_Core_BAO_Discount::getOptionGroup($id, 'civicrm_event');
1380 foreach ($discount as $discountId => $setId) {
1381
9da8dc8c 1382 $copyPriceSet = &CRM_Price_BAO_PriceSet::copy($setId);
44c8822b 1383
28156120 1384 CRM_Core_DAO::copyGeneric(
c6914066
PN
1385 'CRM_Core_DAO_Discount',
1386 array(
1387 'id' => $discountId,
1388 ),
1389 array(
1390 'entity_id' => $newId,
1391 'price_set_id' => $copyPriceSet->id,
1392 )
1393 );
1394 }
1395 }
1396 }
1397 }
dc428161 1398
1399 /*
1400 * Function to set tax_amount and tax_rate in LineItem
1401 *
1402 *
1403 */
1404 static function setLineItem($field, $lineItem, $optionValueId) {
1405 if ($field['html_type'] == 'Text') {
1406 $taxAmount = $field['options'][$optionValueId]['tax_amount'] * $lineItem[$optionValueId]['qty'];
1407 }
1408 else {
1409 $taxAmount = $field['options'][$optionValueId]['tax_amount'];
1410 }
1411 $taxRate = $field['options'][$optionValueId]['tax_rate'];
dc428161 1412 $lineItem[$optionValueId]['tax_amount'] = $taxAmount;
1413 $lineItem[$optionValueId]['tax_rate'] = $taxRate;
1414
1415 return $lineItem;
1416 }
6a488035
TO
1417}
1418