/** * Takes an associative array and creates a price set object. * * @param array $params * (reference) an assoc array of name/value pairs. * * @return CRM_Price_DAO_PriceSet */ public static function create(&$params) { if (empty($params['id']) && empty($params['name'])) { $params['name'] = CRM_Utils_String::munge($params['title'], '_', 242); } $priceSetID = NULL; $validatePriceSet = TRUE; if (!empty($params['extends']) && is_array($params['extends'])) { if (!array_key_exists(CRM_Core_Component::getComponentID('CiviEvent'), $params['extends']) || !array_key_exists(CRM_Core_Component::getComponentID('CiviMember'), $params['extends'])) { $validatePriceSet = FALSE; } $params['extends'] = CRM_Utils_Array::implodePadded($params['extends']); } else { $priceSetID = CRM_Utils_Array::value('id', $params); } // CRM-16189 if ($validatePriceSet && !empty($params['financial_type_id'])) { CRM_Financial_BAO_FinancialAccount::validateFinancialType($params['financial_type_id'], $priceSetID); } $priceSetBAO = new CRM_Price_BAO_PriceSet(); $priceSetBAO->copyValues($params); if (self::eventPriceSetDomainID()) { $priceSetBAO->domain_id = CRM_Core_Config::domainID(); } return $priceSetBAO->save(); }
/** * Global validation rules for the form. * * @param array $fields * Posted values of the form. * * @param $files * @param CRM_Core_Form $form * * @return array * if errors then list of errors to be posted back to the form, * true otherwise */ public static function formRule($fields, $files, $form) { $errors = array(); if (!empty($fields['count']) && !empty($fields['max_value']) && $fields['count'] > $fields['max_value']) { $errors['count'] = ts('Participant count can not be greater than max participants.'); } // CRM-16189 try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($fields['financial_type_id'], $form->_fid, 'PriceField'); } catch (CRM_Core_Exception $e) { $errors['financial_type_id'] = $e->getMessage(); } return empty($errors) ? TRUE : $errors; }
/** * Global validation rules for the form. * * @param array $values * Posted values of the form. * * @return array * list of errors to be posted back to the form */ public static function formRule($values) { $errors = array(); if (!empty($values['is_discount'])) { $occurDiscount = array_count_values($values['discount_name']); $countemptyrows = 0; $countemptyvalue = 0; for ($i = 1; $i <= self::NUM_DISCOUNT; $i++) { $start_date = $end_date = NULL; if (!empty($values['discount_name'][$i])) { if (!empty($values['discount_start_date'][$i])) { $start_date = $values['discount_start_date'][$i] ? CRM_Utils_Date::processDate($values['discount_start_date'][$i]) : 0; } if (!empty($values['discount_end_date'][$i])) { $end_date = $values['discount_end_date'][$i] ? CRM_Utils_Date::processDate($values['discount_end_date'][$i]) : 0; } if ($start_date && $end_date && strcmp($end_date, $start_date) < 0) { $errors["discount_end_date[{$i}]"] = ts('The discount end date cannot be prior to the start date.'); } if (!$start_date && !$end_date) { $errors["discount_start_date[{$i}]"] = $errors["discount_end_date[{$i}]"] = ts('Please specify either start date or end date.'); } if ($i > 1) { $end_date_1 = $values['discount_end_date'][$i - 1] ? CRM_Utils_Date::processDate($values['discount_end_date'][$i - 1]) : 0; if ($start_date && $end_date_1 && strcmp($end_date_1, $start_date) >= 0) { $errors["discount_start_date[{$i}]"] = ts('Select non-overlapping discount start date.'); } elseif (!$start_date && !$end_date_1) { $j = $i - 1; $errors["discount_start_date[{$i}]"] = $errors["discount_end_date[{$j}]"] = ts('Select either of the dates.'); } } foreach ($occurDiscount as $key => $value) { if ($value > 1 && $key != '') { if ($key == $values['discount_name'][$i]) { $errors['discount_name[' . $i . ']'] = ts('%1 is already used for Discount Name.', array(1 => $key)); } } } //validation for discount labels and values for ($index = self::NUM_OPTION; $index > 0; $index--) { $label = TRUE; if (empty($values['discounted_label'][$index]) && !empty($values['discounted_value'][$index][$i])) { $label = FALSE; if (!$label) { $errors["discounted_label[{$index}]"] = ts('Label cannot be empty.'); } } if (!empty($values['discounted_label'][$index])) { $duplicateIndex = CRM_Utils_Array::key($values['discounted_label'][$index], $values['discounted_label']); if (!($duplicateIndex === FALSE) && !($duplicateIndex == $index)) { $errors["discounted_label[{$index}]"] = ts('Duplicate label value'); } } if (empty($values['discounted_label'][$index]) && empty($values['discounted_value'][$index][$i])) { $countemptyrows++; } if (empty($values['discounted_value'][$index][$i])) { $countemptyvalue++; } } if (!empty($values['_qf_Fee_next']) && ($countemptyrows == 11 || $countemptyvalue == 11)) { $errors["discounted_label[1]"] = $errors["discounted_value[1][{$i}]"] = ts('At least one fee should be entered for your Discount Set. If you do not see the table to enter discount fees, click the "Add Discount Set to Fee Table" button.'); } } } } if ($values['is_monetary']) { //check if financial type is selected if (!$values['financial_type_id']) { $errors['financial_type_id'] = ts("Please select financial type."); } //check for the event fee label (mandatory) if (!$values['fee_label']) { $errors['fee_label'] = ts('Please enter the fee label for the paid event.'); } if (empty($values['price_set_id'])) { //check fee label and amount $check = 0; $optionKeys = array(); foreach ($values['label'] as $key => $val) { if (trim($val) && trim($values['value'][$key])) { $optionKeys[$key] = $key; $check++; } } $default = CRM_Utils_Array::value('default', $values); if ($default && !in_array($default, $optionKeys)) { $errors['default'] = ts('Please select an appropriate option as default.'); } if (!$check) { if (!$values['label'][1]) { $errors['label[1]'] = ts('Please enter a label for at least one fee level.'); } if (!$values['value'][1]) { $errors['value[1]'] = ts('Please enter an amount for at least one fee level.'); } } } if (isset($values['is_pay_later'])) { if (empty($values['pay_later_text'])) { $errors['pay_later_text'] = ts('Please enter the Pay Later prompt to be displayed on the Registration form.'); } if (empty($values['pay_later_receipt'])) { $errors['pay_later_receipt'] = ts('Please enter the Pay Later instructions to be displayed to your users.'); } } } // CRM-16189 try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($values['financial_type_id']); } catch (CRM_Core_Exception $e) { $errors['financial_type_id'] = $e->getMessage(); } return empty($errors) ? TRUE : $errors; }
/** * Add the event. * * @param array $params * Reference array contains the values submitted by the form. * * @return CRM_Event_DAO_Event */ public static function add(&$params) { CRM_Utils_System::flushCache(); $financialTypeId = NULL; if (!empty($params['id'])) { CRM_Utils_Hook::pre('edit', 'Event', $params['id'], $params); if (empty($params['skipFinancialType'])) { $financialTypeId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $params['id'], 'financial_type_id'); } } else { CRM_Utils_Hook::pre('create', 'Event', NULL, $params); } // CRM-16189 if (!empty($params['financial_type_id'])) { CRM_Financial_BAO_FinancialAccount::validateFinancialType($params['financial_type_id']); } $event = new CRM_Event_DAO_Event(); $event->copyValues($params); $result = $event->save(); if (!empty($params['id'])) { CRM_Utils_Hook::post('edit', 'Event', $event->id, $event); } else { CRM_Utils_Hook::post('create', 'Event', $event->id, $event); } if ($financialTypeId && !empty($params['financial_type_id']) && $financialTypeId != $params['financial_type_id']) { CRM_Price_BAO_PriceFieldValue::updateFinancialType($params['id'], 'civicrm_event', $params['financial_type_id']); } return $result; }
/** * Test if financial type has Deferred Revenue Account is relationship with Financial Account. * */ public function testValidateFinancialType() { Civi::settings()->set('contribution_invoice_settings', array('deferred_revenue_enabled' => '1')); $financialTypes = CRM_Contribute_PseudoConstant::financialType(); foreach ($financialTypes as $key => $value) { try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($key); if (!in_array($value, array('Member Dues', 'Event Fee'))) { $this->fail("Missed expected exception"); } } catch (CRM_Core_Exception $e) { if (in_array($value, array('Member Dues', 'Event Fees'))) { $this->fail("Should not call exception"); } else { $this->assertEquals('Deferred revenue account is not configured for selected financial type. Please have an administrator set up the deferred revenue account at Administer > CiviContribute > Financial Accounts, then configure it for financial types at Administer > CiviContribution > Financial Types, Accounts', $e->getMessage()); } } } }
/** * Validation. * * @param array $params * (ref.) an assoc array of name/value pairs. * * @return bool|array * mixed true or array of errors */ public static function formRule($params) { $errors = array(); if (!$params['name']) { $errors['name'] = ts('Please enter a membership type name.'); } if ($params['minimum_fee'] > 0 && !$params['financial_type_id']) { $errors['financial_type_id'] = ts('Please enter the financial Type.'); } if (empty($params['duration_interval']) and $params['duration_unit'] != 'lifetime') { $errors['duration_interval'] = ts('Please enter a duration interval.'); } if (in_array(CRM_Utils_Array::value('auto_renew', $params), array(1, 2))) { if ($params['duration_interval'] > 1 && $params['duration_unit'] == 'year' || $params['duration_interval'] > 12 && $params['duration_unit'] == 'month') { $errors['duration_unit'] = ts('Automatic renewals are not supported by the currently available payment processors when the membership duration is greater than 1 year / 12 months.'); } } if ($params['period_type'] == 'fixed' && $params['duration_unit'] == 'day') { $errors['period_type'] = ts('Period type should be Rolling when duration unit is Day'); } if ($params['period_type'] == 'fixed' && $params['duration_unit'] == 'year') { $periods = array('fixed_period_start_day', 'fixed_period_rollover_day'); foreach ($periods as $period) { $month = $params[$period]['M']; $date = $params[$period]['d']; if (!$month || !$date) { switch ($period) { case 'fixed_period_start_day': $errors[$period] = ts('Please enter a valid fixed period start day'); break; case 'fixed_period_rollover_day': $errors[$period] = ts('Please enter a valid fixed period rollover day'); break; } } } } if ($params['fixed_period_start_day'] && !empty($params['fixed_period_start_day'])) { $params['fixed_period_start_day']['Y'] = date('Y'); if (!CRM_Utils_Rule::qfDate($params['fixed_period_start_day'])) { $errors['fixed_period_start_day'] = ts('Please enter valid Fixed Period Start Day'); } } if ($params['fixed_period_rollover_day'] && !empty($params['fixed_period_rollover_day'])) { $params['fixed_period_rollover_day']['Y'] = date('Y'); if (!CRM_Utils_Rule::qfDate($params['fixed_period_rollover_day'])) { $errors['fixed_period_rollover_day'] = ts('Please enter valid Fixed Period Rollover Day'); } } // CRM-16189 try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($params['financial_type_id']); } catch (CRM_Core_Exception $e) { $errors['financial_type_id'] = $e->getMessage(); } return empty($errors) ? TRUE : $errors; }
/** * Global validation rules for the form. * * @param array $fields * Posted values of the form. * * @param $files * @param CRM_Core_Form $form * * @return array * if errors then list of errors to be posted back to the form, * true otherwise */ public static function formRule($fields, $files, $form) { // all option fields are of type "money" $errors = array(); /** Check the option values entered * Appropriate values are required for the selected datatype * Incomplete row checking is also required. */ if (($form->_action & CRM_Core_Action::ADD || $form->_action & CRM_Core_Action::UPDATE) && $fields['html_type'] == 'Text') { if ($fields['price'] == NULL) { $errors['price'] = ts('Price is a required field'); } if ($fields['financial_type_id'] == '') { $errors['financial_type_id'] = ts('Financial Type is a required field'); } else { // CRM-16189 try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($fields['financial_type_id'], $form->_sid); } catch (CRM_Core_Exception $e) { $errors['financial_type_id'] = $e->getMessage(); } } } //avoid the same price field label in Within PriceSet $priceFieldLabel = new CRM_Price_DAO_PriceField(); $priceFieldLabel->label = $fields['label']; $priceFieldLabel->price_set_id = $form->_sid; $dupeLabel = FALSE; if ($priceFieldLabel->find(TRUE) && $form->_fid != $priceFieldLabel->id) { $dupeLabel = TRUE; } if ($dupeLabel) { $errors['label'] = ts('Name already exists in Database.'); } if (is_numeric(CRM_Utils_Array::value('count', $fields)) && CRM_Utils_Array::value('count', $fields) == 0 && CRM_Utils_Array::value('html_type', $fields) == 'Text') { $errors['count'] = ts('Participant Count must be greater than zero.'); } if ($form->_action & CRM_Core_Action::ADD) { if ($fields['html_type'] != 'Text') { $countemptyrows = 0; $_flagOption = $_rowError = 0; $_showHide = new CRM_Core_ShowHideBlocks('', ''); for ($index = 1; $index <= self::NUM_OPTION; $index++) { $noLabel = $noAmount = $noWeight = 1; if (!empty($fields['option_label'][$index])) { $noLabel = 0; $duplicateIndex = CRM_Utils_Array::key($fields['option_label'][$index], $fields['option_label']); if (!($duplicateIndex === FALSE) && !($duplicateIndex == $index)) { $errors["option_label[{$index}]"] = ts('Duplicate label value'); $_flagOption = 1; } } if ($form->_useForMember) { if (!empty($fields['membership_type_id'][$index])) { $memTypesIDS[] = $fields['membership_type_id'][$index]; } } // allow for 0 value. if (!empty($fields['option_amount'][$index]) || strlen($fields['option_amount'][$index]) > 0) { $noAmount = 0; } if (!empty($fields['option_weight'][$index])) { $noWeight = 0; $duplicateIndex = CRM_Utils_Array::key($fields['option_weight'][$index], $fields['option_weight']); if (!($duplicateIndex === FALSE) && !($duplicateIndex == $index)) { $errors["option_weight[{$index}]"] = ts('Duplicate weight value'); $_flagOption = 1; } } if (!$noLabel && !$noAmount && !empty($fields['option_financial_type_id']) && $fields['option_financial_type_id'][$index] == '' && $fields['html_type'] != 'Text') { $errors["option_financial_type_id[{$index}]"] = ts('Financial Type is a Required field.'); } if ($noLabel && !$noAmount) { $errors["option_label[{$index}]"] = ts('Label cannot be empty.'); $_flagOption = 1; } if (!$noLabel && $noAmount) { $errors["option_amount[{$index}]"] = ts('Amount cannot be empty.'); $_flagOption = 1; } if ($noLabel && $noAmount) { $countemptyrows++; $_emptyRow = 1; } elseif (!empty($fields['option_max_value'][$index]) && !empty($fields['option_count'][$index]) && $fields['option_count'][$index] > $fields['option_max_value'][$index]) { $errors["option_max_value[{$index}]"] = ts('Participant count can not be greater than max participants.'); $_flagOption = 1; } $showBlocks = 'optionField_' . $index; if ($_flagOption) { $_showHide->addShow($showBlocks); $_rowError = 1; } if (!empty($_emptyRow)) { $_showHide->addHide($showBlocks); } else { $_showHide->addShow($showBlocks); } if ($index == self::NUM_OPTION) { $hideBlock = 'additionalOption'; $_showHide->addHide($hideBlock); } $_flagOption = $_emptyRow = 0; // CRM-16189 try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($fields['option_financial_type_id'][$index], $form->_fid, 'PriceField'); } catch (CRM_Core_Exception $e) { $errors["option_financial_type_id[{$index}]"] = $e->getMessage(); } } if (!empty($memTypesIDS)) { // check for checkboxes allowing user to select multiple memberships from same membership organization if ($fields['html_type'] == 'CheckBox') { $foundDuplicate = FALSE; $orgIds = array(); foreach ($memTypesIDS as $key => $val) { $org = CRM_Member_BAO_MembershipType::getMembershipTypeOrganization($val); if (in_array($org[$val], $orgIds)) { $foundDuplicate = TRUE; break; } $orgIds[$val] = $org[$val]; } if ($foundDuplicate) { $errors['_qf_default'] = ts('You have selected multiple memberships for the same organization or entity. Please review your selections and choose only one membership per entity.'); } } // CRM-10390 - Only one price field in a set can include auto-renew membership options $foundAutorenew = FALSE; foreach ($memTypesIDS as $key => $val) { // see if any price field option values in this price field are for memberships with autorenew $memTypeDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($val); if (!empty($memTypeDetails['auto_renew'])) { $foundAutorenew = TRUE; break; } } if ($foundAutorenew) { // if so, check for other fields in this price set which also have auto-renew membership options $otherFieldAutorenew = CRM_Price_BAO_PriceSet::checkAutoRenewForPriceSet($form->_sid); if ($otherFieldAutorenew) { $errors['_qf_default'] = ts('You can include auto-renew membership choices for only one price field in a price set. Another field in this set already contains one or more auto-renew membership options.'); } } } $_showHide->addToTemplate(); if ($countemptyrows == 15) { $errors['option_label[1]'] = $errors['option_amount[1]'] = ts('Label and value cannot be empty.'); $_flagOption = 1; } } elseif (!empty($fields['max_value']) && !empty($fields['count']) && $fields['count'] > $fields['max_value']) { $errors['max_value'] = ts('Participant count can not be greater than max participants.'); } // do not process if no option rows were submitted if (empty($fields['option_amount']) && empty($fields['option_label'])) { return TRUE; } if (empty($fields['option_name'])) { $fields['option_amount'] = array(); } if (empty($fields['option_label'])) { $fields['option_label'] = array(); } } return empty($errors) ? TRUE : $errors; }
/** * Global form rule. * * @param array $fields * The input form values. * @param array $files * The uploaded files if any. * @param array $options * Additional user data. * * @return bool|array * true if no errors, else array of errors */ public static function formRule($fields, $files, $options) { $errors = array(); $count = count(CRM_Utils_Array::value('extends', $fields)); //price sets configured for membership if ($count && array_key_exists(CRM_Core_Component::getComponentID('CiviMember'), $fields['extends'])) { if ($count > 1) { $errors['extends'] = ts('If you plan on using this price set for membership signup and renewal, you can not also use it for Events or Contributions. However, a membership price set may include additional fields for non-membership options that require an additional fee (e.g. magazine subscription).'); } } //checks the given price set doesnot start with digit $title = $fields['title']; // gives the ascii value $asciiValue = ord($title[0]); if ($asciiValue >= 48 && $asciiValue <= 57) { $errors['title'] = ts("Name cannot not start with a digit"); } // CRM-16189 if (!empty($fields['extends']) && (array_key_exists(CRM_Core_Component::getComponentID('CiviEvent'), $fields['extends']) || array_key_exists(CRM_Core_Component::getComponentID('CiviMember'), $fields['extends']))) { try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($fields['financial_type_id']); } catch (CRM_Core_Exception $e) { $errors['financial_type_id'] = $e->getMessage(); } } return empty($errors) ? TRUE : $errors; }
/** * Add the membership types. * * @param array $params * Reference array contains the values submitted by the form. * @param array $ids * Array contains the id (deprecated). * * * @return object */ public static function add(&$params, $ids = array()) { $id = CRM_Utils_Array::value('id', $params, CRM_Utils_Array::value('membershipType', $ids)); if (!$id) { if (!isset($params['is_active'])) { // do we need this? $params['is_active'] = FALSE; } if (!isset($params['domain_id'])) { $params['domain_id'] = CRM_Core_Config::domainID(); } } // CRM-16189 if (!empty($params['financial_type_id'])) { CRM_Financial_BAO_FinancialAccount::validateFinancialType($params['financial_type_id']); } // action is taken depending upon the mode $membershipType = new CRM_Member_DAO_MembershipType(); $membershipType->copyValues($params); $membershipType->id = $id; // $previousID is the old organization id for membership type i.e 'member_of_contact_id'. This is used when an organization is changed. $previousID = NULL; if ($id) { $previousID = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $id, 'member_of_contact_id'); } $membershipType->save(); if ($id) { // on update we may need to retrieve some details for the price field function - otherwise we get e-notices on attempts to retrieve // name etc - the presence of previous id tells us this is an update $params = array_merge(civicrm_api3('membership_type', 'getsingle', array('id' => $membershipType->id)), $params); } self::createMembershipPriceField($params, $previousID, $membershipType->id); // update all price field value for quick config when membership type is set CRM-11718 if ($id) { self::updateAllPriceFieldValue($id, $params); } self::flush(); return $membershipType; }