Commit 20705f36 authored by Eileen McNaughton's avatar Eileen McNaughton
Browse files

towards adding event_type_id filter

parent 420239cd
......@@ -67,6 +67,7 @@ class CRM_CiviDiscount_BAO_Item extends CRM_CiviDiscount_DAO_Item {
$item->amount_type = $params['amount_type'];
$item->count_max = $params['count_max'];
$item->discount_msg = $params['discount_msg'];
$item->filters = json_encode($params['filters']);
foreach ($params['multi_valued'] as $mv => $dontCare) {
if (!empty($params[$mv])) {
......@@ -160,26 +161,42 @@ SELECT id,
discount_msg_enabled,
discount_msg,
count_use,
count_max
count_max,
filters
FROM cividiscount_item
";
$dao =& CRM_Core_DAO::executeQuery($sql, array());
$dao = CRM_Core_DAO::executeQuery($sql, array());
while ($dao->fetch()) {
$a = (array) $dao;
if (CRM_CiviDiscount_BAO_Item::isValid($a)) {
$discounts[$a['code']] = $a;
}
}
$filters = json_decode($dao->filters, TRUE);
// Expand set-valued fields.
$fields = array('events', 'pricesets', 'memberships', 'autodiscount');
$fields = array('events' => 'event', 'pricesets' => 'price_set', 'memberships' => 'membership', 'autodiscount' => NULL);
foreach ($discounts as &$discount) {
foreach ($fields as $field) {
$items = array_filter(explode(CRM_Core_DAO::VALUE_SEPARATOR, $discount[$field]));
foreach ($fields as $field => $entity) {
if(is_null($discount[$field])) {
$items = array();
}
else {
$items = explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($discount[$field], CRM_Core_DAO::VALUE_SEPARATOR));
}
if(!empty($items) && $entity) {
if(!isset($filters[$entity])) {
$filters[$entity] = array();
}
//0 indicates 'any' so for 0 we construct an empty filter - otherwise we add a limit by id clause
//note that this may be combined with stored filters e.g. 'event_type_id'
if(!in_array(0, $items)) {
$filters[$entity]['id'] = array('IN' => $items);
}
}
$discount[$field] = !empty($items) ? array_combine($items, $items) : array();
}
}
$discount['filters'] = empty($filters) ? array() : $filters;
return $discounts;
}
......
......@@ -31,8 +31,7 @@
* $Id$
*
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
class CRM_CiviDiscount_DAO_Item extends CRM_Core_DAO {
/**
* static instance to hold the table name
......@@ -97,6 +96,12 @@ class CRM_CiviDiscount_DAO_Item extends CRM_Core_DAO {
* @var string
*/
public $description;
/**
* Discount Filters.
*
* @var string
*/
public $filters;
/**
* Amount of discount either actual or percentage?
*
......@@ -234,6 +239,14 @@ class CRM_CiviDiscount_DAO_Item extends CRM_Core_DAO {
'maxlength' => 255,
'size' => CRM_Utils_Type::HUGE,
),
'filters' => array(
'name' => 'filters',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Discount Filters'),
'required' => false,
'maxlength' => 255,
'size' => CRM_Utils_Type::HUGE,
),
'amount' => array(
'name' => 'amount',
'type' => CRM_Utils_Type::T_STRING,
......
......@@ -34,8 +34,6 @@
*
*/
require_once 'CRM/Admin/Form.php';
require_once 'CRM/CiviDiscount/BAO/Item.php';
/**
* This class generates form components for cividiscount administration.
......@@ -100,7 +98,7 @@ class CRM_CiviDiscount_Form_Admin extends CRM_Admin_Form {
// assign the defaults to smarty so delete can use it
$this->assign('discountValue', $defaults);
$this->applyFilterDefaults($defaults);
foreach ($this->_multiValued as $mv => $info) {
if (! empty($defaults[$mv])) {
$v = substr($defaults[$mv], 1, -1);
......@@ -220,6 +218,7 @@ class CRM_CiviDiscount_Form_Admin extends CRM_Admin_Form {
$events = CRM_CiviDiscount_Utils::getEvents();
if (! empty($events)) {
$events['0'] = ts('any event');
$this->_multiValued['events'] = $events;
$this->addElement('advmultiselect',
'events',
......@@ -229,6 +228,18 @@ class CRM_CiviDiscount_Form_Admin extends CRM_Admin_Form {
'style' => 'width:auto; min-width:150px;',
'class' => 'advmultiselect')
);
$eventTypes = civicrm_api3('event', 'getoptions', array('field' => 'event_type_id'));
$eventTypes = $eventTypes['values'];
$this->_multiValued['eventtypes'] = $eventTypes;
$this->addElement('advmultiselect',
'event_type_id',
ts('Event Types'),
$eventTypes,
array('size' => 5,
'style' => 'width:auto; min-width:150px;',
'class' => 'advmultiselect')
);
}
$pricesets = CRM_CiviDiscount_Utils::getPriceSets();
......@@ -273,10 +284,81 @@ class CRM_CiviDiscount_Form_Admin extends CRM_Admin_Form {
}
$params['multi_valued'] = $this->_multiValued;
if(in_array(0, $params['events']) && count($params['events']) > 1) {
CRM_Core_Session::setStatus(ts('You selected `any event` and specific events, specific events have been unset'));
$params['events'] = array(0);
}
$params['filters'] = $this->getFiltersFromParams($params);
$item = CRM_CiviDiscount_BAO_Item::add($params);
CRM_Core_Session::setStatus(ts('The discount \'%1\' has been saved.',
array(1 => $item->description ? $item->description : $item->code)));
}
/**
* Convert from params to values to be stored in the filter
* @param array $params parameters submitted to form
* @return array filters to be stored in DB
*/
function getFiltersFromParams($params) {
$filters = array();
foreach ($this->getSupportedFilters() as $entity => $fields) {
foreach ($fields as $field => $spec) {
$fieldName = $spec['form_field_name'];
if(!empty($params[$fieldName])) {
if(empty($spec['operator'])) {
$filters[$entity][$field] = $params[$fieldName];
}
else {
$filters[$entity][$field] = array($spec['operator'] => $params[$fieldName]);
}
}
}
}
return $filters;
}
/**
* Convert from params to values to be stored in the filter
* @param array $params parameters submitted to form
* @return array filters to be stored in DB
*/
function applyFilterDefaults(&$defaults) {
$filters = json_decode($defaults['filters'], TRUE);
foreach ($this->getSupportedFilters() as $entity => $fields) {
foreach ($fields as $field => $spec) {
$fieldName = $spec['form_field_name'];
if(empty($spec['operator'])) {
$defaults[$fieldName] = $filters[$entity][$field];
}
else {
$defaults[$fieldName] = $filters[$entity][$field][$spec['operator']];
}
}
}
return $filters;
}
/**
* Here we define filter extensions to be stored in the filters field in the DB
* Later we will figure out how to make this hookable so that discounts can be extended
* The format is
* array(
* 'entity' => array(
* 'field1' => array('form_field_name' => field1),
* 'field2' => array('form_field_name' => field2),
* )
* where both the entity & the field names should be valid for api calls.
* The form field name is the name of the field on the form - we set it in case we get a conflict
* - eg. multiple entities have 'status_id'
* @return array supported filters
*/
function getSupportedFilters() {
return array('event' => array(
'event_type_id' => array(
'form_field_name' => 'event_type_id',
'operator' => 'IN',
))
);
}
}
......@@ -17,4 +17,9 @@ class CRM_CiviDiscount_Upgrader extends CRM_CiviDiscount_Upgrader_Base {
CRM_Core_DAO::executeQuery('ALTER TABLE cividiscount_item ADD COLUMN discount_msg VARCHAR(255) AFTER discount_msg_enabled');
return TRUE;
}
public function upgrade_2202() {
$this->ctx->log->info('Applying update 2202');
CRM_Core_DAO::executeQuery('ALTER TABLE cividiscount_item ADD COLUMN filters VARCHAR(255) AFTER discount_msg');
return TRUE;
}
}
......@@ -348,7 +348,7 @@ function cividiscount_civicrm_buildAmount($pagetype, &$form, &$amounts) {
}
if ($pagetype == 'event') {
$discounts = _cividiscount_filter_discounts($discounts, 'events', $eid);
$discounts = _cividiscount_filter_discounts($discounts, 'event', $eid);
}
else if ($pagetype == 'membership') {
if (!in_array(get_class($form), array(
......@@ -808,14 +808,46 @@ function _cividiscount_get_candidate_discounts($code, $contact_id) {
}
/**
* Filter out discounts that don't offer a discount to the specified $id in the
* category $field.
* Filter out discounts that are not applicable based on id or other filters
* @param array $discounts discount array from db
* @param string $entity - this should match the api entity
* @param integer $id entity id
*/
function _cividiscount_filter_discounts($discounts, $field, $id) {
return array_filter(
$discounts,
function($discount) use($field, $id) { return CRM_Utils_Array::value($id, $discount[$field]); }
function _cividiscount_filter_discounts($discounts, $entity, $id) {
foreach ($discounts as $discount_id => $discount) {
if(!_cividiscount_discount_applicable($discount, $entity, $id)) {
unset($discounts[$discount_id]);
}
}
return $discounts;
}
/**
* Check if discount is applicable - we check the 'filters' to see if
* 1) there are any filters for this entity type - no filter means NO
* 2) there is an empty filter for this entity type - means 'any'
* 3) the only filter is on id (in which case we will do a direct comparison
* 4) there is an api filter
*
* @param array $discounts discount array from db
* @param string $field - this should match the api entity
* @param integer $id entity id
*/
function _cividiscount_discount_applicable($discount, $entity, $id) {
if(!isset($discount['filters'][$entity])) {
return FALSE;
}
if(empty($discount['filters'][$entity])) {
return TRUE;
}
if(array_keys($discount['filters'][$entity]) == array('id')) {
return in_array($id, $discount['filters'][$entity]['id']);
}
$ids = civicrm_api3($entity, 'get', $discount['filters'][$entity] + array(
'options' => array('limit' => 999999999), 'return' => 'id')
);
return in_array($id, array_keys($ids['values']));
}
/**
......
......@@ -103,12 +103,15 @@
{if $form.events}
<tr class="crm-discount-item-form-block-events">
<td class="label">{$form.events.label} {help id="events" title=$form.events.label}</td>
<td>{$form.events.html}<br/>
{if $form.pricesets}
<span
class="description"><strong><em>{ts}If you use price sets for your events, you also need to select any discountable price sets below.{/ts}</em></strong>
</span>
{/if}
<td>{$form.events.html}<td>
</tr>
<tr class="crm-discount-item-form-block-event-types">
<td class="label">{$form.event_type_id.label} {help id="eventtypes" title=$form.eventstypes.label}</td>
<td>{$form.event_type_id.html}</td>
</tr>
<tr>
<td colspan=2>
<strong><em>{ts}If you use price sets for your events, you also need to select any discountable price sets below.{/ts}</em></strong>
</td>
</tr>
{/if}
......
......@@ -119,4 +119,11 @@
<comment>Is this discount active?</comment>
<add>4.1</add>
</field>
<field>
<name>filters</name>
<type>string</type>
<title>Discount Filters</title>
<comment>What filters apply to this discount (json array)</comment>
<add>2.6</add>
</field>
</table>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment