| 1 | <?php |
| 2 | /* |
| 3 | +--------------------------------------------------------------------+ |
| 4 | | CiviCRM version 4.7 | |
| 5 | +--------------------------------------------------------------------+ |
| 6 | | Copyright CiviCRM LLC (c) 2004-2015 | |
| 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 |
| 31 | * @copyright CiviCRM LLC (c) 2004-2015 |
| 32 | */ |
| 33 | |
| 34 | /** |
| 35 | * form to process actions on the group aspect of Custom Data |
| 36 | */ |
| 37 | class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_ContributionBase { |
| 38 | |
| 39 | /** |
| 40 | * The id of the contact associated with this contribution. |
| 41 | * |
| 42 | * @var int |
| 43 | */ |
| 44 | public $_contactID; |
| 45 | |
| 46 | |
| 47 | /** |
| 48 | * The id of the contribution object that is created when the form is submitted. |
| 49 | * |
| 50 | * @var int |
| 51 | */ |
| 52 | public $_contributionID; |
| 53 | |
| 54 | /** |
| 55 | * Set the parameters to be passed to contribution create function. |
| 56 | * |
| 57 | * @param array $params |
| 58 | * @param int $financialTypeID |
| 59 | * @param float $nonDeductibleAmount |
| 60 | * @param bool $pending |
| 61 | * @param array $paymentProcessorOutcome |
| 62 | * @param string $receiptDate |
| 63 | * @param int $recurringContributionID |
| 64 | * |
| 65 | * @return array |
| 66 | */ |
| 67 | public static function getContributionParams( |
| 68 | $params, $financialTypeID, $nonDeductibleAmount, $pending, |
| 69 | $paymentProcessorOutcome, $receiptDate, $recurringContributionID) { |
| 70 | $contributionParams = array( |
| 71 | 'financial_type_id' => $financialTypeID, |
| 72 | 'receive_date' => (CRM_Utils_Array::value('receive_date', $params)) ? CRM_Utils_Date::processDate($params['receive_date']) : date('YmdHis'), |
| 73 | 'non_deductible_amount' => $nonDeductibleAmount, |
| 74 | 'total_amount' => $params['amount'], |
| 75 | 'tax_amount' => CRM_Utils_Array::value('tax_amount', $params), |
| 76 | 'amount_level' => CRM_Utils_Array::value('amount_level', $params), |
| 77 | 'invoice_id' => $params['invoiceID'], |
| 78 | 'currency' => $params['currencyID'], |
| 79 | 'is_pay_later' => CRM_Utils_Array::value('is_pay_later', $params, 0), |
| 80 | //configure cancel reason, cancel date and thankyou date |
| 81 | //from 'contribution' type profile if included |
| 82 | 'cancel_reason' => CRM_Utils_Array::value('cancel_reason', $params, 0), |
| 83 | 'cancel_date' => isset($params['cancel_date']) ? CRM_Utils_Date::format($params['cancel_date']) : NULL, |
| 84 | 'thankyou_date' => isset($params['thankyou_date']) ? CRM_Utils_Date::format($params['thankyou_date']) : NULL, |
| 85 | //setting to make available to hook - although seems wrong to set on form for BAO hook availability |
| 86 | 'skipLineItem' => CRM_Utils_Array::value('skipLineItem', $params, 0), |
| 87 | ); |
| 88 | |
| 89 | if ($paymentProcessorOutcome) { |
| 90 | $contributionParams['payment_processor'] = CRM_Utils_Array::value('payment_processor', $paymentProcessorOutcome); |
| 91 | } |
| 92 | if (!$pending && $paymentProcessorOutcome) { |
| 93 | $contributionParams += array( |
| 94 | 'fee_amount' => CRM_Utils_Array::value('fee_amount', $paymentProcessorOutcome), |
| 95 | 'net_amount' => CRM_Utils_Array::value('net_amount', $paymentProcessorOutcome, $params['amount']), |
| 96 | 'trxn_id' => $paymentProcessorOutcome['trxn_id'], |
| 97 | 'receipt_date' => $receiptDate, |
| 98 | // also add financial_trxn details as part of fix for CRM-4724 |
| 99 | 'trxn_result_code' => CRM_Utils_Array::value('trxn_result_code', $paymentProcessorOutcome), |
| 100 | ); |
| 101 | } |
| 102 | |
| 103 | // CRM-4038: for non-en_US locales, CRM_Contribute_BAO_Contribution::add() expects localised amounts |
| 104 | $contributionParams['non_deductible_amount'] = trim(CRM_Utils_Money::format($contributionParams['non_deductible_amount'], ' ')); |
| 105 | $contributionParams['total_amount'] = trim(CRM_Utils_Money::format($contributionParams['total_amount'], ' ')); |
| 106 | |
| 107 | if ($recurringContributionID) { |
| 108 | $contributionParams['contribution_recur_id'] = $recurringContributionID; |
| 109 | } |
| 110 | |
| 111 | $contributionParams['contribution_status_id'] = $pending ? 2 : 1; |
| 112 | if (isset($contributionParams['invoice_id'])) { |
| 113 | $contributionParams['id'] = CRM_Core_DAO::getFieldValue( |
| 114 | 'CRM_Contribute_DAO_Contribution', |
| 115 | $contributionParams['invoice_id'], |
| 116 | 'id', |
| 117 | 'invoice_id' |
| 118 | ); |
| 119 | } |
| 120 | |
| 121 | return $contributionParams; |
| 122 | } |
| 123 | |
| 124 | /** |
| 125 | * Get non-deductible amount. |
| 126 | * |
| 127 | * This is a bit too much about wierd form interpretation to be this deep. |
| 128 | * |
| 129 | * CRM-11885 |
| 130 | * if non_deductible_amount exists i.e. Additional Details fieldset was opened [and staff typed something] -> keep |
| 131 | * it. |
| 132 | * |
| 133 | * @param array $params |
| 134 | * @param CRM_Financial_BAO_FinancialType $financialType |
| 135 | * @param bool $online |
| 136 | * |
| 137 | * @return array |
| 138 | */ |
| 139 | protected static function getNonDeductibleAmount($params, $financialType, $online) { |
| 140 | if (isset($params['non_deductible_amount']) && (!empty($params['non_deductible_amount']))) { |
| 141 | return $params['non_deductible_amount']; |
| 142 | } |
| 143 | else { |
| 144 | if ($financialType->is_deductible) { |
| 145 | if ($online && isset($params['selectProduct'])) { |
| 146 | $selectProduct = CRM_Utils_Array::value('selectProduct', $params); |
| 147 | } |
| 148 | if (!$online && isset($params['product_name'][0])) { |
| 149 | $selectProduct = $params['product_name'][0]; |
| 150 | } |
| 151 | // if there is a product - compare the value to the contribution amount |
| 152 | if (isset($selectProduct) && |
| 153 | $selectProduct != 'no_thanks' |
| 154 | ) { |
| 155 | $productDAO = new CRM_Contribute_DAO_Product(); |
| 156 | $productDAO->id = $selectProduct; |
| 157 | $productDAO->find(TRUE); |
| 158 | // product value exceeds contribution amount |
| 159 | if ($params['amount'] < $productDAO->price) { |
| 160 | $nonDeductibleAmount = $params['amount']; |
| 161 | return $nonDeductibleAmount; |
| 162 | } |
| 163 | // product value does NOT exceed contribution amount |
| 164 | else { |
| 165 | return $productDAO->price; |
| 166 | } |
| 167 | } |
| 168 | // contribution is deductible - but there is no product |
| 169 | else { |
| 170 | return '0.00'; |
| 171 | } |
| 172 | } |
| 173 | // contribution is NOT deductible |
| 174 | else { |
| 175 | return $params['amount']; |
| 176 | } |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | /** |
| 181 | * Set variables up before form is built. |
| 182 | */ |
| 183 | public function preProcess() { |
| 184 | $config = CRM_Core_Config::singleton(); |
| 185 | parent::preProcess(); |
| 186 | |
| 187 | // lineItem isn't set until Register postProcess |
| 188 | $this->_lineItem = $this->get('lineItem'); |
| 189 | $this->_paymentProcessor = $this->get('paymentProcessor'); |
| 190 | $this->_params = $this->controller->exportValues('Main'); |
| 191 | $this->_params['ip_address'] = CRM_Utils_System::ipAddress(); |
| 192 | $this->_params['amount'] = $this->get('amount'); |
| 193 | if (isset($this->_params['amount'])) { |
| 194 | $this->setFormAmountFields($this->_params['priceSetId']); |
| 195 | } |
| 196 | |
| 197 | $this->_params['tax_amount'] = $this->get('tax_amount'); |
| 198 | $this->_useForMember = $this->get('useForMember'); |
| 199 | |
| 200 | if (isset($this->_params['credit_card_exp_date'])) { |
| 201 | $this->_params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($this->_params); |
| 202 | $this->_params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($this->_params); |
| 203 | } |
| 204 | |
| 205 | $this->_params['currencyID'] = $config->defaultCurrency; |
| 206 | |
| 207 | if (!empty($this->_membershipBlock)) { |
| 208 | $this->_params['selectMembership'] = $this->get('selectMembership'); |
| 209 | } |
| 210 | if (!empty($this->_paymentProcessor) && $this->_paymentProcessor['object']->supports('preApproval')) { |
| 211 | $preApprovalParams = $this->_paymentProcessor['object']->getPreApprovalDetails($this->get('pre_approval_parameters')); |
| 212 | $this->_params = array_merge($this->_params, $preApprovalParams); |
| 213 | } |
| 214 | |
| 215 | // We may have fetched some billing details from the getPreApprovalDetails function so we |
| 216 | // want to ensure we set this after that function has been called. |
| 217 | CRM_Core_Payment_Form::mapParams($this->_bltID, $this->_params, $this->_params, FALSE); |
| 218 | if (!empty($this->_params["billing_state_province_id-{$this->_bltID}"])) { |
| 219 | $this->_params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($this->_params["billing_state_province_id-{$this->_bltID}"]); |
| 220 | } |
| 221 | if (!empty($this->_params["billing_country_id-{$this->_bltID}"])) { |
| 222 | $this->_params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($this->_params["billing_country_id-{$this->_bltID}"]); |
| 223 | } |
| 224 | |
| 225 | $this->_params['is_pay_later'] = $this->get('is_pay_later'); |
| 226 | $this->assign('is_pay_later', $this->_params['is_pay_later']); |
| 227 | if ($this->_params['is_pay_later']) { |
| 228 | $this->assign('pay_later_receipt', $this->_values['pay_later_receipt']); |
| 229 | } |
| 230 | // if onbehalf-of-organization |
| 231 | if (!empty($this->_params['hidden_onbehalf_profile'])) { |
| 232 | // CRM-15182 |
| 233 | if (empty($this->_params['org_option']) && empty($this->_params['organization_id'])) { |
| 234 | if (!empty($this->_params['onbehalfof_id'])) { |
| 235 | $this->_params['organization_id'] = $this->_params['onbehalfof_id']; |
| 236 | } |
| 237 | else { |
| 238 | $this->_params['organization_id'] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_params['onbehalf']['organization_name'], 'id', 'display_name'); |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | $this->_params['organization_name'] = $this->_params['onbehalf']['organization_name']; |
| 243 | $addressBlocks = array( |
| 244 | 'street_address', |
| 245 | 'city', |
| 246 | 'state_province', |
| 247 | 'postal_code', |
| 248 | 'country', |
| 249 | 'supplemental_address_1', |
| 250 | 'supplemental_address_2', |
| 251 | 'supplemental_address_3', |
| 252 | 'postal_code_suffix', |
| 253 | 'geo_code_1', |
| 254 | 'geo_code_2', |
| 255 | 'address_name', |
| 256 | ); |
| 257 | |
| 258 | $blocks = array('email', 'phone', 'im', 'url', 'openid'); |
| 259 | foreach ($this->_params['onbehalf'] as $loc => $value) { |
| 260 | $field = $typeId = NULL; |
| 261 | if (strstr($loc, '-')) { |
| 262 | list($field, $locType) = explode('-', $loc); |
| 263 | } |
| 264 | |
| 265 | if (in_array($field, $addressBlocks)) { |
| 266 | if ($locType == 'Primary') { |
| 267 | $defaultLocationType = CRM_Core_BAO_LocationType::getDefault(); |
| 268 | $locType = $defaultLocationType->id; |
| 269 | } |
| 270 | |
| 271 | if ($field == 'country') { |
| 272 | $value = CRM_Core_PseudoConstant::countryIsoCode($value); |
| 273 | } |
| 274 | elseif ($field == 'state_province') { |
| 275 | $value = CRM_Core_PseudoConstant::stateProvinceAbbreviation($value); |
| 276 | } |
| 277 | |
| 278 | $isPrimary = 1; |
| 279 | if (isset($this->_params['onbehalf_location']['address']) |
| 280 | && count($this->_params['onbehalf_location']['address']) > 0 |
| 281 | ) { |
| 282 | $isPrimary = 0; |
| 283 | } |
| 284 | |
| 285 | $this->_params['onbehalf_location']['address'][$locType][$field] = $value; |
| 286 | if (empty($this->_params['onbehalf_location']['address'][$locType]['is_primary'])) { |
| 287 | $this->_params['onbehalf_location']['address'][$locType]['is_primary'] = $isPrimary; |
| 288 | } |
| 289 | $this->_params['onbehalf_location']['address'][$locType]['location_type_id'] = $locType; |
| 290 | } |
| 291 | elseif (in_array($field, $blocks)) { |
| 292 | if (!$typeId || is_numeric($typeId)) { |
| 293 | $blockName = $fieldName = $field; |
| 294 | $locationType = 'location_type_id'; |
| 295 | if ($locType == 'Primary') { |
| 296 | $defaultLocationType = CRM_Core_BAO_LocationType::getDefault(); |
| 297 | $locationValue = $defaultLocationType->id; |
| 298 | } |
| 299 | else { |
| 300 | $locationValue = $locType; |
| 301 | } |
| 302 | $locTypeId = ''; |
| 303 | $phoneExtField = array(); |
| 304 | |
| 305 | if ($field == 'url') { |
| 306 | $blockName = 'website'; |
| 307 | $locationType = 'website_type_id'; |
| 308 | list($field, $locationValue) = explode('-', $loc); |
| 309 | } |
| 310 | elseif ($field == 'im') { |
| 311 | $fieldName = 'name'; |
| 312 | $locTypeId = 'provider_id'; |
| 313 | $typeId = $this->_params['onbehalf']["{$loc}-provider_id"]; |
| 314 | } |
| 315 | elseif ($field == 'phone') { |
| 316 | list($field, $locType, $typeId) = explode('-', $loc); |
| 317 | $locTypeId = 'phone_type_id'; |
| 318 | |
| 319 | //check if extension field exists |
| 320 | $extField = str_replace('phone', 'phone_ext', $loc); |
| 321 | if (isset($this->_params['onbehalf'][$extField])) { |
| 322 | $phoneExtField = array('phone_ext' => $this->_params['onbehalf'][$extField]); |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | $isPrimary = 1; |
| 327 | if (isset ($this->_params['onbehalf_location'][$blockName]) |
| 328 | && count($this->_params['onbehalf_location'][$blockName]) > 0 |
| 329 | ) { |
| 330 | $isPrimary = 0; |
| 331 | } |
| 332 | if ($locationValue) { |
| 333 | $blockValues = array( |
| 334 | $fieldName => $value, |
| 335 | $locationType => $locationValue, |
| 336 | 'is_primary' => $isPrimary, |
| 337 | ); |
| 338 | |
| 339 | if ($locTypeId) { |
| 340 | $blockValues = array_merge($blockValues, array($locTypeId => $typeId)); |
| 341 | } |
| 342 | if (!empty($phoneExtField)) { |
| 343 | $blockValues = array_merge($blockValues, $phoneExtField); |
| 344 | } |
| 345 | |
| 346 | $this->_params['onbehalf_location'][$blockName][] = $blockValues; |
| 347 | } |
| 348 | } |
| 349 | } |
| 350 | elseif (strstr($loc, 'custom')) { |
| 351 | if ($value && isset($this->_params['onbehalf']["{$loc}_id"])) { |
| 352 | $value = $this->_params['onbehalf']["{$loc}_id"]; |
| 353 | } |
| 354 | $this->_params['onbehalf_location']["{$loc}"] = $value; |
| 355 | } |
| 356 | else { |
| 357 | if ($loc == 'contact_sub_type') { |
| 358 | $this->_params['onbehalf_location'][$loc] = $value; |
| 359 | } |
| 360 | else { |
| 361 | $this->_params['onbehalf_location'][$field] = $value; |
| 362 | } |
| 363 | } |
| 364 | } |
| 365 | } |
| 366 | elseif (!empty($this->_values['is_for_organization'])) { |
| 367 | // no on behalf of an organization, CRM-5519 |
| 368 | // so reset loc blocks from main params. |
| 369 | foreach (array( |
| 370 | 'phone', |
| 371 | 'email', |
| 372 | 'address', |
| 373 | ) as $blk) { |
| 374 | if (isset($this->_params[$blk])) { |
| 375 | unset($this->_params[$blk]); |
| 376 | } |
| 377 | } |
| 378 | } |
| 379 | $this->setRecurringMembershipParams(); |
| 380 | |
| 381 | if ($this->_pcpId) { |
| 382 | $params = $this->processPcp($this, $this->_params); |
| 383 | $this->_params = $params; |
| 384 | } |
| 385 | $this->_params['invoiceID'] = $this->get('invoiceID'); |
| 386 | |
| 387 | //carry campaign from profile. |
| 388 | if (array_key_exists('contribution_campaign_id', $this->_params)) { |
| 389 | $this->_params['campaign_id'] = $this->_params['contribution_campaign_id']; |
| 390 | } |
| 391 | |
| 392 | // assign contribution page id to the template so we can add css class for it |
| 393 | $this->assign('contributionPageID', $this->_id); |
| 394 | |
| 395 | $this->set('params', $this->_params); |
| 396 | } |
| 397 | |
| 398 | /** |
| 399 | * Build the form object. |
| 400 | */ |
| 401 | public function buildQuickForm() { |
| 402 | $this->assignToTemplate(); |
| 403 | |
| 404 | $params = $this->_params; |
| 405 | // make sure we have values for it |
| 406 | if ($this->_honor_block_is_active && !empty($params['soft_credit_type_id'])) { |
| 407 | $honorName = NULL; |
| 408 | $softCreditTypes = CRM_Core_OptionGroup::values("soft_credit_type", FALSE); |
| 409 | |
| 410 | $this->assign('honor_block_is_active', $this->_honor_block_is_active); |
| 411 | $this->assign('soft_credit_type', $softCreditTypes[$params['soft_credit_type_id']]); |
| 412 | CRM_Contribute_BAO_ContributionSoft::formatHonoreeProfileFields($this, $params['honor'], $params['honoree_profile_id']); |
| 413 | |
| 414 | $fieldTypes = array('Contact'); |
| 415 | $fieldTypes[] = CRM_Core_BAO_UFGroup::getContactType($params['honoree_profile_id']); |
| 416 | $this->buildCustom($params['honoree_profile_id'], 'honoreeProfileFields', TRUE, 'honor', $fieldTypes); |
| 417 | } |
| 418 | $this->assign('receiptFromEmail', CRM_Utils_Array::value('receipt_from_email', $this->_values)); |
| 419 | $amount_block_is_active = $this->get('amount_block_is_active'); |
| 420 | $this->assign('amount_block_is_active', $amount_block_is_active); |
| 421 | |
| 422 | $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings'); |
| 423 | $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings); |
| 424 | if ($invoicing) { |
| 425 | $getTaxDetails = FALSE; |
| 426 | $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings); |
| 427 | foreach ($this->_lineItem as $key => $value) { |
| 428 | foreach ($value as $v) { |
| 429 | if (isset($v['tax_rate'])) { |
| 430 | if ($v['tax_rate'] != '') { |
| 431 | $getTaxDetails = TRUE; |
| 432 | } |
| 433 | } |
| 434 | } |
| 435 | } |
| 436 | $this->assign('getTaxDetails', $getTaxDetails); |
| 437 | $this->assign('taxTerm', $taxTerm); |
| 438 | $this->assign('totalTaxAmount', $params['tax_amount']); |
| 439 | } |
| 440 | if (!empty($params['selectProduct']) && $params['selectProduct'] != 'no_thanks') { |
| 441 | $option = CRM_Utils_Array::value('options_' . $params['selectProduct'], $params); |
| 442 | $productID = $params['selectProduct']; |
| 443 | CRM_Contribute_BAO_Premium::buildPremiumBlock($this, $this->_id, FALSE, |
| 444 | $productID, $option |
| 445 | ); |
| 446 | $this->set('productID', $productID); |
| 447 | $this->set('option', $option); |
| 448 | } |
| 449 | $config = CRM_Core_Config::singleton(); |
| 450 | if (in_array('CiviMember', $config->enableComponents)) { |
| 451 | if (isset($params['selectMembership']) && |
| 452 | $params['selectMembership'] != 'no_thanks' |
| 453 | ) { |
| 454 | $this->buildMembershipBlock( |
| 455 | $this->_membershipContactID, |
| 456 | FALSE, |
| 457 | $params['selectMembership'], |
| 458 | FALSE |
| 459 | ); |
| 460 | if (!empty($params['auto_renew'])) { |
| 461 | $this->assign('auto_renew', TRUE); |
| 462 | } |
| 463 | } |
| 464 | else { |
| 465 | $this->assign('membershipBlock', FALSE); |
| 466 | } |
| 467 | } |
| 468 | $this->buildCustom($this->_values['custom_pre_id'], 'customPre', TRUE); |
| 469 | $this->buildCustom($this->_values['custom_post_id'], 'customPost', TRUE); |
| 470 | |
| 471 | if (!empty($params['hidden_onbehalf_profile'])) { |
| 472 | $ufJoinParams = array( |
| 473 | 'module' => 'onBehalf', |
| 474 | 'entity_table' => 'civicrm_contribution_page', |
| 475 | 'entity_id' => $this->_id, |
| 476 | ); |
| 477 | $OnBehalfProfile = CRM_Core_BAO_UFJoin::getUFGroupIds($ufJoinParams); |
| 478 | $profileId = $OnBehalfProfile[0]; |
| 479 | |
| 480 | $fieldTypes = array('Contact', 'Organization'); |
| 481 | $contactSubType = CRM_Contact_BAO_ContactType::subTypes('Organization'); |
| 482 | $fieldTypes = array_merge($fieldTypes, $contactSubType); |
| 483 | if (is_array($this->_membershipBlock) && !empty($this->_membershipBlock)) { |
| 484 | $fieldTypes = array_merge($fieldTypes, array('Membership')); |
| 485 | } |
| 486 | else { |
| 487 | $fieldTypes = array_merge($fieldTypes, array('Contribution')); |
| 488 | } |
| 489 | |
| 490 | $this->buildCustom($profileId, 'onbehalfProfile', TRUE, 'onbehalf', $fieldTypes); |
| 491 | } |
| 492 | |
| 493 | $this->_separateMembershipPayment = $this->get('separateMembershipPayment'); |
| 494 | $this->assign('is_separate_payment', $this->_separateMembershipPayment); |
| 495 | if ($this->_priceSetId && !CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) { |
| 496 | $this->assign('lineItem', $this->_lineItem); |
| 497 | } |
| 498 | else { |
| 499 | $this->assign('is_quick_config', 1); |
| 500 | $this->_params['is_quick_config'] = 1; |
| 501 | } |
| 502 | $this->assign('priceSetID', $this->_priceSetId); |
| 503 | $paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(FALSE, NULL, 'name'); |
| 504 | if ($this->_paymentProcessor && |
| 505 | $this->_paymentProcessor['payment_processor_type_id'] == CRM_Utils_Array::key('Google_Checkout', $paymentProcessorType) |
| 506 | && !$this->_params['is_pay_later'] && !($this->_amount == 0) |
| 507 | ) { |
| 508 | $this->_checkoutButtonName = $this->getButtonName('next', 'checkout'); |
| 509 | $this->add('image', |
| 510 | $this->_checkoutButtonName, |
| 511 | $this->_paymentProcessor['url_button'], |
| 512 | array('class' => 'crm-form-submit') |
| 513 | ); |
| 514 | |
| 515 | $this->addButtons(array( |
| 516 | array( |
| 517 | 'type' => 'back', |
| 518 | 'name' => ts('Go Back'), |
| 519 | ), |
| 520 | ) |
| 521 | ); |
| 522 | } |
| 523 | else { |
| 524 | if ($this->_contributeMode == 'notify' || !$this->_values['is_monetary'] || |
| 525 | $this->_amount <= 0.0 || $this->_params['is_pay_later'] || |
| 526 | ($this->_separateMembershipPayment && $this->_amount <= 0.0) |
| 527 | ) { |
| 528 | $contribButton = ts('Continue'); |
| 529 | $this->assign('button', ts('Continue')); |
| 530 | } |
| 531 | else { |
| 532 | $contribButton = ts('Make Contribution'); |
| 533 | $this->assign('button', ts('Make Contribution')); |
| 534 | } |
| 535 | $this->addButtons(array( |
| 536 | array( |
| 537 | 'type' => 'next', |
| 538 | 'name' => $contribButton, |
| 539 | 'spacing' => ' ', |
| 540 | 'isDefault' => TRUE, |
| 541 | 'js' => array('onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"), |
| 542 | ), |
| 543 | array( |
| 544 | 'type' => 'back', |
| 545 | 'name' => ts('Go Back'), |
| 546 | ), |
| 547 | ) |
| 548 | ); |
| 549 | } |
| 550 | |
| 551 | $defaults = array(); |
| 552 | $fields = array_fill_keys(array_keys($this->_fields), 1); |
| 553 | $fields["billing_state_province-{$this->_bltID}"] = $fields["billing_country-{$this->_bltID}"] = $fields["email-{$this->_bltID}"] = 1; |
| 554 | |
| 555 | $contact = $this->_params; |
| 556 | foreach ($fields as $name => $dontCare) { |
| 557 | // Recursively set defaults for nested fields |
| 558 | if (isset($contact[$name]) && is_array($contact[$name]) && ($name == 'onbehalf' || $name == 'honor')) { |
| 559 | foreach ($contact[$name] as $fieldName => $fieldValue) { |
| 560 | if (is_array($fieldValue) && !in_array($this->_fields[$name][$fieldName]['html_type'], array( |
| 561 | 'Multi-Select', |
| 562 | 'AdvMulti-Select', |
| 563 | )) |
| 564 | ) { |
| 565 | foreach ($fieldValue as $key => $value) { |
| 566 | $defaults["{$name}[{$fieldName}][{$key}]"] = $value; |
| 567 | } |
| 568 | } |
| 569 | else { |
| 570 | $defaults["{$name}[{$fieldName}]"] = $fieldValue; |
| 571 | } |
| 572 | } |
| 573 | } |
| 574 | elseif (isset($contact[$name])) { |
| 575 | $defaults[$name] = $contact[$name]; |
| 576 | if (substr($name, 0, 7) == 'custom_') { |
| 577 | $timeField = "{$name}_time"; |
| 578 | if (isset($contact[$timeField])) { |
| 579 | $defaults[$timeField] = $contact[$timeField]; |
| 580 | } |
| 581 | if (isset($contact["{$name}_id"])) { |
| 582 | $defaults["{$name}_id"] = $contact["{$name}_id"]; |
| 583 | } |
| 584 | } |
| 585 | elseif (in_array($name, array( |
| 586 | 'addressee', |
| 587 | 'email_greeting', |
| 588 | 'postal_greeting', |
| 589 | )) && !empty($contact[$name . '_custom']) |
| 590 | ) { |
| 591 | $defaults[$name . '_custom'] = $contact[$name . '_custom']; |
| 592 | } |
| 593 | } |
| 594 | } |
| 595 | |
| 596 | $this->assign('useForMember', $this->get('useForMember')); |
| 597 | |
| 598 | $this->setDefaults($defaults); |
| 599 | |
| 600 | $this->freeze(); |
| 601 | } |
| 602 | |
| 603 | /** |
| 604 | * Overwrite action. |
| 605 | * |
| 606 | * Since we are only showing elements in frozen mode no help display needed. |
| 607 | * |
| 608 | * @return int |
| 609 | */ |
| 610 | public function getAction() { |
| 611 | if ($this->_action & CRM_Core_Action::PREVIEW) { |
| 612 | return CRM_Core_Action::VIEW | CRM_Core_Action::PREVIEW; |
| 613 | } |
| 614 | else { |
| 615 | return CRM_Core_Action::VIEW; |
| 616 | } |
| 617 | } |
| 618 | |
| 619 | /** |
| 620 | * Set default values for the form. |
| 621 | * |
| 622 | * Note that in edit/view mode |
| 623 | * the default values are retrieved from the database |
| 624 | */ |
| 625 | public function setDefaultValues() { |
| 626 | } |
| 627 | |
| 628 | /** |
| 629 | * Process the form. |
| 630 | */ |
| 631 | public function postProcess() { |
| 632 | $contactID = $this->getContactID(); |
| 633 | $result = $this->processFormSubmission($contactID); |
| 634 | if (is_array($result) && !empty($result['is_payment_failure'])) { |
| 635 | // We will probably have the function that gets this error throw an exception on the next round of refactoring. |
| 636 | CRM_Core_Session::singleton()->setStatus(ts("Payment Processor Error message :") . |
| 637 | $result['error']->getMessage()); |
| 638 | CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/transact', |
| 639 | "_qf_Main_display=true&qfKey={$this->_params['qfKey']}" |
| 640 | )); |
| 641 | } |
| 642 | // Presumably this is for hooks to access? Not quite clear & perhaps not required. |
| 643 | $this->set('params', $this->_params); |
| 644 | } |
| 645 | |
| 646 | /** |
| 647 | * Wrangle financial type ID. |
| 648 | * |
| 649 | * This wrangling of the financialType ID was happening in a shared function rather than in the form it relates to & hence has been moved to that form |
| 650 | * Pledges are not relevant to the membership code so that portion will not go onto the membership form. |
| 651 | * |
| 652 | * Comments from previous refactor indicate doubt as to what was going on. |
| 653 | * |
| 654 | * @param int $contributionTypeId |
| 655 | * |
| 656 | * @return null|string |
| 657 | */ |
| 658 | public function wrangleFinancialTypeID($contributionTypeId) { |
| 659 | if (isset($paymentParams['financial_type'])) { |
| 660 | $contributionTypeId = $paymentParams['financial_type']; |
| 661 | } |
| 662 | elseif (!empty($this->_values['pledge_id'])) { |
| 663 | $contributionTypeId = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_Pledge', |
| 664 | $this->_values['pledge_id'], |
| 665 | 'financial_type_id' |
| 666 | ); |
| 667 | } |
| 668 | return $contributionTypeId; |
| 669 | } |
| 670 | |
| 671 | /** |
| 672 | * Process the form. |
| 673 | * |
| 674 | * @param array $premiumParams |
| 675 | * @param CRM_Contribute_BAO_Contribution $contribution |
| 676 | */ |
| 677 | protected function postProcessPremium($premiumParams, $contribution) { |
| 678 | $hour = $minute = $second = 0; |
| 679 | // assigning Premium information to receipt tpl |
| 680 | $selectProduct = CRM_Utils_Array::value('selectProduct', $premiumParams); |
| 681 | if ($selectProduct && |
| 682 | $selectProduct != 'no_thanks' |
| 683 | ) { |
| 684 | $startDate = $endDate = ""; |
| 685 | $this->assign('selectPremium', TRUE); |
| 686 | $productDAO = new CRM_Contribute_DAO_Product(); |
| 687 | $productDAO->id = $selectProduct; |
| 688 | $productDAO->find(TRUE); |
| 689 | $this->assign('product_name', $productDAO->name); |
| 690 | $this->assign('price', $productDAO->price); |
| 691 | $this->assign('sku', $productDAO->sku); |
| 692 | $this->assign('option', CRM_Utils_Array::value('options_' . $premiumParams['selectProduct'], $premiumParams)); |
| 693 | |
| 694 | $periodType = $productDAO->period_type; |
| 695 | |
| 696 | if ($periodType) { |
| 697 | $fixed_period_start_day = $productDAO->fixed_period_start_day; |
| 698 | $duration_unit = $productDAO->duration_unit; |
| 699 | $duration_interval = $productDAO->duration_interval; |
| 700 | if ($periodType == 'rolling') { |
| 701 | $startDate = date('Y-m-d'); |
| 702 | } |
| 703 | elseif ($periodType == 'fixed') { |
| 704 | if ($fixed_period_start_day) { |
| 705 | $date = explode('-', date('Y-m-d')); |
| 706 | $month = substr($fixed_period_start_day, 0, strlen($fixed_period_start_day) - 2); |
| 707 | $day = substr($fixed_period_start_day, -2) . "<br/>"; |
| 708 | $year = $date[0]; |
| 709 | $startDate = $year . '-' . $month . '-' . $day; |
| 710 | } |
| 711 | else { |
| 712 | $startDate = date('Y-m-d'); |
| 713 | } |
| 714 | } |
| 715 | |
| 716 | $date = explode('-', $startDate); |
| 717 | $year = $date[0]; |
| 718 | $month = $date[1]; |
| 719 | $day = $date[2]; |
| 720 | |
| 721 | switch ($duration_unit) { |
| 722 | case 'year': |
| 723 | $year = $year + $duration_interval; |
| 724 | break; |
| 725 | |
| 726 | case 'month': |
| 727 | $month = $month + $duration_interval; |
| 728 | break; |
| 729 | |
| 730 | case 'day': |
| 731 | $day = $day + $duration_interval; |
| 732 | break; |
| 733 | |
| 734 | case 'week': |
| 735 | $day = $day + ($duration_interval * 7); |
| 736 | } |
| 737 | $endDate = date('Y-m-d H:i:s', mktime($hour, $minute, $second, $month, $day, $year)); |
| 738 | $this->assign('start_date', $startDate); |
| 739 | $this->assign('end_date', $endDate); |
| 740 | } |
| 741 | |
| 742 | $dao = new CRM_Contribute_DAO_Premium(); |
| 743 | $dao->entity_table = 'civicrm_contribution_page'; |
| 744 | $dao->entity_id = $this->_id; |
| 745 | $dao->find(TRUE); |
| 746 | $this->assign('contact_phone', $dao->premiums_contact_phone); |
| 747 | $this->assign('contact_email', $dao->premiums_contact_email); |
| 748 | |
| 749 | //create Premium record |
| 750 | $params = array( |
| 751 | 'product_id' => $premiumParams['selectProduct'], |
| 752 | 'contribution_id' => $contribution->id, |
| 753 | 'product_option' => CRM_Utils_Array::value('options_' . $premiumParams['selectProduct'], $premiumParams), |
| 754 | 'quantity' => 1, |
| 755 | 'start_date' => CRM_Utils_Date::customFormat($startDate, '%Y%m%d'), |
| 756 | 'end_date' => CRM_Utils_Date::customFormat($endDate, '%Y%m%d'), |
| 757 | ); |
| 758 | if (!empty($premiumParams['selectProduct'])) { |
| 759 | $daoPremiumsProduct = new CRM_Contribute_DAO_PremiumsProduct(); |
| 760 | $daoPremiumsProduct->product_id = $premiumParams['selectProduct']; |
| 761 | $daoPremiumsProduct->premiums_id = $dao->id; |
| 762 | $daoPremiumsProduct->find(TRUE); |
| 763 | $params['financial_type_id'] = $daoPremiumsProduct->financial_type_id; |
| 764 | } |
| 765 | //Fixed For CRM-3901 |
| 766 | $daoContrProd = new CRM_Contribute_DAO_ContributionProduct(); |
| 767 | $daoContrProd->contribution_id = $contribution->id; |
| 768 | if ($daoContrProd->find(TRUE)) { |
| 769 | $params['id'] = $daoContrProd->id; |
| 770 | } |
| 771 | |
| 772 | CRM_Contribute_BAO_Contribution::addPremium($params); |
| 773 | if ($productDAO->cost && !empty($params['financial_type_id'])) { |
| 774 | $trxnParams = array( |
| 775 | 'cost' => $productDAO->cost, |
| 776 | 'currency' => $productDAO->currency, |
| 777 | 'financial_type_id' => $params['financial_type_id'], |
| 778 | 'contributionId' => $contribution->id, |
| 779 | ); |
| 780 | CRM_Core_BAO_FinancialTrxn::createPremiumTrxn($trxnParams); |
| 781 | } |
| 782 | } |
| 783 | elseif ($selectProduct == 'no_thanks') { |
| 784 | //Fixed For CRM-3901 |
| 785 | $daoContrProd = new CRM_Contribute_DAO_ContributionProduct(); |
| 786 | $daoContrProd->contribution_id = $contribution->id; |
| 787 | if ($daoContrProd->find(TRUE)) { |
| 788 | $daoContrProd->delete(); |
| 789 | } |
| 790 | } |
| 791 | } |
| 792 | |
| 793 | /** |
| 794 | * Process the contribution. |
| 795 | * |
| 796 | * @param CRM_Core_Form $form |
| 797 | * @param array $params |
| 798 | * @param array $result |
| 799 | * @param array $contributionParams |
| 800 | * Parameters to be passed to contribution create action. |
| 801 | * This differs from params in that we are currently adding params to it and 1) ensuring they are being |
| 802 | * passed consistently & 2) documenting them here. |
| 803 | * - contact_id |
| 804 | * - line_item |
| 805 | * - is_test |
| 806 | * - campaign_id |
| 807 | * - contribution_page_id |
| 808 | * - source |
| 809 | * - payment_type_id |
| 810 | * - thankyou_date (not all forms will set this) |
| 811 | * |
| 812 | * @param CRM_Financial_DAO_FinancialType $financialType |
| 813 | * @param bool $online |
| 814 | * Is the form a front end form? If so set a bunch of unpredictable things that should be passed in from the form. |
| 815 | * |
| 816 | * @param int $billingLocationID |
| 817 | * ID of billing location type. |
| 818 | * |
| 819 | * @return \CRM_Contribute_DAO_Contribution |
| 820 | * @throws \Exception |
| 821 | */ |
| 822 | public static function processFormContribution( |
| 823 | &$form, |
| 824 | $params, |
| 825 | $result, |
| 826 | $contributionParams, |
| 827 | $financialType, |
| 828 | $online, |
| 829 | $billingLocationID |
| 830 | ) { |
| 831 | $transaction = new CRM_Core_Transaction(); |
| 832 | $contactID = $contributionParams['contact_id']; |
| 833 | |
| 834 | $isEmailReceipt = !empty($form->_values['is_email_receipt']); |
| 835 | $isSeparateMembershipPayment = empty($params['separate_membership_payment']) ? FALSE : TRUE; |
| 836 | $pledgeID = empty($params['pledge_id']) ? NULL : $params['pledge_id']; |
| 837 | if (!$isSeparateMembershipPayment && !empty($form->_values['pledge_block_id']) && |
| 838 | (!empty($params['is_pledge']) || $pledgeID)) { |
| 839 | $isPledge = TRUE; |
| 840 | } |
| 841 | else { |
| 842 | $isPledge = FALSE; |
| 843 | } |
| 844 | |
| 845 | // add these values for the recurringContrib function ,CRM-10188 |
| 846 | $params['financial_type_id'] = $financialType->id; |
| 847 | |
| 848 | $contributionParams['address_id'] = CRM_Contribute_BAO_Contribution::createAddress($params, $billingLocationID); |
| 849 | |
| 850 | //@todo - this is being set from the form to resolve CRM-10188 - an |
| 851 | // eNotice caused by it not being set @ the front end |
| 852 | // however, we then get it being over-written with null for backend contributions |
| 853 | // a better fix would be to set the values in the respective forms rather than require |
| 854 | // a function being shared by two forms to deal with their respective values |
| 855 | // moving it to the BAO & not taking the $form as a param would make sense here. |
| 856 | if (!isset($params['is_email_receipt']) && $isEmailReceipt) { |
| 857 | $params['is_email_receipt'] = $isEmailReceipt; |
| 858 | } |
| 859 | $recurringContributionID = self::processRecurringContribution($form, $params, $contactID, $financialType, $online); |
| 860 | $nonDeductibleAmount = self::getNonDeductibleAmount($params, $financialType, $online); |
| 861 | |
| 862 | $now = date('YmdHis'); |
| 863 | $receiptDate = CRM_Utils_Array::value('receipt_date', $params); |
| 864 | if ($isEmailReceipt) { |
| 865 | $receiptDate = $now; |
| 866 | } |
| 867 | |
| 868 | // Prepare soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin. |
| 869 | if (!empty($params['pcp_made_through_id']) || !empty($params['soft_credit_to'])) { |
| 870 | // if its due to pcp |
| 871 | if (!empty($params['pcp_made_through_id'])) { |
| 872 | $contributionParams['soft_credit_to'] = CRM_Core_DAO::getFieldValue( |
| 873 | 'CRM_PCP_DAO_PCP', |
| 874 | $params['pcp_made_through_id'], |
| 875 | 'contact_id' |
| 876 | ); |
| 877 | // Pass these details onto with the contribution to make them |
| 878 | // available at hook_post_process, CRM-8908 |
| 879 | // @todo - obsolete? |
| 880 | $params['soft_credit_to'] = $contributionParams['soft_credit_to']; |
| 881 | } |
| 882 | else { |
| 883 | $contributionParams['soft_credit_to'] = CRM_Utils_Array::value('soft_credit_to', $params); |
| 884 | } |
| 885 | } |
| 886 | |
| 887 | if (isset($params['amount'])) { |
| 888 | $contributionParams = array_merge(self::getContributionParams( |
| 889 | $params, $financialType->id, $nonDeductibleAmount, TRUE, |
| 890 | $result, $receiptDate, |
| 891 | $recurringContributionID), $contributionParams |
| 892 | ); |
| 893 | $contribution = CRM_Contribute_BAO_Contribution::add($contributionParams); |
| 894 | |
| 895 | $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings'); |
| 896 | $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings); |
| 897 | if ($invoicing) { |
| 898 | $dataArray = array(); |
| 899 | // @todo - interrogate the line items passed in on the params array. |
| 900 | // No reason to assume line items will be set on the form. |
| 901 | foreach ($form->_lineItem as $lineItemKey => $lineItemValue) { |
| 902 | foreach ($lineItemValue as $key => $value) { |
| 903 | if (isset($value['tax_amount']) && isset($value['tax_rate'])) { |
| 904 | if (isset($dataArray[$value['tax_rate']])) { |
| 905 | $dataArray[$value['tax_rate']] = $dataArray[$value['tax_rate']] + CRM_Utils_Array::value('tax_amount', $value); |
| 906 | } |
| 907 | else { |
| 908 | $dataArray[$value['tax_rate']] = CRM_Utils_Array::value('tax_amount', $value); |
| 909 | } |
| 910 | } |
| 911 | } |
| 912 | } |
| 913 | $smarty = CRM_Core_Smarty::singleton(); |
| 914 | $smarty->assign('dataArray', $dataArray); |
| 915 | $smarty->assign('totalTaxAmount', $params['tax_amount']); |
| 916 | } |
| 917 | if (is_a($contribution, 'CRM_Core_Error')) { |
| 918 | $message = CRM_Core_Error::getMessages($contribution); |
| 919 | CRM_Core_Error::fatal($message); |
| 920 | } |
| 921 | |
| 922 | // lets store it in the form variable so postProcess hook can get to this and use it |
| 923 | $form->_contributionID = $contribution->id; |
| 924 | } |
| 925 | |
| 926 | //CRM-13981, processing honor contact into soft-credit contribution |
| 927 | CRM_Contact_Form_ProfileContact::postProcess($form, $params); |
| 928 | |
| 929 | // process soft credit / pcp pages |
| 930 | CRM_Contribute_Form_Contribution_Confirm::processPcpSoft($params, $contribution); |
| 931 | |
| 932 | //handle pledge stuff. |
| 933 | if ($isPledge) { |
| 934 | if ($pledgeID) { |
| 935 | //when user doing pledge payments. |
| 936 | //update the schedule when payment(s) are made |
| 937 | foreach ($params['pledge_amount'] as $paymentId => $dontCare) { |
| 938 | $scheduledAmount = CRM_Core_DAO::getFieldValue( |
| 939 | 'CRM_Pledge_DAO_PledgePayment', |
| 940 | $paymentId, |
| 941 | 'scheduled_amount', |
| 942 | 'id' |
| 943 | ); |
| 944 | |
| 945 | $pledgePaymentParams = array( |
| 946 | 'id' => $paymentId, |
| 947 | 'contribution_id' => $contribution->id, |
| 948 | 'status_id' => $contribution->contribution_status_id, |
| 949 | 'actual_amount' => $scheduledAmount, |
| 950 | ); |
| 951 | |
| 952 | CRM_Pledge_BAO_PledgePayment::add($pledgePaymentParams); |
| 953 | } |
| 954 | |
| 955 | //update pledge status according to the new payment statuses |
| 956 | CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($pledgeID); |
| 957 | } |
| 958 | else { |
| 959 | //when user creating pledge record. |
| 960 | $pledgeParams = array(); |
| 961 | $pledgeParams['contact_id'] = $contribution->contact_id; |
| 962 | $pledgeParams['installment_amount'] = $pledgeParams['actual_amount'] = $contribution->total_amount; |
| 963 | $pledgeParams['contribution_id'] = $contribution->id; |
| 964 | $pledgeParams['contribution_page_id'] = $contribution->contribution_page_id; |
| 965 | $pledgeParams['financial_type_id'] = $contribution->financial_type_id; |
| 966 | $pledgeParams['frequency_interval'] = $params['pledge_frequency_interval']; |
| 967 | $pledgeParams['installments'] = $params['pledge_installments']; |
| 968 | $pledgeParams['frequency_unit'] = $params['pledge_frequency_unit']; |
| 969 | if ($pledgeParams['frequency_unit'] == 'month') { |
| 970 | $pledgeParams['frequency_day'] = intval(date("d")); |
| 971 | } |
| 972 | else { |
| 973 | $pledgeParams['frequency_day'] = 1; |
| 974 | } |
| 975 | $pledgeParams['create_date'] = $pledgeParams['start_date'] = $pledgeParams['scheduled_date'] = date("Ymd"); |
| 976 | $pledgeParams['status_id'] = $contribution->contribution_status_id; |
| 977 | $pledgeParams['max_reminders'] = $form->_values['max_reminders']; |
| 978 | $pledgeParams['initial_reminder_day'] = $form->_values['initial_reminder_day']; |
| 979 | $pledgeParams['additional_reminder_day'] = $form->_values['additional_reminder_day']; |
| 980 | $pledgeParams['is_test'] = $contribution->is_test; |
| 981 | $pledgeParams['acknowledge_date'] = date('Ymd'); |
| 982 | $pledgeParams['original_installment_amount'] = $pledgeParams['installment_amount']; |
| 983 | |
| 984 | //inherit campaign from contirb page. |
| 985 | $pledgeParams['campaign_id'] = CRM_Utils_Array::value('campaign_id', $contributionParams); |
| 986 | |
| 987 | $pledge = CRM_Pledge_BAO_Pledge::create($pledgeParams); |
| 988 | |
| 989 | $form->_params['pledge_id'] = $pledge->id; |
| 990 | |
| 991 | //send acknowledgment email. only when pledge is created |
| 992 | if ($pledge->id) { |
| 993 | //build params to send acknowledgment. |
| 994 | $pledgeParams['id'] = $pledge->id; |
| 995 | $pledgeParams['receipt_from_name'] = $form->_values['receipt_from_name']; |
| 996 | $pledgeParams['receipt_from_email'] = $form->_values['receipt_from_email']; |
| 997 | |
| 998 | //scheduled amount will be same as installment_amount. |
| 999 | $pledgeParams['scheduled_amount'] = $pledgeParams['installment_amount']; |
| 1000 | |
| 1001 | //get total pledge amount. |
| 1002 | $pledgeParams['total_pledge_amount'] = $pledge->amount; |
| 1003 | |
| 1004 | CRM_Pledge_BAO_Pledge::sendAcknowledgment($form, $pledgeParams); |
| 1005 | } |
| 1006 | } |
| 1007 | } |
| 1008 | |
| 1009 | if ($online && $contribution) { |
| 1010 | CRM_Core_BAO_CustomValueTable::postProcess($params, |
| 1011 | 'civicrm_contribution', |
| 1012 | $contribution->id, |
| 1013 | 'Contribution' |
| 1014 | ); |
| 1015 | } |
| 1016 | elseif ($contribution) { |
| 1017 | //handle custom data. |
| 1018 | $params['contribution_id'] = $contribution->id; |
| 1019 | if (!empty($params['custom']) && |
| 1020 | is_array($params['custom']) && |
| 1021 | !is_a($contribution, 'CRM_Core_Error') |
| 1022 | ) { |
| 1023 | CRM_Core_BAO_CustomValueTable::store($params['custom'], 'civicrm_contribution', $contribution->id); |
| 1024 | } |
| 1025 | } |
| 1026 | // Save note |
| 1027 | if ($contribution && !empty($params['contribution_note'])) { |
| 1028 | $noteParams = array( |
| 1029 | 'entity_table' => 'civicrm_contribution', |
| 1030 | 'note' => $params['contribution_note'], |
| 1031 | 'entity_id' => $contribution->id, |
| 1032 | 'contact_id' => $contribution->contact_id, |
| 1033 | 'modified_date' => date('Ymd'), |
| 1034 | ); |
| 1035 | |
| 1036 | CRM_Core_BAO_Note::add($noteParams, array()); |
| 1037 | } |
| 1038 | |
| 1039 | if (isset($params['related_contact'])) { |
| 1040 | $contactID = $params['related_contact']; |
| 1041 | } |
| 1042 | elseif (isset($params['cms_contactID'])) { |
| 1043 | $contactID = $params['cms_contactID']; |
| 1044 | } |
| 1045 | |
| 1046 | //create contribution activity w/ individual and target |
| 1047 | //activity w/ organisation contact id when onbelf, CRM-4027 |
| 1048 | $targetContactID = NULL; |
| 1049 | if (!empty($params['hidden_onbehalf_profile'])) { |
| 1050 | $targetContactID = $contribution->contact_id; |
| 1051 | $contribution->contact_id = $contactID; |
| 1052 | } |
| 1053 | |
| 1054 | // create an activity record |
| 1055 | if ($contribution) { |
| 1056 | CRM_Activity_BAO_Activity::addActivity($contribution, NULL, $targetContactID); |
| 1057 | } |
| 1058 | |
| 1059 | $transaction->commit(); |
| 1060 | // CRM-13074 - create the CMSUser after the transaction is completed as it |
| 1061 | // is not appropriate to delete a valid contribution if a user create problem occurs |
| 1062 | CRM_Contribute_BAO_Contribution_Utils::createCMSUser($params, |
| 1063 | $contactID, |
| 1064 | 'email-' . $billingLocationID |
| 1065 | ); |
| 1066 | return $contribution; |
| 1067 | } |
| 1068 | |
| 1069 | /** |
| 1070 | * Create the recurring contribution record. |
| 1071 | * |
| 1072 | * @param CRM_Core_Form $form |
| 1073 | * @param array $params |
| 1074 | * @param int $contactID |
| 1075 | * @param string $contributionType |
| 1076 | * @param bool $online |
| 1077 | * |
| 1078 | * @return mixed |
| 1079 | */ |
| 1080 | public static function processRecurringContribution(&$form, &$params, $contactID, $contributionType, $online = TRUE) { |
| 1081 | // return if this page is not set for recurring |
| 1082 | // or the user has not chosen the recurring option |
| 1083 | |
| 1084 | //this is online case validation. |
| 1085 | if ((empty($form->_values['is_recur']) && $online) || empty($params['is_recur'])) { |
| 1086 | return NULL; |
| 1087 | } |
| 1088 | |
| 1089 | $recurParams = array('contact_id' => $contactID); |
| 1090 | $recurParams['amount'] = CRM_Utils_Array::value('amount', $params); |
| 1091 | $recurParams['auto_renew'] = CRM_Utils_Array::value('auto_renew', $params); |
| 1092 | $recurParams['frequency_unit'] = CRM_Utils_Array::value('frequency_unit', $params); |
| 1093 | $recurParams['frequency_interval'] = CRM_Utils_Array::value('frequency_interval', $params); |
| 1094 | $recurParams['installments'] = CRM_Utils_Array::value('installments', $params); |
| 1095 | $recurParams['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $params); |
| 1096 | $recurParams['currency'] = CRM_Utils_Array::value('currency', $params); |
| 1097 | |
| 1098 | // CRM-14354: For an auto-renewing membership with an additional contribution, |
| 1099 | // if separate payments is not enabled, make sure only the membership fee recurs |
| 1100 | if (!empty($form->_membershipBlock) |
| 1101 | && $form->_membershipBlock['is_separate_payment'] === '0' |
| 1102 | && isset($params['selectMembership']) |
| 1103 | && $form->_values['is_allow_other_amount'] == '1' |
| 1104 | // CRM-16331 |
| 1105 | && !empty($form->_membershipTypeValues) |
| 1106 | && !empty($form->_membershipTypeValues[$params['selectMembership']]['minimum_fee']) |
| 1107 | ) { |
| 1108 | $recurParams['amount'] = $form->_membershipTypeValues[$params['selectMembership']]['minimum_fee']; |
| 1109 | } |
| 1110 | |
| 1111 | $recurParams['is_test'] = 0; |
| 1112 | if (($form->_action & CRM_Core_Action::PREVIEW) || |
| 1113 | (isset($form->_mode) && ($form->_mode == 'test')) |
| 1114 | ) { |
| 1115 | $recurParams['is_test'] = 1; |
| 1116 | } |
| 1117 | |
| 1118 | $recurParams['start_date'] = $recurParams['create_date'] = $recurParams['modified_date'] = date('YmdHis'); |
| 1119 | if (!empty($params['receive_date'])) { |
| 1120 | $recurParams['start_date'] = $params['receive_date']; |
| 1121 | } |
| 1122 | $recurParams['invoice_id'] = CRM_Utils_Array::value('invoiceID', $params); |
| 1123 | $recurParams['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending'); |
| 1124 | $recurParams['payment_processor_id'] = CRM_Utils_Array::value('payment_processor_id', $params); |
| 1125 | $recurParams['is_email_receipt'] = CRM_Utils_Array::value('is_email_receipt', $params); |
| 1126 | // we need to add a unique trxn_id to avoid a unique key error |
| 1127 | // in paypal IPN we reset this when paypal sends us the real trxn id, CRM-2991 |
| 1128 | $recurParams['trxn_id'] = CRM_Utils_Array::value('trxn_id', $params, $params['invoiceID']); |
| 1129 | $recurParams['financial_type_id'] = $contributionType->id; |
| 1130 | |
| 1131 | if (!$online || $form->_values['is_monetary']) { |
| 1132 | $recurParams['payment_instrument_id'] = 1; |
| 1133 | } |
| 1134 | |
| 1135 | $campaignId = CRM_Utils_Array::value('campaign_id', $params); |
| 1136 | if ($online) { |
| 1137 | if (!array_key_exists('campaign_id', $params)) { |
| 1138 | $campaignId = CRM_Utils_Array::value('campaign_id', $form->_values); |
| 1139 | } |
| 1140 | } |
| 1141 | $recurParams['campaign_id'] = $campaignId; |
| 1142 | |
| 1143 | $recurring = CRM_Contribute_BAO_ContributionRecur::add($recurParams); |
| 1144 | if (is_a($recurring, 'CRM_Core_Error')) { |
| 1145 | CRM_Core_Error::displaySessionError($recurring); |
| 1146 | $urlString = 'civicrm/contribute/transact'; |
| 1147 | $urlParams = '_qf_Main_display=true'; |
| 1148 | if (get_class($form) == 'CRM_Contribute_Form_Contribution') { |
| 1149 | $urlString = 'civicrm/contact/view/contribution'; |
| 1150 | $urlParams = "action=add&cid={$form->_contactID}"; |
| 1151 | if ($form->_mode) { |
| 1152 | $urlParams .= "&mode={$form->_mode}"; |
| 1153 | } |
| 1154 | } |
| 1155 | CRM_Utils_System::redirect(CRM_Utils_System::url($urlString, $urlParams)); |
| 1156 | } |
| 1157 | |
| 1158 | return $recurring->id; |
| 1159 | } |
| 1160 | |
| 1161 | /** |
| 1162 | * Add on behalf of organization and it's location. |
| 1163 | * |
| 1164 | * This situation occurs when on behalf of is enabled for the contribution page and the person |
| 1165 | * signing up does so on behalf of an organization. |
| 1166 | * |
| 1167 | * @param array $behalfOrganization |
| 1168 | * array of organization info. |
| 1169 | * @param int $contactID |
| 1170 | * individual contact id. One. |
| 1171 | * who is doing the process of signup / contribution. |
| 1172 | * |
| 1173 | * @param array $values |
| 1174 | * form values array. |
| 1175 | * @param array $params |
| 1176 | * @param array $fields |
| 1177 | * Array of fields from the onbehalf profile relevant to the organization. |
| 1178 | */ |
| 1179 | public static function processOnBehalfOrganization(&$behalfOrganization, &$contactID, &$values, &$params, $fields = NULL) { |
| 1180 | $isCurrentEmployer = FALSE; |
| 1181 | $dupeIDs = array(); |
| 1182 | $orgID = NULL; |
| 1183 | if (!empty($behalfOrganization['organization_id']) && empty($behalfOrganization['org_option'])) { |
| 1184 | $orgID = $behalfOrganization['organization_id']; |
| 1185 | unset($behalfOrganization['organization_id']); |
| 1186 | $isCurrentEmployer = TRUE; |
| 1187 | } |
| 1188 | |
| 1189 | // formalities for creating / editing organization. |
| 1190 | $behalfOrganization['contact_type'] = 'Organization'; |
| 1191 | |
| 1192 | // get the relationship type id |
| 1193 | $relType = new CRM_Contact_DAO_RelationshipType(); |
| 1194 | $relType->name_a_b = 'Employee of'; |
| 1195 | $relType->find(TRUE); |
| 1196 | $relTypeId = $relType->id; |
| 1197 | |
| 1198 | // keep relationship params ready |
| 1199 | $relParams['relationship_type_id'] = $relTypeId . '_a_b'; |
| 1200 | $relParams['is_permission_a_b'] = 1; |
| 1201 | $relParams['is_active'] = 1; |
| 1202 | |
| 1203 | if (!$orgID) { |
| 1204 | // check if matching organization contact exists |
| 1205 | $dedupeParams = CRM_Dedupe_Finder::formatParams($behalfOrganization, 'Organization'); |
| 1206 | $dedupeParams['check_permission'] = FALSE; |
| 1207 | $dupeIDs = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Organization', 'Unsupervised'); |
| 1208 | |
| 1209 | // CRM-6243 says to pick the first org even if more than one match |
| 1210 | if (count($dupeIDs) >= 1) { |
| 1211 | $behalfOrganization['contact_id'] = $orgID = $dupeIDs[0]; |
| 1212 | // don't allow name edit |
| 1213 | unset($behalfOrganization['organization_name']); |
| 1214 | } |
| 1215 | } |
| 1216 | else { |
| 1217 | // if found permissioned related organization, allow location edit |
| 1218 | $behalfOrganization['contact_id'] = $orgID; |
| 1219 | // don't allow name edit |
| 1220 | unset($behalfOrganization['organization_name']); |
| 1221 | } |
| 1222 | |
| 1223 | // handling for image url |
| 1224 | if (!empty($behalfOrganization['image_URL'])) { |
| 1225 | CRM_Contact_BAO_Contact::processImageParams($behalfOrganization); |
| 1226 | } |
| 1227 | |
| 1228 | // create organization, add location |
| 1229 | $orgID = CRM_Contact_BAO_Contact::createProfileContact($behalfOrganization, $fields, $orgID, |
| 1230 | NULL, NULL, 'Organization' |
| 1231 | ); |
| 1232 | // create relationship |
| 1233 | $relParams['contact_check'][$orgID] = 1; |
| 1234 | $cid = array('contact' => $contactID); |
| 1235 | CRM_Contact_BAO_Relationship::legacyCreateMultiple($relParams, $cid); |
| 1236 | |
| 1237 | // if multiple match - send a duplicate alert |
| 1238 | if ($dupeIDs && (count($dupeIDs) > 1)) { |
| 1239 | $values['onbehalf_dupe_alert'] = 1; |
| 1240 | // required for IPN |
| 1241 | $params['onbehalf_dupe_alert'] = 1; |
| 1242 | } |
| 1243 | |
| 1244 | // make sure organization-contact-id is considered for recording |
| 1245 | // contribution/membership etc.. |
| 1246 | if ($contactID != $orgID) { |
| 1247 | // take a note of contact-id, so we can send the |
| 1248 | // receipt to individual contact as well. |
| 1249 | |
| 1250 | // required for mailing/template display ..etc |
| 1251 | $values['related_contact'] = $contactID; |
| 1252 | // required for IPN |
| 1253 | $params['related_contact'] = $contactID; |
| 1254 | |
| 1255 | //make this employee of relationship as current |
| 1256 | //employer / employee relationship, CRM-3532 |
| 1257 | if ($isCurrentEmployer && |
| 1258 | ($orgID != CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactID, 'employer_id')) |
| 1259 | ) { |
| 1260 | $isCurrentEmployer = FALSE; |
| 1261 | } |
| 1262 | |
| 1263 | if (!$isCurrentEmployer && $orgID) { |
| 1264 | //build current employer params |
| 1265 | $currentEmpParams[$contactID] = $orgID; |
| 1266 | CRM_Contact_BAO_Contact_Utils::setCurrentEmployer($currentEmpParams); |
| 1267 | } |
| 1268 | |
| 1269 | // contribution / signup will be done using this |
| 1270 | // organization id. |
| 1271 | $contactID = $orgID; |
| 1272 | } |
| 1273 | } |
| 1274 | |
| 1275 | /** |
| 1276 | * Function used to save pcp / soft credit entry. |
| 1277 | * |
| 1278 | * This is used by contribution and also event pcps |
| 1279 | * |
| 1280 | * @param array $params |
| 1281 | * @param object $contribution |
| 1282 | * Contribution object. |
| 1283 | */ |
| 1284 | public static function processPcpSoft(&$params, &$contribution) { |
| 1285 | // Add soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin. |
| 1286 | if (!empty($params['soft_credit_to'])) { |
| 1287 | $contributionSoftParams = array(); |
| 1288 | foreach (array( |
| 1289 | 'pcp_display_in_roll', |
| 1290 | 'pcp_roll_nickname', |
| 1291 | 'pcp_personal_note', |
| 1292 | 'amount', |
| 1293 | ) as $val) { |
| 1294 | if (!empty($params[$val])) { |
| 1295 | $contributionSoftParams[$val] = $params[$val]; |
| 1296 | } |
| 1297 | } |
| 1298 | |
| 1299 | $contributionSoftParams['contact_id'] = $params['soft_credit_to']; |
| 1300 | // add contribution id |
| 1301 | $contributionSoftParams['contribution_id'] = $contribution->id; |
| 1302 | // add pcp id |
| 1303 | $contributionSoftParams['pcp_id'] = $params['pcp_made_through_id']; |
| 1304 | |
| 1305 | $contributionSoftParams['soft_credit_type_id'] = CRM_Core_OptionGroup::getValue('soft_credit_type', 'pcp', 'name'); |
| 1306 | |
| 1307 | $contributionSoft = CRM_Contribute_BAO_ContributionSoft::add($contributionSoftParams); |
| 1308 | |
| 1309 | //Send notification to owner for PCP |
| 1310 | if ($contributionSoft->id && $contributionSoft->pcp_id) { |
| 1311 | CRM_Contribute_Form_Contribution_Confirm::pcpNotifyOwner($contribution, $contributionSoft); |
| 1312 | } |
| 1313 | } |
| 1314 | } |
| 1315 | |
| 1316 | /** |
| 1317 | * Function used to send notification mail to pcp owner. |
| 1318 | * |
| 1319 | * This is used by contribution and also event PCPs. |
| 1320 | * |
| 1321 | * @param object $contribution |
| 1322 | * @param object $contributionSoft |
| 1323 | * Contribution object. |
| 1324 | */ |
| 1325 | public static function pcpNotifyOwner($contribution, $contributionSoft) { |
| 1326 | $params = array('id' => $contributionSoft->pcp_id); |
| 1327 | CRM_Core_DAO::commonRetrieve('CRM_PCP_DAO_PCP', $params, $pcpInfo); |
| 1328 | $ownerNotifyID = CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCPBlock', $pcpInfo['pcp_block_id'], 'owner_notify_id'); |
| 1329 | |
| 1330 | if ($ownerNotifyID != CRM_Core_OptionGroup::getValue('pcp_owner_notify', 'no_notifications', 'name') && |
| 1331 | (($ownerNotifyID == CRM_Core_OptionGroup::getValue('pcp_owner_notify', 'owner_chooses', 'name') && |
| 1332 | CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCP', $contributionSoft->pcp_id, 'is_notify')) || |
| 1333 | $ownerNotifyID == CRM_Core_OptionGroup::getValue('pcp_owner_notify', 'all_owners', 'name'))) { |
| 1334 | $pcpInfoURL = CRM_Utils_System::url('civicrm/pcp/info', |
| 1335 | "reset=1&id={$contributionSoft->pcp_id}", |
| 1336 | TRUE, NULL, FALSE, TRUE |
| 1337 | ); |
| 1338 | // set email in the template here |
| 1339 | // get the billing location type |
| 1340 | $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id', array(), 'validate'); |
| 1341 | $billingLocationTypeId = array_search('Billing', $locationTypes); |
| 1342 | |
| 1343 | if ($billingLocationTypeId) { |
| 1344 | list($donorName, $email) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contribution->contact_id, FALSE, $billingLocationTypeId); |
| 1345 | } |
| 1346 | // get primary location email if no email exist( for billing location). |
| 1347 | if (!$email) { |
| 1348 | list($donorName, $email) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contribution->contact_id); |
| 1349 | } |
| 1350 | list($ownerName, $ownerEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contributionSoft->contact_id); |
| 1351 | $tplParams = array( |
| 1352 | 'page_title' => $pcpInfo['title'], |
| 1353 | 'receive_date' => $contribution->receive_date, |
| 1354 | 'total_amount' => $contributionSoft->amount, |
| 1355 | 'donors_display_name' => $donorName, |
| 1356 | 'donors_email' => $email, |
| 1357 | 'pcpInfoURL' => $pcpInfoURL, |
| 1358 | 'is_honor_roll_enabled' => $contributionSoft->pcp_display_in_roll, |
| 1359 | 'currency' => $contributionSoft->currency, |
| 1360 | ); |
| 1361 | $domainValues = CRM_Core_BAO_Domain::getNameAndEmail(); |
| 1362 | $sendTemplateParams = array( |
| 1363 | 'groupName' => 'msg_tpl_workflow_contribution', |
| 1364 | 'valueName' => 'pcp_owner_notify', |
| 1365 | 'contactId' => $contributionSoft->contact_id, |
| 1366 | 'toEmail' => $ownerEmail, |
| 1367 | 'toName' => $ownerName, |
| 1368 | 'from' => "$domainValues[0] <$domainValues[1]>", |
| 1369 | 'tplParams' => $tplParams, |
| 1370 | 'PDFFilename' => 'receipt.pdf', |
| 1371 | ); |
| 1372 | CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams); |
| 1373 | } |
| 1374 | } |
| 1375 | |
| 1376 | /** |
| 1377 | * Function used to se pcp related defaults / params. |
| 1378 | * |
| 1379 | * This is used by contribution and also event PCPs |
| 1380 | * |
| 1381 | * @param CRM_Core_Form $page |
| 1382 | * Form object. |
| 1383 | * @param array $params |
| 1384 | * |
| 1385 | * @return array |
| 1386 | */ |
| 1387 | public static function processPcp(&$page, $params) { |
| 1388 | $params['pcp_made_through_id'] = $page->_pcpId; |
| 1389 | $page->assign('pcpBlock', TRUE); |
| 1390 | if (!empty($params['pcp_display_in_roll']) && empty($params['pcp_roll_nickname'])) { |
| 1391 | $params['pcp_roll_nickname'] = ts('Anonymous'); |
| 1392 | $params['pcp_is_anonymous'] = 1; |
| 1393 | } |
| 1394 | else { |
| 1395 | $params['pcp_is_anonymous'] = 0; |
| 1396 | } |
| 1397 | foreach (array( |
| 1398 | 'pcp_display_in_roll', |
| 1399 | 'pcp_is_anonymous', |
| 1400 | 'pcp_roll_nickname', |
| 1401 | 'pcp_personal_note', |
| 1402 | ) as $val) { |
| 1403 | if (!empty($params[$val])) { |
| 1404 | $page->assign($val, $params[$val]); |
| 1405 | } |
| 1406 | } |
| 1407 | |
| 1408 | return $params; |
| 1409 | } |
| 1410 | |
| 1411 | /** |
| 1412 | * Process membership. |
| 1413 | * |
| 1414 | * @param array $membershipParams |
| 1415 | * @param int $contactID |
| 1416 | * @param array $customFieldsFormatted |
| 1417 | * @param array $fieldTypes |
| 1418 | * @param array $premiumParams |
| 1419 | * @param array $membershipLineItems |
| 1420 | * Line items specifically relating to memberships. |
| 1421 | * @param bool $isPayLater |
| 1422 | */ |
| 1423 | protected function processMembership($membershipParams, $contactID, $customFieldsFormatted, $fieldTypes, $premiumParams, |
| 1424 | $membershipLineItems, $isPayLater) { |
| 1425 | |
| 1426 | $membershipTypeIDs = (array) $membershipParams['selectMembership']; |
| 1427 | $membershipTypes = CRM_Member_BAO_Membership::buildMembershipTypeValues($this, $membershipTypeIDs); |
| 1428 | $membershipType = empty($membershipTypes) ? array() : reset($membershipTypes); |
| 1429 | $isPending = $this->getIsPending(); |
| 1430 | |
| 1431 | $this->assign('membership_name', CRM_Utils_Array::value('name', $membershipType)); |
| 1432 | |
| 1433 | $isPaidMembership = FALSE; |
| 1434 | if ($this->_amount >= 0.0 && isset($membershipParams['amount'])) { |
| 1435 | //amount must be greater than zero for |
| 1436 | //adding contribution record to contribution table. |
| 1437 | //this condition arises when separate membership payment is |
| 1438 | //enabled and contribution amount is not selected. fix for CRM-3010 |
| 1439 | $isPaidMembership = TRUE; |
| 1440 | } |
| 1441 | $isProcessSeparateMembershipTransaction = $this->isSeparateMembershipTransaction($this->_id, $this->_values['amount_block_is_active']); |
| 1442 | |
| 1443 | if ($this->_values['amount_block_is_active']) { |
| 1444 | $financialTypeID = $this->_values['financial_type_id']; |
| 1445 | } |
| 1446 | else { |
| 1447 | $financialTypeID = CRM_Utils_Array::value('financial_type_id', $membershipType, CRM_Utils_Array::value('financial_type_id', $membershipParams)); |
| 1448 | } |
| 1449 | |
| 1450 | if (CRM_Utils_Array::value('membership_source', $this->_params)) { |
| 1451 | $membershipParams['contribution_source'] = $this->_params['membership_source']; |
| 1452 | } |
| 1453 | |
| 1454 | $this->postProcessMembership($membershipParams, $contactID, |
| 1455 | $this, $premiumParams, $customFieldsFormatted, $fieldTypes, $membershipType, $membershipTypeIDs, $isPaidMembership, $this->_membershipId, $isProcessSeparateMembershipTransaction, $financialTypeID, |
| 1456 | $membershipLineItems, $isPayLater, $isPending); |
| 1457 | |
| 1458 | $this->assign('membership_assign', TRUE); |
| 1459 | $this->set('membershipTypeID', $membershipParams['selectMembership']); |
| 1460 | } |
| 1461 | |
| 1462 | /** |
| 1463 | * Process the Memberships. |
| 1464 | * |
| 1465 | * @param array $membershipParams |
| 1466 | * Array of membership fields. |
| 1467 | * @param int $contactID |
| 1468 | * Contact id. |
| 1469 | * @param CRM_Contribute_Form_Contribution_Confirm $form |
| 1470 | * Confirmation form object. |
| 1471 | * |
| 1472 | * @param array $premiumParams |
| 1473 | * @param null $customFieldsFormatted |
| 1474 | * @param null $includeFieldTypes |
| 1475 | * |
| 1476 | * @param array $membershipDetails |
| 1477 | * |
| 1478 | * @param array $membershipTypeIDs |
| 1479 | * |
| 1480 | * @param bool $isPaidMembership |
| 1481 | * @param array $membershipID |
| 1482 | * |
| 1483 | * @param bool $isProcessSeparateMembershipTransaction |
| 1484 | * |
| 1485 | * @param int $financialTypeID |
| 1486 | * @param array $membershipLineItems |
| 1487 | * Line items specific to membership payment that is separate to contribution. |
| 1488 | * @param bool $isPayLater |
| 1489 | * @param bool $isPending |
| 1490 | * |
| 1491 | * @throws \CRM_Core_Exception |
| 1492 | */ |
| 1493 | protected function postProcessMembership( |
| 1494 | $membershipParams, $contactID, &$form, $premiumParams, |
| 1495 | $customFieldsFormatted = NULL, $includeFieldTypes = NULL, $membershipDetails, $membershipTypeIDs, $isPaidMembership, $membershipID, |
| 1496 | $isProcessSeparateMembershipTransaction, $financialTypeID, $membershipLineItems, $isPayLater, $isPending) { |
| 1497 | $membershipContribution = NULL; |
| 1498 | $isTest = CRM_Utils_Array::value('is_test', $membershipParams, FALSE); |
| 1499 | $errors = $createdMemberships = $paymentResult = array(); |
| 1500 | |
| 1501 | if ($isPaidMembership) { |
| 1502 | if ($isProcessSeparateMembershipTransaction) { |
| 1503 | // If we have 2 transactions only one can use the invoice id. |
| 1504 | $membershipParams['invoiceID'] .= '-2'; |
| 1505 | } |
| 1506 | |
| 1507 | $paymentResult = CRM_Contribute_BAO_Contribution_Utils::processConfirm($form, $membershipParams, |
| 1508 | $contactID, |
| 1509 | $financialTypeID, |
| 1510 | 'membership', |
| 1511 | $isTest |
| 1512 | ); |
| 1513 | |
| 1514 | if (!empty($paymentResult['contribution'])) { |
| 1515 | $this->postProcessPremium($premiumParams, $paymentResult['contribution']); |
| 1516 | //note that this will be over-written if we are using a separate membership transaction. Otherwise there is only one |
| 1517 | $membershipContribution = $paymentResult['contribution']; |
| 1518 | // Save the contribution ID so that I can be used in email receipts |
| 1519 | // For example, if you need to generate a tax receipt for the donation only. |
| 1520 | $form->_values['contribution_other_id'] = $membershipContribution->id; |
| 1521 | } |
| 1522 | } |
| 1523 | |
| 1524 | if ($isProcessSeparateMembershipTransaction) { |
| 1525 | try { |
| 1526 | $form->_lineItem = $membershipLineItems; |
| 1527 | if (empty($form->_params['auto_renew']) && !empty($membershipParams['is_recur'])) { |
| 1528 | unset($membershipParams['is_recur']); |
| 1529 | } |
| 1530 | $membershipContribution = $this->processSecondaryFinancialTransaction($contactID, $form, $membershipParams, |
| 1531 | $isTest, $membershipLineItems, CRM_Utils_Array::value('minimum_fee', $membershipDetails, 0), CRM_Utils_Array::value('financial_type_id', $membershipDetails)); |
| 1532 | } |
| 1533 | catch (CRM_Core_Exception $e) { |
| 1534 | $errors[2] = $e->getMessage(); |
| 1535 | $membershipContribution = NULL; |
| 1536 | } |
| 1537 | } |
| 1538 | |
| 1539 | $membership = NULL; |
| 1540 | if (!empty($membershipContribution) && !is_a($membershipContribution, 'CRM_Core_Error')) { |
| 1541 | $membershipContributionID = $membershipContribution->id; |
| 1542 | } |
| 1543 | |
| 1544 | //@todo - why is this nested so deep? it seems like it could be just set on the calling function on the form layer |
| 1545 | if (isset($membershipParams['onbehalf']) && !empty($membershipParams['onbehalf']['member_campaign_id'])) { |
| 1546 | $form->_params['campaign_id'] = $membershipParams['onbehalf']['member_campaign_id']; |
| 1547 | } |
| 1548 | //@todo it should no longer be possible for it to get to this point & membership to not be an array |
| 1549 | if (is_array($membershipTypeIDs) && !empty($membershipContributionID)) { |
| 1550 | $typesTerms = CRM_Utils_Array::value('types_terms', $membershipParams, array()); |
| 1551 | foreach ($membershipTypeIDs as $memType) { |
| 1552 | $numTerms = CRM_Utils_Array::value($memType, $typesTerms, 1); |
| 1553 | if (!empty($membershipContribution)) { |
| 1554 | $pendingStatus = CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name'); |
| 1555 | $pending = ($membershipContribution->contribution_status_id == $pendingStatus) ? TRUE : FALSE; |
| 1556 | } |
| 1557 | else { |
| 1558 | $pending = $isPending; |
| 1559 | } |
| 1560 | $contributionRecurID = isset($form->_params['contributionRecurID']) ? $form->_params['contributionRecurID'] : NULL; |
| 1561 | |
| 1562 | $membershipSource = NULL; |
| 1563 | if (!empty($form->_params['membership_source'])) { |
| 1564 | $membershipSource = $form->_params['membership_source']; |
| 1565 | } |
| 1566 | elseif (isset($form->_values['title']) && !empty($form->_values['title'])) { |
| 1567 | $membershipSource = ts('Online Contribution:') . ' ' . $form->_values['title']; |
| 1568 | } |
| 1569 | $isPayLater = NULL; |
| 1570 | if (isset($form->_params)) { |
| 1571 | $isPayLater = CRM_Utils_Array::value('is_pay_later', $form->_params); |
| 1572 | } |
| 1573 | $campaignId = NULL; |
| 1574 | if (isset($form->_values) && is_array($form->_values) && !empty($form->_values)) { |
| 1575 | $campaignId = CRM_Utils_Array::value('campaign_id', $form->_params); |
| 1576 | if (!array_key_exists('campaign_id', $form->_params)) { |
| 1577 | $campaignId = CRM_Utils_Array::value('campaign_id', $form->_values); |
| 1578 | } |
| 1579 | } |
| 1580 | |
| 1581 | list($membership, $renewalMode, $dates) = CRM_Member_BAO_Membership::renewMembership( |
| 1582 | $contactID, $memType, $isTest, |
| 1583 | date('YmdHis'), CRM_Utils_Array::value('cms_contactID', $membershipParams), |
| 1584 | $customFieldsFormatted, |
| 1585 | $numTerms, $membershipID, $pending, |
| 1586 | $contributionRecurID, $membershipSource, $isPayLater, $campaignId |
| 1587 | ); |
| 1588 | $form->set('renewal_mode', $renewalMode); |
| 1589 | if (!empty($dates)) { |
| 1590 | $form->assign('mem_start_date', |
| 1591 | CRM_Utils_Date::customFormat($dates['start_date'], '%Y%m%d') |
| 1592 | ); |
| 1593 | $form->assign('mem_end_date', |
| 1594 | CRM_Utils_Date::customFormat($dates['end_date'], '%Y%m%d') |
| 1595 | ); |
| 1596 | } |
| 1597 | |
| 1598 | if (!empty($membershipContribution)) { |
| 1599 | // update recurring id for membership record |
| 1600 | CRM_Member_BAO_Membership::updateRecurMembership($membership, $membershipContribution); |
| 1601 | CRM_Member_BAO_Membership::linkMembershipPayment($membership, $membershipContribution); |
| 1602 | } |
| 1603 | } |
| 1604 | if ($form->_priceSetId && !empty($form->_useForMember) && !empty($form->_lineItem)) { |
| 1605 | foreach ($form->_lineItem[$form->_priceSetId] as & $priceFieldOp) { |
| 1606 | if (!empty($priceFieldOp['membership_type_id']) && |
| 1607 | isset($createdMemberships[$priceFieldOp['membership_type_id']]) |
| 1608 | ) { |
| 1609 | $membershipOb = $createdMemberships[$priceFieldOp['membership_type_id']]; |
| 1610 | $priceFieldOp['start_date'] = $membershipOb->start_date ? CRM_Utils_Date::customFormat($membershipOb->start_date, '%B %E%f, %Y') : '-'; |
| 1611 | $priceFieldOp['end_date'] = $membershipOb->end_date ? CRM_Utils_Date::customFormat($membershipOb->end_date, '%B %E%f, %Y') : '-'; |
| 1612 | } |
| 1613 | else { |
| 1614 | $priceFieldOp['start_date'] = $priceFieldOp['end_date'] = 'N/A'; |
| 1615 | } |
| 1616 | } |
| 1617 | $form->_values['lineItem'] = $form->_lineItem; |
| 1618 | $form->assign('lineItem', $form->_lineItem); |
| 1619 | } |
| 1620 | } |
| 1621 | |
| 1622 | if (!empty($errors)) { |
| 1623 | $message = $this->compileErrorMessage($errors); |
| 1624 | throw new CRM_Core_Exception($message); |
| 1625 | } |
| 1626 | $form->_params['createdMembershipIDs'] = array(); |
| 1627 | |
| 1628 | // CRM-7851 - Moved after processing Payment Errors |
| 1629 | //@todo - the reasoning for this being here seems a little outdated |
| 1630 | foreach ($createdMemberships as $createdMembership) { |
| 1631 | CRM_Core_BAO_CustomValueTable::postProcess( |
| 1632 | $form->_params, |
| 1633 | 'civicrm_membership', |
| 1634 | $createdMembership->id, |
| 1635 | 'Membership' |
| 1636 | ); |
| 1637 | $form->_params['createdMembershipIDs'][] = $createdMembership->id; |
| 1638 | } |
| 1639 | if (count($createdMemberships) == 1) { |
| 1640 | //presumably this is only relevant for exactly 1 membership |
| 1641 | $form->_params['membershipID'] = $createdMembership->id; |
| 1642 | } |
| 1643 | |
| 1644 | //CRM-15232: Check if membership is created and on the basis of it use |
| 1645 | //membership receipt template to send payment receipt |
| 1646 | if (count($createdMemberships)) { |
| 1647 | $form->_values['isMembership'] = TRUE; |
| 1648 | } |
| 1649 | if (isset($membershipContributionID)) { |
| 1650 | $form->_values['contribution_id'] = $membershipContributionID; |
| 1651 | } |
| 1652 | if ($form->_contributeMode) { |
| 1653 | if ($form->_values['is_monetary'] && $form->_amount > 0.0 && !$form->_params['is_pay_later']) { |
| 1654 | // call postProcess hook before leaving |
| 1655 | $form->postProcessHook(); |
| 1656 | } |
| 1657 | $payment = Civi\Payment\System::singleton()->getByProcessor($form->_paymentProcessor); |
| 1658 | $paymentActionResult = $payment->doPayment($form->_params, 'contribute'); |
| 1659 | $this->completeTransaction($paymentActionResult, $paymentResult['contribution']->id); |
| 1660 | // Do not send an email if Recurring transaction is done via Direct Mode |
| 1661 | // Email will we sent when the IPN is received. |
| 1662 | return; |
| 1663 | } |
| 1664 | |
| 1665 | //finally send an email receipt |
| 1666 | CRM_Contribute_BAO_ContributionPage::sendMail($contactID, |
| 1667 | $form->_values, |
| 1668 | $isTest, FALSE, |
| 1669 | $includeFieldTypes |
| 1670 | ); |
| 1671 | } |
| 1672 | |
| 1673 | /** |
| 1674 | * Turn array of errors into message string. |
| 1675 | * |
| 1676 | * @param array $errors |
| 1677 | * |
| 1678 | * @return string |
| 1679 | */ |
| 1680 | protected function compileErrorMessage($errors) { |
| 1681 | foreach ($errors as $error) { |
| 1682 | if (is_string($error)) { |
| 1683 | $message[] = $error; |
| 1684 | } |
| 1685 | } |
| 1686 | return ts('Payment Processor Error message') . ': ' . implode('<br/>', $message); |
| 1687 | } |
| 1688 | |
| 1689 | /** |
| 1690 | * Where a second separate financial transaction is supported we will process it here. |
| 1691 | * |
| 1692 | * @param int $contactID |
| 1693 | * @param CRM_Contribute_Form_Contribution_Confirm $form |
| 1694 | * @param array $tempParams |
| 1695 | * @param bool $isTest |
| 1696 | * @param array $lineItems |
| 1697 | * @param $minimumFee |
| 1698 | * @param int $financialTypeID |
| 1699 | * |
| 1700 | * @throws CRM_Core_Exception |
| 1701 | * @throws Exception |
| 1702 | * @return CRM_Contribute_BAO_Contribution |
| 1703 | */ |
| 1704 | protected function processSecondaryFinancialTransaction($contactID, &$form, $tempParams, $isTest, $lineItems, $minimumFee, |
| 1705 | $financialTypeID) { |
| 1706 | $financialType = new CRM_Financial_DAO_FinancialType(); |
| 1707 | $financialType->id = $financialTypeID; |
| 1708 | $financialType->find(TRUE); |
| 1709 | $tempParams['amount'] = $minimumFee; |
| 1710 | $tempParams['invoiceID'] = md5(uniqid(rand(), TRUE)); |
| 1711 | |
| 1712 | //assign receive date when separate membership payment |
| 1713 | //and contribution amount not selected. |
| 1714 | if ($form->_amount == 0) { |
| 1715 | $now = date('YmdHis'); |
| 1716 | $form->_params['receive_date'] = $now; |
| 1717 | $receiveDate = CRM_Utils_Date::mysqlToIso($now); |
| 1718 | $form->set('params', $form->_params); |
| 1719 | $form->assign('receive_date', $receiveDate); |
| 1720 | } |
| 1721 | |
| 1722 | $form->set('membership_amount', $minimumFee); |
| 1723 | $form->assign('membership_amount', $minimumFee); |
| 1724 | |
| 1725 | // we don't need to create the user twice, so lets disable cms_create_account |
| 1726 | // irrespective of the value, CRM-2888 |
| 1727 | $tempParams['cms_create_account'] = 0; |
| 1728 | |
| 1729 | //set this variable as we are not creating pledge for |
| 1730 | //separate membership payment contribution. |
| 1731 | //so for differentiating membership contribution from |
| 1732 | //main contribution. |
| 1733 | $form->_params['separate_membership_payment'] = 1; |
| 1734 | $contributionParams = array( |
| 1735 | 'contact_id' => $contactID, |
| 1736 | 'line_item' => $lineItems, |
| 1737 | 'is_test' => $isTest, |
| 1738 | 'campaign_id' => CRM_Utils_Array::value('campaign_id', $tempParams, CRM_Utils_Array::value('campaign_id', |
| 1739 | $form->_values)), |
| 1740 | 'contribution_page_id' => $form->_id, |
| 1741 | 'source' => CRM_Utils_Array::value('source', $tempParams, CRM_Utils_Array::value('description', $tempParams)), |
| 1742 | ); |
| 1743 | $isMonetary = !empty($form->_values['is_monetary']); |
| 1744 | if ($isMonetary) { |
| 1745 | if (empty($paymentParams['is_pay_later'])) { |
| 1746 | $contributionParams['payment_instrument_id'] = $form->_paymentProcessor['payment_instrument_id']; |
| 1747 | } |
| 1748 | } |
| 1749 | $membershipContribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($form, |
| 1750 | $tempParams, |
| 1751 | $tempParams, |
| 1752 | $contributionParams, |
| 1753 | $financialType, |
| 1754 | TRUE, |
| 1755 | $form->_bltID |
| 1756 | ); |
| 1757 | |
| 1758 | if ($form->_values['is_monetary'] && !$form->_params['is_pay_later'] && $minimumFee > 0.0) { |
| 1759 | // At the moment our tests are calling this form in a way that leaves 'object' empty. For |
| 1760 | // now we compensate here. |
| 1761 | if (empty($form->_paymentProcessor['object'])) { |
| 1762 | $payment = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor); |
| 1763 | } |
| 1764 | else { |
| 1765 | $payment = $form->_paymentProcessor['object']; |
| 1766 | } |
| 1767 | $result = $payment->doPayment($tempParams, 'contribute'); |
| 1768 | $form->set('membership_trx_id', $result['trxn_id']); |
| 1769 | $form->assign('membership_trx_id', $result['trxn_id']); |
| 1770 | $this->completeTransaction($result, $membershipContribution->id); |
| 1771 | } |
| 1772 | |
| 1773 | return $membershipContribution; |
| 1774 | } |
| 1775 | |
| 1776 | /** |
| 1777 | * Is the payment a pending payment. |
| 1778 | * |
| 1779 | * We are moving towards always creating as pending and updating at the end (based on payment), so this should be |
| 1780 | * an interim refactoring. It was shared with another unrelated form & some parameters may not apply to this form. |
| 1781 | * |
| 1782 | * |
| 1783 | * @return bool |
| 1784 | */ |
| 1785 | protected function getIsPending() { |
| 1786 | if (((isset($this->_contributeMode)) || !empty |
| 1787 | ($this->_params['is_pay_later']) |
| 1788 | ) && |
| 1789 | (($this->_values['is_monetary'] && $this->_amount > 0.0)) |
| 1790 | ) { |
| 1791 | return TRUE; |
| 1792 | } |
| 1793 | return FALSE; |
| 1794 | } |
| 1795 | |
| 1796 | /** |
| 1797 | * Are we going to do 2 financial transactions. |
| 1798 | * |
| 1799 | * Ie the membership block supports a separate transactions AND the contribution form has been configured for a |
| 1800 | * contribution |
| 1801 | * transaction AND a membership transaction AND the payment processor supports double financial transactions (ie. NOT doTransferPayment style) |
| 1802 | * |
| 1803 | * @param int $formID |
| 1804 | * @param bool $amountBlockActiveOnForm |
| 1805 | * |
| 1806 | * @return bool |
| 1807 | */ |
| 1808 | public function isSeparateMembershipTransaction($formID, $amountBlockActiveOnForm) { |
| 1809 | $memBlockDetails = CRM_Member_BAO_Membership::getMembershipBlock($formID); |
| 1810 | if (!empty($memBlockDetails['is_separate_payment']) && $amountBlockActiveOnForm) { |
| 1811 | return TRUE; |
| 1812 | } |
| 1813 | return FALSE; |
| 1814 | } |
| 1815 | |
| 1816 | /** |
| 1817 | * This function sets the fields. |
| 1818 | * |
| 1819 | * - $this->_params['amount_level'] |
| 1820 | * - $this->_params['selectMembership'] |
| 1821 | * And under certain circumstances sets |
| 1822 | * $this->_params['amount'] = null; |
| 1823 | * |
| 1824 | * @param int $priceSetID |
| 1825 | */ |
| 1826 | public function setFormAmountFields($priceSetID) { |
| 1827 | $isQuickConfig = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_params['priceSetId'], 'is_quick_config'); |
| 1828 | $priceField = new CRM_Price_DAO_PriceField(); |
| 1829 | $priceField->price_set_id = $priceSetID; |
| 1830 | $priceField->orderBy('weight'); |
| 1831 | $priceField->find(); |
| 1832 | $paramWeDoNotUnderstand = NULL; |
| 1833 | |
| 1834 | while ($priceField->fetch()) { |
| 1835 | if ($priceField->name == "contribution_amount") { |
| 1836 | $paramWeDoNotUnderstand = $priceField->id; |
| 1837 | } |
| 1838 | if ($isQuickConfig && !empty($this->_params["price_{$priceField->id}"])) { |
| 1839 | if ($this->_values['fee'][$priceField->id]['html_type'] != 'Text') { |
| 1840 | $this->_params['amount_level'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', |
| 1841 | $this->_params["price_{$priceField->id}"], 'label'); |
| 1842 | } |
| 1843 | if ($priceField->name == "membership_amount") { |
| 1844 | $this->_params['selectMembership'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', |
| 1845 | $this->_params["price_{$priceField->id}"], 'membership_type_id'); |
| 1846 | } |
| 1847 | } |
| 1848 | // If separate payment we set contribution amount to be null, so that it will not show contribution amount same |
| 1849 | // as membership amount. |
| 1850 | // @todo - this needs more documentation - it appears the setting to null is tied up with separate membership payments |
| 1851 | // but the circumstances are very confusing. Many of these conditions are repeated in the next conditional |
| 1852 | // so we should merge them together |
| 1853 | // the quick config seems like a red-herring - if this is about a separate membership payment then there |
| 1854 | // are 2 types of line items - membership ones & non-membership ones - regardless of whether quick config is set |
| 1855 | elseif ( |
| 1856 | CRM_Utils_Array::value('is_separate_payment', $this->_membershipBlock) |
| 1857 | && !empty($this->_values['fee'][$priceField->id]) |
| 1858 | && ($this->_values['fee'][$priceField->id]['name'] == "other_amount") |
| 1859 | && CRM_Utils_Array::value("price_{$paramWeDoNotUnderstand}", $this->_params) < 1 |
| 1860 | && empty($this->_params["price_{$priceField->id}"]) |
| 1861 | ) { |
| 1862 | $this->_params['amount'] = NULL; |
| 1863 | } |
| 1864 | |
| 1865 | // Fix for CRM-14375 - If we are using separate payments and "no |
| 1866 | // thank you" is selected for the additional contribution, set |
| 1867 | // contribution amount to be null, so that it will not show |
| 1868 | // contribution amount same as membership amount. |
| 1869 | //@todo - merge with section above |
| 1870 | if ($this->_membershipBlock['is_separate_payment'] |
| 1871 | && !empty($this->_values['fee'][$priceField->id]) |
| 1872 | && CRM_Utils_Array::value('name', $this->_values['fee'][$priceField->id]) == 'contribution_amount' |
| 1873 | && CRM_Utils_Array::value("price_{$priceField->id}", $this->_params) == '-1' |
| 1874 | ) { |
| 1875 | $this->_params['amount'] = NULL; |
| 1876 | } |
| 1877 | } |
| 1878 | } |
| 1879 | |
| 1880 | /** |
| 1881 | * Submit function. |
| 1882 | * |
| 1883 | * @param array $params |
| 1884 | * |
| 1885 | * @throws CiviCRM_API3_Exception |
| 1886 | */ |
| 1887 | public static function submit($params) { |
| 1888 | $form = new CRM_Contribute_Form_Contribution_Confirm(); |
| 1889 | $form->_id = $params['id']; |
| 1890 | |
| 1891 | CRM_Contribute_BAO_ContributionPage::setValues($form->_id, $form->_values); |
| 1892 | $form->_separateMembershipPayment = CRM_Contribute_BAO_ContributionPage::getIsMembershipPayment($form->_id); |
| 1893 | //this way the mocked up controller ignores the session stuff |
| 1894 | $_SERVER['REQUEST_METHOD'] = 'GET'; |
| 1895 | $form->controller = new CRM_Contribute_Controller_Contribution(); |
| 1896 | $params['invoiceID'] = md5(uniqid(rand(), TRUE)); |
| 1897 | $paramsProcessedForForm = $form->_params = self::getFormParams($params['id'], $params); |
| 1898 | $form->_amount = $params['amount']; |
| 1899 | $priceSetID = $form->_params['priceSetId'] = $paramsProcessedForForm['price_set_id']; |
| 1900 | $priceFields = CRM_Price_BAO_PriceSet::getSetDetail($priceSetID); |
| 1901 | $priceSetFields = reset($priceFields); |
| 1902 | $form->_values['fee'] = $priceSetFields['fields']; |
| 1903 | $form->_priceSetId = $priceSetID; |
| 1904 | $form->setFormAmountFields($priceSetID); |
| 1905 | if (!empty($params['payment_processor_id'])) { |
| 1906 | $form->_paymentProcessor = civicrm_api3('payment_processor', 'getsingle', array( |
| 1907 | 'id' => $params['payment_processor_id'], |
| 1908 | )); |
| 1909 | if ($form->_paymentProcessor['billing_mode'] == 1) { |
| 1910 | $form->_contributeMode = 'direct'; |
| 1911 | } |
| 1912 | else { |
| 1913 | $form->_contributeMode = 'notify'; |
| 1914 | } |
| 1915 | } |
| 1916 | else { |
| 1917 | $form->_params['payment_processor_id'] = 0; |
| 1918 | } |
| 1919 | $priceFields = $priceFields[$priceSetID]['fields']; |
| 1920 | CRM_Price_BAO_PriceSet::processAmount($priceFields, $paramsProcessedForForm, $lineItems, 'civicrm_contribution'); |
| 1921 | $form->_lineItem = array($priceSetID => $lineItems); |
| 1922 | $form->processFormSubmission(CRM_Utils_Array::value('contact_id', $params)); |
| 1923 | } |
| 1924 | |
| 1925 | /** |
| 1926 | * Helper function for static submit function. |
| 1927 | * |
| 1928 | * Set relevant params - help us to build up an array that we can pass in. |
| 1929 | * |
| 1930 | * @param int $id |
| 1931 | * @param array $params |
| 1932 | * |
| 1933 | * @return array |
| 1934 | * @throws CiviCRM_API3_Exception |
| 1935 | */ |
| 1936 | public static function getFormParams($id, array $params) { |
| 1937 | if (!isset($params['is_pay_later'])) { |
| 1938 | if (!empty($params['payment_processor_id'])) { |
| 1939 | $params['is_pay_later'] = 0; |
| 1940 | } |
| 1941 | else { |
| 1942 | $params['is_pay_later'] = civicrm_api3('contribution_page', 'getvalue', array( |
| 1943 | 'id' => $id, |
| 1944 | 'return' => 'is_pay_later', |
| 1945 | )); |
| 1946 | } |
| 1947 | } |
| 1948 | if (empty($params['price_set_id'])) { |
| 1949 | $params['price_set_id'] = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $params['id']); |
| 1950 | } |
| 1951 | return $params; |
| 1952 | } |
| 1953 | |
| 1954 | /** |
| 1955 | * Post form submission handling. |
| 1956 | * |
| 1957 | * This is also called from the test suite. |
| 1958 | * |
| 1959 | * @param int $contactID |
| 1960 | * |
| 1961 | * @return array |
| 1962 | */ |
| 1963 | protected function processFormSubmission($contactID) { |
| 1964 | $isPayLater = $this->_params['is_pay_later']; |
| 1965 | if (isset($this->_params['payment_processor_id']) && $this->_params['payment_processor_id'] == 0) { |
| 1966 | $this->_params['is_pay_later'] = $isPayLater = TRUE; |
| 1967 | } |
| 1968 | // add a description field at the very beginning |
| 1969 | $this->_params['description'] = ts('Online Contribution') . ': ' . (($this->_pcpInfo['title']) ? $this->_pcpInfo['title'] : $this->_values['title']); |
| 1970 | |
| 1971 | $this->_params['accountingCode'] = CRM_Utils_Array::value('accountingCode', $this->_values); |
| 1972 | |
| 1973 | // fix currency ID |
| 1974 | $this->_params['currencyID'] = CRM_Core_Config::singleton()->defaultCurrency; |
| 1975 | |
| 1976 | //carry payment processor id. |
| 1977 | if (CRM_Utils_Array::value('id', $this->_paymentProcessor)) { |
| 1978 | $this->_params['payment_processor_id'] = $this->_paymentProcessor['id']; |
| 1979 | } |
| 1980 | |
| 1981 | $premiumParams = $membershipParams = $params = $this->_params; |
| 1982 | if (!empty($params['image_URL'])) { |
| 1983 | CRM_Contact_BAO_Contact::processImageParams($params); |
| 1984 | } |
| 1985 | |
| 1986 | $fields = array('email-Primary' => 1); |
| 1987 | |
| 1988 | // get the add to groups |
| 1989 | $addToGroups = array(); |
| 1990 | |
| 1991 | // now set the values for the billing location. |
| 1992 | foreach ($this->_fields as $name => $value) { |
| 1993 | $fields[$name] = 1; |
| 1994 | |
| 1995 | // get the add to groups for uf fields |
| 1996 | if (!empty($value['add_to_group_id'])) { |
| 1997 | $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id']; |
| 1998 | } |
| 1999 | } |
| 2000 | |
| 2001 | if (!array_key_exists('first_name', $fields)) { |
| 2002 | $nameFields = array('first_name', 'middle_name', 'last_name'); |
| 2003 | foreach ($nameFields as $name) { |
| 2004 | $fields[$name] = 1; |
| 2005 | if (array_key_exists("billing_$name", $params)) { |
| 2006 | $params[$name] = $params["billing_{$name}"]; |
| 2007 | $params['preserveDBName'] = TRUE; |
| 2008 | } |
| 2009 | } |
| 2010 | } |
| 2011 | |
| 2012 | // billing email address |
| 2013 | $fields["email-{$this->_bltID}"] = 1; |
| 2014 | |
| 2015 | //unset the billing parameters if it is pay later mode |
| 2016 | //to avoid creation of billing location |
| 2017 | if ($isPayLater && !$this->_isBillingAddressRequiredForPayLater) { |
| 2018 | $billingFields = array( |
| 2019 | 'billing_first_name', |
| 2020 | 'billing_middle_name', |
| 2021 | 'billing_last_name', |
| 2022 | "billing_street_address-{$this->_bltID}", |
| 2023 | "billing_city-{$this->_bltID}", |
| 2024 | "billing_state_province-{$this->_bltID}", |
| 2025 | "billing_state_province_id-{$this->_bltID}", |
| 2026 | "billing_postal_code-{$this->_bltID}", |
| 2027 | "billing_country-{$this->_bltID}", |
| 2028 | "billing_country_id-{$this->_bltID}", |
| 2029 | ); |
| 2030 | |
| 2031 | foreach ($billingFields as $value) { |
| 2032 | unset($params[$value]); |
| 2033 | unset($fields[$value]); |
| 2034 | } |
| 2035 | } |
| 2036 | |
| 2037 | // if onbehalf-of-organization contribution, take out |
| 2038 | // organization params in a separate variable, to make sure |
| 2039 | // normal behavior is continued. And use that variable to |
| 2040 | // process on-behalf-of functionality. |
| 2041 | if (!empty($this->_params['hidden_onbehalf_profile'])) { |
| 2042 | $behalfOrganization = array(); |
| 2043 | $orgFields = array('organization_name', 'organization_id', 'org_option'); |
| 2044 | foreach ($orgFields as $fld) { |
| 2045 | if (array_key_exists($fld, $params)) { |
| 2046 | $behalfOrganization[$fld] = $params[$fld]; |
| 2047 | unset($params[$fld]); |
| 2048 | } |
| 2049 | } |
| 2050 | |
| 2051 | if (is_array($params['onbehalf']) && !empty($params['onbehalf'])) { |
| 2052 | foreach ($params['onbehalf'] as $fld => $values) { |
| 2053 | if (strstr($fld, 'custom_')) { |
| 2054 | $behalfOrganization[$fld] = $values; |
| 2055 | } |
| 2056 | elseif (!(strstr($fld, '-'))) { |
| 2057 | if (in_array($fld, array( |
| 2058 | 'contribution_campaign_id', |
| 2059 | 'member_campaign_id', |
| 2060 | ))) { |
| 2061 | $fld = 'campaign_id'; |
| 2062 | } |
| 2063 | else { |
| 2064 | $behalfOrganization[$fld] = $values; |
| 2065 | } |
| 2066 | $this->_params[$fld] = $values; |
| 2067 | } |
| 2068 | } |
| 2069 | } |
| 2070 | |
| 2071 | if (array_key_exists('onbehalf_location', $params) && is_array($params['onbehalf_location'])) { |
| 2072 | foreach ($params['onbehalf_location'] as $block => $vals) { |
| 2073 | //fix for custom data (of type checkbox, multi-select) |
| 2074 | if (substr($block, 0, 7) == 'custom_') { |
| 2075 | continue; |
| 2076 | } |
| 2077 | // fix the index of block elements |
| 2078 | if (is_array($vals)) { |
| 2079 | foreach ($vals as $key => $val) { |
| 2080 | //dont adjust the index of address block as |
| 2081 | //it's index is WRT to location type |
| 2082 | $newKey = ($block == 'address') ? $key : ++$key; |
| 2083 | $behalfOrganization[$block][$newKey] = $val; |
| 2084 | } |
| 2085 | } |
| 2086 | } |
| 2087 | unset($params['onbehalf_location']); |
| 2088 | } |
| 2089 | if (!empty($params['onbehalf[image_URL]'])) { |
| 2090 | $behalfOrganization['image_URL'] = $params['onbehalf[image_URL]']; |
| 2091 | } |
| 2092 | } |
| 2093 | |
| 2094 | // check for profile double opt-in and get groups to be subscribed |
| 2095 | $subscribeGroupIds = CRM_Core_BAO_UFGroup::getDoubleOptInGroupIds($params, $contactID); |
| 2096 | |
| 2097 | // since we are directly adding contact to group lets unset it from mailing |
| 2098 | if (!empty($addToGroups)) { |
| 2099 | foreach ($addToGroups as $groupId) { |
| 2100 | if (isset($subscribeGroupIds[$groupId])) { |
| 2101 | unset($subscribeGroupIds[$groupId]); |
| 2102 | } |
| 2103 | } |
| 2104 | } |
| 2105 | |
| 2106 | foreach ($addToGroups as $k) { |
| 2107 | if (array_key_exists($k, $subscribeGroupIds)) { |
| 2108 | unset($addToGroups[$k]); |
| 2109 | } |
| 2110 | } |
| 2111 | |
| 2112 | if (empty($contactID)) { |
| 2113 | $dupeParams = $params; |
| 2114 | if (!empty($dupeParams['onbehalf'])) { |
| 2115 | unset($dupeParams['onbehalf']); |
| 2116 | } |
| 2117 | if (!empty($dupeParams['honor'])) { |
| 2118 | unset($dupeParams['honor']); |
| 2119 | } |
| 2120 | |
| 2121 | $dedupeParams = CRM_Dedupe_Finder::formatParams($dupeParams, 'Individual'); |
| 2122 | $dedupeParams['check_permission'] = FALSE; |
| 2123 | $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Individual'); |
| 2124 | |
| 2125 | // if we find more than one contact, use the first one |
| 2126 | $contactID = CRM_Utils_Array::value(0, $ids); |
| 2127 | |
| 2128 | // Fetch default greeting id's if creating a contact |
| 2129 | if (!$contactID) { |
| 2130 | foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) { |
| 2131 | if (!isset($params[$greeting])) { |
| 2132 | $params[$greeting] = CRM_Contact_BAO_Contact_Utils::defaultGreeting('Individual', $greeting); |
| 2133 | } |
| 2134 | } |
| 2135 | } |
| 2136 | $contactType = NULL; |
| 2137 | } |
| 2138 | else { |
| 2139 | $contactType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactID, 'contact_type'); |
| 2140 | } |
| 2141 | $contactID = CRM_Contact_BAO_Contact::createProfileContact( |
| 2142 | $params, |
| 2143 | $fields, |
| 2144 | $contactID, |
| 2145 | $addToGroups, |
| 2146 | NULL, |
| 2147 | $contactType, |
| 2148 | TRUE |
| 2149 | ); |
| 2150 | |
| 2151 | // Make the contact ID associated with the contribution available at the Class level. |
| 2152 | // Also make available to the session. |
| 2153 | //@todo consider handling this in $this->getContactID(); |
| 2154 | $this->set('contactID', $contactID); |
| 2155 | $this->_contactID = $contactID; |
| 2156 | |
| 2157 | //get email primary first if exist |
| 2158 | $subscriptionEmail = array('email' => CRM_Utils_Array::value('email-Primary', $params)); |
| 2159 | if (!$subscriptionEmail['email']) { |
| 2160 | $subscriptionEmail['email'] = CRM_Utils_Array::value("email-{$this->_bltID}", $params); |
| 2161 | } |
| 2162 | // subscribing contact to groups |
| 2163 | if (!empty($subscribeGroupIds) && $subscriptionEmail['email']) { |
| 2164 | CRM_Mailing_Event_BAO_Subscribe::commonSubscribe($subscribeGroupIds, $subscriptionEmail, $contactID); |
| 2165 | } |
| 2166 | |
| 2167 | // If onbehalf-of-organization contribution / signup, add organization |
| 2168 | // and it's location. |
| 2169 | if (isset($params['hidden_onbehalf_profile']) && isset($behalfOrganization['organization_name'])) { |
| 2170 | $ufFields = array(); |
| 2171 | foreach ($this->_fields['onbehalf'] as $name => $value) { |
| 2172 | $ufFields[$name] = 1; |
| 2173 | } |
| 2174 | self::processOnBehalfOrganization($behalfOrganization, $contactID, $this->_values, |
| 2175 | $this->_params, $ufFields |
| 2176 | ); |
| 2177 | } |
| 2178 | elseif (!empty($this->_membershipContactID) && $contactID != $this->_membershipContactID) { |
| 2179 | // this is an onbehalf renew case for inherited membership. For e.g a permissioned member of household, |
| 2180 | // store current user id as related contact for later use for mailing / activity.. |
| 2181 | $this->_values['related_contact'] = $contactID; |
| 2182 | $this->_params['related_contact'] = $contactID; |
| 2183 | // swap contact like we do for on-behalf-org case, so parent/primary membership is affected |
| 2184 | $contactID = $this->_membershipContactID; |
| 2185 | } |
| 2186 | |
| 2187 | // lets store the contactID in the session |
| 2188 | // for things like tell a friend |
| 2189 | $session = CRM_Core_Session::singleton(); |
| 2190 | if (!$session->get('userID')) { |
| 2191 | $session->set('transaction.userID', $contactID); |
| 2192 | } |
| 2193 | else { |
| 2194 | $session->set('transaction.userID', NULL); |
| 2195 | } |
| 2196 | |
| 2197 | $this->_useForMember = $this->get('useForMember'); |
| 2198 | |
| 2199 | // store the fact that this is a membership and membership type is selected |
| 2200 | if ((!empty($membershipParams['selectMembership']) && |
| 2201 | $membershipParams['selectMembership'] != 'no_thanks' |
| 2202 | ) || |
| 2203 | $this->_useForMember |
| 2204 | ) { |
| 2205 | if (!$this->_useForMember) { |
| 2206 | $this->assign('membership_assign', TRUE); |
| 2207 | $this->set('membershipTypeID', $this->_params['selectMembership']); |
| 2208 | } |
| 2209 | |
| 2210 | if ($this->_action & CRM_Core_Action::PREVIEW) { |
| 2211 | $membershipParams['is_test'] = 1; |
| 2212 | } |
| 2213 | if ($this->_params['is_pay_later']) { |
| 2214 | $membershipParams['is_pay_later'] = 1; |
| 2215 | } |
| 2216 | |
| 2217 | //inherit campaign from contribution page. |
| 2218 | if (!array_key_exists('campaign_id', $membershipParams)) { |
| 2219 | $membershipParams['campaign_id'] = CRM_Utils_Array::value('campaign_id', $this->_values); |
| 2220 | } |
| 2221 | |
| 2222 | CRM_Core_Payment_Form::mapParams($this->_bltID, $this->_params, $membershipParams, TRUE); |
| 2223 | $this->doMembershipProcessing($contactID, $membershipParams, $premiumParams, $isPayLater); |
| 2224 | } |
| 2225 | else { |
| 2226 | // at this point we've created a contact and stored its address etc |
| 2227 | // all the payment processors expect the name and address to be in the |
| 2228 | // so we copy stuff over to first_name etc. |
| 2229 | $paymentParams = $this->_params; |
| 2230 | |
| 2231 | if (!empty($paymentParams['onbehalf']) && |
| 2232 | is_array($paymentParams['onbehalf']) |
| 2233 | ) { |
| 2234 | foreach ($paymentParams['onbehalf'] as $key => $value) { |
| 2235 | if (strstr($key, 'custom_')) { |
| 2236 | $this->_params[$key] = $value; |
| 2237 | } |
| 2238 | } |
| 2239 | } |
| 2240 | |
| 2241 | $result = CRM_Contribute_BAO_Contribution_Utils::processConfirm($this, $paymentParams, |
| 2242 | $contactID, |
| 2243 | $this->wrangleFinancialTypeID($this->_values['financial_type_id']), |
| 2244 | 'contribution', |
| 2245 | ($this->_mode == 'test') ? 1 : 0 |
| 2246 | ); |
| 2247 | |
| 2248 | if (empty($result['is_payment_failure'])) { |
| 2249 | // @todo move premium processing to complete transaction if it truly is an 'after' action. |
| 2250 | $this->postProcessPremium($premiumParams, $result['contribution']); |
| 2251 | } |
| 2252 | if (!empty($result['contribution'])) { |
| 2253 | // Not quite sure why it would be empty at this stage but tests show it can be ... at least in tests. |
| 2254 | $this->completeTransaction($result, $result['contribution']->id); |
| 2255 | } |
| 2256 | return $result; |
| 2257 | } |
| 2258 | } |
| 2259 | |
| 2260 | /** |
| 2261 | * Membership processing section. |
| 2262 | * |
| 2263 | * This is in a separate function as part of a move towards refactoring. |
| 2264 | * |
| 2265 | * @param int $contactID |
| 2266 | * @param array $membershipParams |
| 2267 | * @param array $premiumParams |
| 2268 | * @param bool $isPayLater |
| 2269 | */ |
| 2270 | protected function doMembershipProcessing($contactID, $membershipParams, $premiumParams, $isPayLater) { |
| 2271 | |
| 2272 | // added new parameter for cms user contact id, needed to distinguish behaviour for on behalf of sign-ups |
| 2273 | if (isset($this->_params['related_contact'])) { |
| 2274 | $membershipParams['cms_contactID'] = $this->_params['related_contact']; |
| 2275 | } |
| 2276 | else { |
| 2277 | $membershipParams['cms_contactID'] = $contactID; |
| 2278 | } |
| 2279 | |
| 2280 | if (!empty($membershipParams['onbehalf']) && |
| 2281 | is_array($membershipParams['onbehalf']) && !empty($membershipParams['onbehalf']['member_campaign_id']) |
| 2282 | ) { |
| 2283 | $this->_params['campaign_id'] = $membershipParams['onbehalf']['member_campaign_id']; |
| 2284 | } |
| 2285 | |
| 2286 | $customFieldsFormatted = $fieldTypes = array(); |
| 2287 | if (!empty($membershipParams['onbehalf']) && |
| 2288 | is_array($membershipParams['onbehalf']) |
| 2289 | ) { |
| 2290 | foreach ($membershipParams['onbehalf'] as $key => $value) { |
| 2291 | if (strstr($key, 'custom_')) { |
| 2292 | $customFieldId = explode('_', $key); |
| 2293 | CRM_Core_BAO_CustomField::formatCustomField( |
| 2294 | $customFieldId[1], |
| 2295 | $customFieldsFormatted, |
| 2296 | $value, |
| 2297 | 'Membership', |
| 2298 | NULL, |
| 2299 | $contactID |
| 2300 | ); |
| 2301 | } |
| 2302 | } |
| 2303 | $fieldTypes = array('Contact', 'Organization', 'Membership'); |
| 2304 | } |
| 2305 | |
| 2306 | $priceFieldIds = $this->get('memberPriceFieldIDS'); |
| 2307 | |
| 2308 | if (!empty($priceFieldIds)) { |
| 2309 | $contributionTypeID = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceFieldIds['id'], 'financial_type_id'); |
| 2310 | unset($priceFieldIds['id']); |
| 2311 | $membershipTypeIds = array(); |
| 2312 | $membershipTypeTerms = array(); |
| 2313 | foreach ($priceFieldIds as $priceFieldId) { |
| 2314 | if ($id = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldId, 'membership_type_id')) { |
| 2315 | $membershipTypeIds[] = $id; |
| 2316 | //@todo the value for $term is immediately overwritten. It is unclear from the code whether it was intentional to |
| 2317 | // do this or a double = was intended (this ambiguity is the reason many IDEs complain about 'assignment in condition' |
| 2318 | $term = 1; |
| 2319 | if ($term = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldId, 'membership_num_terms')) { |
| 2320 | $membershipTypeTerms[$id] = ($term > 1) ? $term : 1; |
| 2321 | } |
| 2322 | else { |
| 2323 | $membershipTypeTerms[$id] = 1; |
| 2324 | } |
| 2325 | } |
| 2326 | } |
| 2327 | $membershipParams['selectMembership'] = $membershipTypeIds; |
| 2328 | $membershipParams['financial_type_id'] = $contributionTypeID; |
| 2329 | $membershipParams['types_terms'] = $membershipTypeTerms; |
| 2330 | } |
| 2331 | if (!empty($membershipParams['selectMembership'])) { |
| 2332 | // CRM-12233 |
| 2333 | $membershipLineItems = array(); |
| 2334 | if ($this->_separateMembershipPayment && $this->_values['amount_block_is_active']) { |
| 2335 | foreach ($this->_values['fee'] as $key => $feeValues) { |
| 2336 | if ($feeValues['name'] == 'membership_amount') { |
| 2337 | $fieldId = $this->_params['price_' . $key]; |
| 2338 | $membershipLineItems[$this->_priceSetId][$fieldId] = $this->_lineItem[$this->_priceSetId][$fieldId]; |
| 2339 | unset($this->_lineItem[$this->_priceSetId][$fieldId]); |
| 2340 | break; |
| 2341 | } |
| 2342 | } |
| 2343 | } |
| 2344 | try { |
| 2345 | $this->processMembership($membershipParams, $contactID, $customFieldsFormatted, $fieldTypes, $premiumParams, $membershipLineItems, $isPayLater); |
| 2346 | } |
| 2347 | catch (CRM_Core_Exception $e) { |
| 2348 | CRM_Core_Session::singleton()->setStatus($e->getMessage()); |
| 2349 | CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/transact', "_qf_Main_display=true&qfKey={$this->_params['qfKey']}")); |
| 2350 | } |
| 2351 | if (!$this->_amount > 0.0 || !$membershipParams['amount']) { |
| 2352 | // we need to explicitly create a CMS user in case of free memberships |
| 2353 | // since it is done under processConfirm for paid memberships |
| 2354 | CRM_Contribute_BAO_Contribution_Utils::createCMSUser($membershipParams, |
| 2355 | $membershipParams['cms_contactID'], |
| 2356 | 'email-' . $this->_bltID |
| 2357 | ); |
| 2358 | } |
| 2359 | } |
| 2360 | } |
| 2361 | |
| 2362 | /** |
| 2363 | * Complete transaction if payment has been processed. |
| 2364 | * |
| 2365 | * Check the result for a success outcome & if paid then complete the transaction. |
| 2366 | * |
| 2367 | * Completing will trigger update of related entities and emails. |
| 2368 | * |
| 2369 | * @param array $result |
| 2370 | * @param int $contributionID |
| 2371 | * |
| 2372 | * @throws \CRM_Core_Exception |
| 2373 | */ |
| 2374 | protected function completeTransaction($result, $contributionID) { |
| 2375 | if (CRM_Utils_Array::value('payment_status_id', $result) == 1) { |
| 2376 | try { |
| 2377 | civicrm_api3('contribution', 'completetransaction', array( |
| 2378 | 'id' => $contributionID, |
| 2379 | 'trxn_id' => CRM_Utils_Array::value('trxn_id', $result), |
| 2380 | 'payment_processor_id' => $this->_paymentProcessor['id'], |
| 2381 | 'is_transactional' => FALSE, |
| 2382 | 'fee_amount' => CRM_Utils_Array::value('fee_amount', $result), |
| 2383 | ) |
| 2384 | ); |
| 2385 | } |
| 2386 | catch (CiviCRM_API3_Exception $e) { |
| 2387 | if ($e->getErrorCode() != 'contribution_completed') { |
| 2388 | throw new CRM_Core_Exception('Failed to update contribution in database'); |
| 2389 | } |
| 2390 | } |
| 2391 | } |
| 2392 | } |
| 2393 | |
| 2394 | } |