3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * This class provides the functionality for batch profile update for contributions.
21 class CRM_Contribute_Form_Task_Batch
extends CRM_Contribute_Form_Task
{
24 * The title of the group
31 * Maximum profile fields that will be displayed
34 protected $_maxFields = 9;
37 * Variable to store redirect path
40 protected $_userContext;
43 * Build all the data structures needed to build the form.
45 public function preProcess() {
46 // initialize the task and row fields
49 //get the contact read only fields to display.
50 $readOnlyFields = array_merge(['sort_name' => ts('Name')],
51 CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
52 'contact_autocomplete_options',
53 TRUE, NULL, FALSE, 'name', TRUE
56 //get the read only field data.
57 $returnProperties = array_fill_keys(array_keys($readOnlyFields), 1);
58 $contactDetails = CRM_Contact_BAO_Contact_Utils
::contactDetails($this->_contributionIds
,
59 'CiviContribute', $returnProperties
61 $this->assign('contactDetails', $contactDetails);
62 $this->assign('readOnlyFields', $readOnlyFields);
66 * Build the form object.
68 public function buildQuickForm() {
69 $ufGroupId = $this->get('ufGroupId');
72 throw new CRM_Core_Exception('ufGroupId is missing');
74 $this->_title
= ts('Update multiple contributions') . ' - ' . CRM_Core_BAO_UFGroup
::getTitle($ufGroupId);
75 CRM_Utils_System
::setTitle($this->_title
);
77 $this->addDefaultButtons(ts('Save'));
79 $this->_fields
= CRM_Core_BAO_UFGroup
::getFields($ufGroupId, FALSE, CRM_Core_Action
::VIEW
);
81 // remove file type field and then limit fields
82 $suppressFields = FALSE;
83 $removehtmlTypes = ['File'];
84 foreach ($this->_fields
as $name => $field) {
85 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name) &&
86 in_array($this->_fields
[$name]['html_type'], $removehtmlTypes)
88 $suppressFields = TRUE;
89 unset($this->_fields
[$name]);
92 //fix to reduce size as we are using this field in grid
93 if (is_array($field['attributes']) && !empty($this->_fields
[$name]['attributes']['size']) && $this->_fields
[$name]['attributes']['size'] > 19) {
94 //shrink class to "form-text-medium"
95 $this->_fields
[$name]['attributes']['size'] = 19;
99 $this->_fields
= array_slice($this->_fields
, 0, $this->_maxFields
);
104 'name' => ts('Update Contribution(s)'),
109 'name' => ts('Cancel'),
113 $this->assign('profileTitle', $this->_title
);
114 $this->assign('componentIds', $this->_contributionIds
);
116 //load all campaigns.
117 if (array_key_exists('contribution_campaign_id', $this->_fields
)) {
118 $this->_componentCampaigns
= [];
119 CRM_Core_PseudoConstant
::populate($this->_componentCampaigns
,
120 'CRM_Contribute_DAO_Contribution',
121 TRUE, 'campaign_id', 'id',
122 ' id IN (' . implode(' , ', array_values($this->_contributionIds
)) . ' ) '
126 // It is possible to have fields that are required in CiviCRM not be required in the
127 // profile. Overriding that here. Perhaps a better approach would be to
128 // make them required in the schema & read that up through getFields functionality.
129 $requiredFields = ['receive_date'];
132 $customFields = CRM_Core_BAO_CustomField
::getFields('Contribution');
133 foreach ($this->_contributionIds
as $contributionId) {
134 $typeId = CRM_Core_DAO
::getFieldValue("CRM_Contribute_DAO_Contribution", $contributionId, 'financial_type_id');
135 foreach ($this->_fields
as $name => $field) {
136 $entityColumnValue = [];
137 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
138 $customValue = $customFields[$customFieldID] ??
NULL;
139 if (!empty($customValue['extends_entity_column_value'])) {
140 $entityColumnValue = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
141 $customValue['extends_entity_column_value']
145 if (!empty($entityColumnValue[$typeId]) ||
146 CRM_Utils_System
::isNull(CRM_Utils_Array
::value($typeId, $entityColumnValue))
148 CRM_Core_BAO_UFGroup
::buildProfile($this, $field, NULL, $contributionId);
152 // handle non custom fields
153 if (in_array($field['name'], $requiredFields)) {
154 $field['is_required'] = TRUE;
156 CRM_Core_BAO_UFGroup
::buildProfile($this, $field, NULL, $contributionId);
161 $this->assign('fields', $this->_fields
);
163 // don't set the status message when form is submitted.
164 $buttonName = $this->controller
->getButtonName('submit');
166 if ($suppressFields && $buttonName != '_qf_Batch_next') {
167 CRM_Core_Session
::setStatus(ts("File type field(s) in the selected profile are not supported for Update multiple contributions."), ts('Unsupported Field Type'), 'error');
170 $this->addDefaultButtons(ts('Update Contributions'));
174 * Set default values for the form.
176 public function setDefaultValues() {
177 if (empty($this->_fields
)) {
182 foreach ($this->_contributionIds
as $contributionId) {
183 CRM_Core_BAO_UFGroup
::setProfileDefaults(NULL, $this->_fields
, $defaults, FALSE, $contributionId, 'Contribute');
190 * Process the form after the input has been submitted and validated.
192 public function postProcess() {
193 $params = $this->exportValues();
194 // @todo extract submit functions &
195 // extend CRM_Event_Form_Task_BatchTest::testSubmit with a data provider to test
196 // handling of custom data, specifically checkbox fields.
197 if (isset($params['field'])) {
198 foreach ($params['field'] as $contributionID => $value) {
200 $value['id'] = $contributionID;
201 if (!empty($value['financial_type'])) {
202 $value['financial_type_id'] = $value['financial_type'];
205 $value['options'] = [
208 $contribution = civicrm_api3('Contribution', 'create', $value);
209 $contribution = $contribution['values'][$contributionID];
211 // @todo add check as to whether the status is updated.
212 if (!empty($value['contribution_status_id'])) {
213 // @todo - use completeorder api or make api call do this.
214 CRM_Contribute_BAO_Contribution
::transitionComponentWithReturnMessage($contribution['id'],
215 $value['contribution_status_id'],
216 CRM_Utils_Array
::value("field[{$contributionID}][contribution_status_id]", $this->_defaultValues
),
217 $contribution['receive_date']
221 CRM_Core_Session
::setStatus(ts("Your updates have been saved."), ts('Saved'), 'success');
224 CRM_Core_Session
::setStatus(ts("No updates have been saved."), ts('Not Saved'), 'alert');