* Process the form submission.
*/
public function postProcess() {
- $sendReceipt = $pId = $contribution = $isRelatedId = FALSE;
- $softParams = $softIDs = array();
-
if ($this->_action & CRM_Core_Action::DELETE) {
CRM_Contribute_BAO_Contribution::deleteContribution($this->_id);
CRM_Core_Session::singleton()->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view',
// Get the submitted form values.
$submittedValues = $this->controller->exportValues($this->_name);
- if (!empty($submittedValues['price_set_id']) && $this->_action & CRM_Core_Action::UPDATE) {
- $line = CRM_Price_BAO_LineItem::getLineItems($this->_id, 'contribution');
- $lineID = key($line);
- $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', CRM_Utils_Array::value('price_field_id', $line[$lineID]), 'price_set_id');
- $quickConfig = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'is_quick_config');
- if ($quickConfig) {
- CRM_Price_BAO_LineItem::deleteLineItems($this->_id, 'civicrm_contribution');
+ $contribution = $this->submit($submittedValues);
+ $session = CRM_Core_Session::singleton();
+ $buttonName = $this->controller->getButtonName();
+ if ($this->_context == 'standalone') {
+ if ($buttonName == $this->getButtonName('upload', 'new')) {
+ $session->replaceUserContext(CRM_Utils_System::url('civicrm/contribute/add',
+ 'reset=1&action=add&context=standalone'
+ ));
}
+ else {
+ $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view',
+ "reset=1&cid={$this->_contactID}&selectedChild=contribute"
+ ));
+ }
+ }
+ elseif ($this->_context == 'contribution' && $this->_mode && $buttonName == $this->getButtonName('upload', 'new')) {
+ $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view/contribution',
+ "reset=1&action=add&context={$this->_context}&cid={$this->_contactID}&mode={$this->_mode}"
+ ));
+ }
+ elseif ($buttonName == $this->getButtonName('upload', 'new')) {
+ $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view/contribution',
+ "reset=1&action=add&context={$this->_context}&cid={$this->_contactID}"
+ ));
}
- // Process price set and get total amount and line items.
- $lineItem = array();
- $priceSetId = CRM_Utils_Array::value('price_set_id', $submittedValues);
- if (empty($priceSetId) && !$this->_id) {
- $this->_priceSetId = $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', 'default_contribution_amount', 'id', 'name');
- $this->_priceSet = current(CRM_Price_BAO_PriceSet::getSetDetail($priceSetId));
- $fieldID = key($this->_priceSet['fields']);
- $fieldValueId = key($this->_priceSet['fields'][$fieldID]['options']);
- $this->_priceSet['fields'][$fieldID]['options'][$fieldValueId]['amount'] = $submittedValues['total_amount'];
- $submittedValues['price_' . $fieldID] = 1;
+ //store contribution ID if not yet set (on create)
+ if (empty($this->_id) && !empty($contribution->id)) {
+ $this->_id = $contribution->id;
}
+ }
- if ($priceSetId) {
- CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'],
- $submittedValues, $lineItem[$priceSetId]);
+ /**
+ * Process credit card payment.
+ *
+ * @param array $submittedValues
+ * @param array $lineItem
+ *
+ * @throws CRM_Core_Exception
+ */
+ protected function processCreditCard($submittedValues, $lineItem) {
+ $sendReceipt = $contribution = FALSE;
- // Unset tax amount for offline 'is_quick_config' contribution.
- if ($this->_priceSet['is_quick_config'] &&
- !array_key_exists($submittedValues['financial_type_id'], CRM_Core_PseudoConstant::getTaxRates())
- ) {
- unset($submittedValues['tax_amount']);
+ $unsetParams = array(
+ 'trxn_id',
+ 'payment_instrument_id',
+ 'contribution_status_id',
+ 'cancel_date',
+ 'cancel_reason',
+ );
+ foreach ($unsetParams as $key) {
+ if (isset($submittedValues[$key])) {
+ unset($submittedValues[$key]);
}
- $submittedValues['total_amount'] = CRM_Utils_Array::value('amount', $submittedValues);
}
- if ($this->_id) {
- if ($this->_compId) {
- if ($this->_context == 'participant') {
- $pId = $this->_compId;
- }
- elseif ($this->_context == 'membership') {
- $isRelatedId = TRUE;
- }
- else {
- $pId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_id, 'participant_id', 'contribution_id');
- }
- }
- else {
- $contributionDetails = CRM_Contribute_BAO_Contribution::getComponentDetails($this->_id);
- if (array_key_exists('membership', $contributionDetails)) {
- $isRelatedId = TRUE;
- }
- elseif (array_key_exists('participant', $contributionDetails)) {
- $pId = $contributionDetails['participant'];
- }
- }
+ $isTest = ($this->_mode == 'test') ? 1 : 0;
+ // CRM-12680 set $_lineItem if its not set
+ if (empty($this->_lineItem) && !empty($lineItem)) {
+ $this->_lineItem = $lineItem;
}
- if (!$priceSetId && !empty($submittedValues['total_amount']) && $this->_id) {
- // CRM-10117 update the line items for participants.
- if ($pId) {
- $entityTable = 'participant';
- $entityID = $pId;
- $isRelatedId = FALSE;
- $participantParams = array(
- 'fee_amount' => $submittedValues['total_amount'],
- 'id' => $entityID,
- );
- CRM_Event_BAO_Participant::add($participantParams);
- if (empty($this->_lineItems)) {
- $this->_lineItems[] = CRM_Price_BAO_LineItem::getLineItems($entityID, 'participant', 1);
- }
- }
- else {
- $entityTable = 'contribution';
- $entityID = $this->_id;
- }
- $lineItems = CRM_Price_BAO_LineItem::getLineItems($entityID, $entityTable, NULL, TRUE, $isRelatedId);
- foreach (array_keys($lineItems) as $id) {
- $lineItems[$id]['id'] = $id;
- }
- $itemId = key($lineItems);
- if ($itemId && !empty($lineItems[$itemId]['price_field_id'])) {
- $this->_priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $lineItems[$itemId]['price_field_id'], 'price_set_id');
- }
+ //Get the require fields value only.
+ $params = $this->_params = $submittedValues;
- if ($this->_priceSetId && CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
- $lineItems[$itemId]['unit_price'] = $lineItems[$itemId]['line_total'] = CRM_Utils_Rule::cleanMoney(CRM_Utils_Array::value('total_amount', $submittedValues));
+ $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($this->_params['payment_processor_id'],
+ $this->_mode
+ );
- // Update line total and total amount with tax on edit.
- $financialItemsId = CRM_Core_PseudoConstant::getTaxRates();
- if (array_key_exists($submittedValues['financial_type_id'], $financialItemsId)) {
- $lineItems[$itemId]['tax_rate'] = $financialItemsId[$submittedValues['financial_type_id']];
- }
- else {
- $lineItems[$itemId]['tax_rate'] = $lineItems[$itemId]['tax_amount'] = "";
- $submittedValues['tax_amount'] = 'null';
- }
- if ($lineItems[$itemId]['tax_rate']) {
- $lineItems[$itemId]['tax_amount'] = ($lineItems[$itemId]['tax_rate'] / 100) * $lineItems[$itemId]['line_total'];
- $submittedValues['total_amount'] = $lineItems[$itemId]['line_total'] + $lineItems[$itemId]['tax_amount'];
- $submittedValues['tax_amount'] = $lineItems[$itemId]['tax_amount'];
- }
- }
- // CRM-10117 update the line items for participants.
- if (!empty($lineItems[$itemId]['price_field_id'])) {
- $lineItem[$this->_priceSetId] = $lineItems;
- }
- }
+ // Get the payment processor id as per mode.
+ $this->_params['payment_processor'] = $params['payment_processor_id']
+ = $this->_params['payment_processor_id'] = $submittedValues['payment_processor_id'] = $this->_paymentProcessor['id'];
- $isQuickConfig = 0;
- if ($this->_priceSetId && CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
- $isQuickConfig = 1;
- }
- //CRM-11529 for quick config back office transactions
- //when financial_type_id is passed in form, update the
- //line items with the financial type selected in form
- if ($isQuickConfig && !empty($submittedValues['financial_type_id']) && CRM_Utils_Array::value($this->_priceSetId, $lineItem)
- ) {
- foreach ($lineItem[$this->_priceSetId] as &$values) {
- $values['financial_type_id'] = $submittedValues['financial_type_id'];
- }
- }
+ $now = date('YmdHis');
+ $fields = array();
- if (!isset($submittedValues['total_amount'])) {
- $submittedValues['total_amount'] = CRM_Utils_Array::value('total_amount', $this->_values);
+ // we need to retrieve email address
+ if ($this->_context == 'standalone' && !empty($submittedValues['is_email_receipt'])) {
+ list($this->userDisplayName,
+ $this->userEmail
+ ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
+ $this->assign('displayName', $this->userDisplayName);
}
- $this->assign('lineItem', !empty($lineItem) && !$isQuickConfig ? $lineItem : FALSE);
- if (!empty($submittedValues['pcp_made_through_id'])) {
- $pcp = array();
- $fields = array(
- 'pcp_made_through_id',
- 'pcp_display_in_roll',
- 'pcp_roll_nickname',
- 'pcp_personal_note',
- );
- foreach ($fields as $f) {
- $pcp[$f] = CRM_Utils_Array::value($f, $submittedValues);
- }
- }
+ // Set email for primary location.
+ $fields['email-Primary'] = 1;
+ $params['email-Primary'] = $this->userEmail;
- $isEmpty = array_keys(array_flip($submittedValues['soft_credit_contact_id']));
- if ($this->_id && count($isEmpty) == 1 && key($isEmpty) == NULL) {
- //Delete existing soft credit records if soft credit list is empty on update
- CRM_Contribute_BAO_ContributionSoft::del(array('contribution_id' => $this->_id));
+ // now set the values for the billing location.
+ foreach (array_keys($this->_fields) as $name) {
+ $fields[$name] = 1;
}
- else {
- //build soft credit params
- foreach ($submittedValues['soft_credit_contact_id'] as $key => $val) {
- if ($val && $submittedValues['soft_credit_amount'][$key]) {
- $softParams[$key]['contact_id'] = $val;
- $softParams[$key]['amount'] = CRM_Utils_Rule::cleanMoney($submittedValues['soft_credit_amount'][$key]);
- $softParams[$key]['soft_credit_type_id'] = $submittedValues['soft_credit_type'][$key];
- if (!empty($submittedValues['soft_credit_id'][$key])) {
- $softIDs[] = $softParams[$key]['id'] = $submittedValues['soft_credit_id'][$key];
- }
- }
+
+ // also add location name to the array
+ $params["address_name-{$this->_bltID}"] = CRM_Utils_Array::value('billing_first_name', $params) . ' ' . CRM_Utils_Array::value('billing_middle_name', $params) . ' ' . CRM_Utils_Array::value('billing_last_name', $params);
+
+ $params["address_name-{$this->_bltID}"] = trim($params["address_name-{$this->_bltID}"]);
+ $fields["address_name-{$this->_bltID}"] = 1;
+ $ctype = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
+ $this->_contactID,
+ 'contact_type'
+ );
+
+ $nameFields = array('first_name', 'middle_name', 'last_name');
+ foreach ($nameFields as $name) {
+ $fields[$name] = 1;
+ if (array_key_exists("billing_$name", $params)) {
+ $params[$name] = $params["billing_{$name}"];
+ $params['preserveDBName'] = TRUE;
}
}
- // set the contact, when contact is selected
- if (!empty($submittedValues['contact_id'])) {
- $this->_contactID = $submittedValues['contact_id'];
+ if (!empty($params['source'])) {
+ unset($params['source']);
}
+ $contactID = CRM_Contact_BAO_Contact::createProfileContact($params, $fields,
+ $this->_contactID,
+ NULL, NULL,
+ $ctype
+ );
- // Credit Card Contribution.
- if ($this->_mode) {
- $this->processCreditCard($submittedValues, $lineItem);
+ // add all the additional payment params we need
+ if (!empty($this->_params["billing_state_province_id-{$this->_bltID}"])) {
+ $this->_params["state_province-{$this->_bltID}"] = $this->_params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($this->_params["billing_state_province_id-{$this->_bltID}"]);
+ }
+ if (!empty($this->_params["billing_country_id-{$this->_bltID}"])) {
+ $this->_params["country-{$this->_bltID}"] = $this->_params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($this->_params["billing_country_id-{$this->_bltID}"]);
+ }
+ $legacyCreditCardExpiryCheck = FALSE;
+ if ($this->_paymentProcessor['payment_type'] & CRM_Core_Payment::PAYMENT_TYPE_CREDIT_CARD && !isset($this->_paymentFields)) {
+ $legacyCreditCardExpiryCheck = TRUE;
+ }
+ if ($legacyCreditCardExpiryCheck || in_array('credit_card_exp_date', array_keys($this->_paymentFields))) {
+ $this->_params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($this->_params);
+ $this->_params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($this->_params);
+ }
+ $this->_params['ip_address'] = CRM_Utils_System::ipAddress();
+ $this->_params['amount'] = $this->_params['total_amount'];
+ $this->_params['amount_level'] = 0;
+ $this->_params['description'] = ts('Office Credit Card contribution');
+ $this->_params['currencyID'] = CRM_Utils_Array::value('currency',
+ $this->_params,
+ CRM_Core_Config::singleton()->defaultCurrency
+ );
+ $this->_params['payment_action'] = 'Sale';
+ if (!empty($this->_params['receive_date'])) {
+ $this->_params['receive_date'] = CRM_Utils_Date::processDate($this->_params['receive_date'], $this->_params['receive_date_time']);
}
- else {
- // Offline Contribution.
- $submittedValues = $this->unsetCreditCardFields($submittedValues);
-
- // get the required field value only.
- $formValues = $submittedValues;
- $params = $ids = array();
-
- $params['contact_id'] = $this->_contactID;
-
- $params['currency'] = $this->getCurrency($submittedValues);
- $fields = array(
- 'financial_type_id',
- 'contribution_status_id',
- 'payment_instrument_id',
- 'cancel_reason',
- 'source',
- 'check_number',
- );
- foreach ($fields as $f) {
- $params[$f] = CRM_Utils_Array::value($f, $formValues);
- }
+ if (!empty($params['soft_credit_to'])) {
+ $this->_params['soft_credit_to'] = $params['soft_credit_to'];
+ $this->_params['pcp_made_through_id'] = $params['pcp_made_through_id'];
+ }
- if (!empty($pcp)) {
- $params['pcp'] = $pcp;
- }
- if (!empty($softParams)) {
- $params['soft_credit'] = $softParams;
- $params['soft_credit_ids'] = $softIDs;
- }
+ $this->_params['pcp_display_in_roll'] = CRM_Utils_Array::value('pcp_display_in_roll', $params);
+ $this->_params['pcp_roll_nickname'] = CRM_Utils_Array::value('pcp_roll_nickname', $params);
+ $this->_params['pcp_personal_note'] = CRM_Utils_Array::value('pcp_personal_note', $params);
- // CRM-5740 if priceset is used, no need to cleanup money.
- if ($priceSetId) {
- $params['skipCleanMoney'] = 1;
- }
+ //Add common data to formatted params
+ CRM_Contribute_Form_AdditionalInfo::postProcessCommon($params, $this->_params, $this);
- $dates = array(
- 'receive_date',
- 'receipt_date',
- 'cancel_date',
- );
+ if (empty($this->_params['invoice_id'])) {
+ $this->_params['invoiceID'] = md5(uniqid(rand(), TRUE));
+ }
+ else {
+ $this->_params['invoiceID'] = $this->_params['invoice_id'];
+ }
- foreach ($dates as $d) {
- $params[$d] = CRM_Utils_Date::processDate($formValues[$d], $formValues[$d . '_time'], TRUE);
- }
+ // At this point we've created a contact and stored its address etc
+ // all the payment processors expect the name and address to be in the
+ // so we copy stuff over to first_name etc.
+ $paymentParams = $this->_params;
+ $paymentParams['contactID'] = $this->_contactID;
+ CRM_Core_Payment_Form::mapParams($this->_bltID, $this->_params, $paymentParams, TRUE);
- if (!empty($formValues['is_email_receipt'])) {
- $params['receipt_date'] = date("Y-m-d");
- }
+ $contributionType = new CRM_Financial_DAO_FinancialType();
+ $contributionType->id = $params['financial_type_id'];
- if ($params['contribution_status_id'] == CRM_Core_OptionGroup::getValue('contribution_status', 'Cancelled', 'name')
- || $params['contribution_status_id'] == CRM_Core_OptionGroup::getValue('contribution_status', 'Refunded', 'name')
- ) {
- if (CRM_Utils_System::isNull(CRM_Utils_Array::value('cancel_date', $params))) {
- $params['cancel_date'] = date('Y-m-d');
- }
- }
- else {
- $params['cancel_date'] = $params['cancel_reason'] = 'null';
- }
+ // Add some financial type details to the params list
+ // if folks need to use it.
+ $paymentParams['contributionType_name'] = $this->_params['contributionType_name'] = $contributionType->name;
+ $paymentParams['contributionPageID'] = NULL;
- // Set is_pay_later flag for back-office offline Pending status contributions CRM-8996
- // else if contribution_status is changed to Completed is_pay_later flag is changed to 0, CRM-15041
- if ($params['contribution_status_id'] == CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name')) {
- $params['is_pay_later'] = 1;
- }
- elseif ($params['contribution_status_id'] == CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name')) {
- $params['is_pay_later'] = 0;
- }
+ if (!empty($this->_params['is_email_receipt'])) {
+ $paymentParams['email'] = $this->userEmail;
+ $paymentParams['is_email_receipt'] = 1;
+ }
+ else {
+ $paymentParams['is_email_receipt'] = 0;
+ $this->_params['is_email_receipt'] = 0;
+ }
+ if (!empty($this->_params['receive_date'])) {
+ $paymentParams['receive_date'] = $this->_params['receive_date'];
+ }
- $ids['contribution'] = $params['id'] = $this->_id;
+ // For recurring contribution, create Contribution Record first.
+ // Contribution ID, Recurring ID and Contact ID needed
+ // When we get a callback from the payment processor, CRM-7115
- // Add Additional common information to formatted params.
- CRM_Contribute_Form_AdditionalInfo::postProcessCommon($formValues, $params, $this);
- if ($pId) {
- $params['contribution_mode'] = 'participant';
- $params['participant_id'] = $pId;
- $params['skipLineItem'] = 1;
- }
- elseif ($isRelatedId) {
- $params['contribution_mode'] = 'membership';
- }
- $params['line_item'] = $lineItem;
- $params['payment_processor_id'] = $params['payment_processor'] = CRM_Utils_Array::value('id', $this->_paymentProcessor);
- if (isset($submittedValues['tax_amount'])) {
- $params['tax_amount'] = $submittedValues['tax_amount'];
- }
- //create contribution.
- if ($isQuickConfig) {
- $params['is_quick_config'] = 1;
+ if (!empty($paymentParams['is_recur'])) {
+ $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($this,
+ $this->_params,
+ NULL,
+ $this->_contactID,
+ $contributionType,
+ TRUE,
+ FALSE,
+ $isTest,
+ $this->_lineItem
+ );
+ $paymentParams['contributionID'] = $contribution->id;
+ $paymentParams['contributionTypeID'] = $contribution->financial_type_id;
+ $paymentParams['contributionPageID'] = $contribution->contribution_page_id;
+ $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id;
+ }
+ $result = array();
+ if ($paymentParams['amount'] > 0.0) {
+ // force a re-get of the payment processor in case the form changed it, CRM-7179
+ $payment = CRM_Core_Payment::singleton($this->_mode, $this->_paymentProcessor, $this, TRUE);
+ try {
+ $result = $payment->doPayment($paymentParams, 'contribute');
}
-
- // CRM-11956
- // if non_deductible_amount exists i.e. Additional Details field set was opened [and staff typed something] -
- // if non_deductible_amount does NOT exist - then calculate it depending on:
- // $ContributionType->is_deductible and whether there is a product (premium).
- if (empty($params['non_deductible_amount'])) {
- $contributionType = new CRM_Financial_DAO_FinancialType();
- $contributionType->id = $params['financial_type_id'];
- if (!$contributionType->find(TRUE)) {
- CRM_Core_Error::fatal('Could not find a system table');
- }
- if ($contributionType->is_deductible) {
-
- if (isset($formValues['product_name'][0])) {
- $selectProduct = $formValues['product_name'][0];
- }
- // if there is a product - compare the value to the contribution amount
- if (isset($selectProduct)) {
- $productDAO = new CRM_Contribute_DAO_Product();
- $productDAO->id = $selectProduct;
- $productDAO->find(TRUE);
- // product value exceeds contribution amount
- if ($params['total_amount'] < $productDAO->price) {
- $params['non_deductible_amount'] = $params['total_amount'];
- }
- // product value does NOT exceed contribution amount
- else {
- $params['non_deductible_amount'] = $productDAO->price;
- }
- }
- // contribution is deductible - but there is no product
- else {
- $params['non_deductible_amount'] = '0.00';
- }
+ catch (CRM_Core_Exception $e) {
+ $message = ts("Payment Processor Error message") . $e->getMessage();
+ $this->cleanupDBAfterPaymentFailure($paymentParams, $message);
+ // Set the contribution mode.
+ $urlParams = "action=add&cid={$this->_contactID}";
+ if ($this->_mode) {
+ $urlParams .= "&mode={$this->_mode}";
}
- // contribution is NOT deductible
- else {
- $params['non_deductible_amount'] = $params['total_amount'];
+ if (!empty($this->_ppID)) {
+ $urlParams .= "&context=pledge&ppid={$this->_ppID}";
}
+ CRM_Core_Error::statusBounce($message, $urlParams, ts('Payment Processor Error'));
}
+ }
- $contribution = CRM_Contribute_BAO_Contribution::create($params, $ids);
+ $this->_params = array_merge($this->_params, $result);
- // process associated membership / participant, CRM-4395
- $relatedComponentStatusMsg = NULL;
- if ($contribution->id && $this->_action & CRM_Core_Action::UPDATE) {
- $relatedComponentStatusMsg = $this->updateRelatedComponent($contribution->id,
- $contribution->contribution_status_id,
- CRM_Utils_Array::value('contribution_status_id',
- $this->_values
- ),
- $contribution->receive_date
- );
- }
+ $this->_params['receive_date'] = $now;
- //process note
- if ($contribution->id && isset($formValues['note'])) {
- CRM_Contribute_Form_AdditionalInfo::processNote($formValues, $this->_contactID, $contribution->id, $this->_noteID);
- }
+ if (!empty($this->_params['is_email_receipt'])) {
+ $this->_params['receipt_date'] = $now;
+ }
+ else {
+ $this->_params['receipt_date'] = CRM_Utils_Date::processDate($this->_params['receipt_date'],
+ $params['receipt_date_time'], TRUE
+ );
+ }
- //process premium
- if ($contribution->id && isset($formValues['product_name'][0])) {
- CRM_Contribute_Form_AdditionalInfo::processPremium($formValues, $contribution->id,
- $this->_premiumID, $this->_options
- );
- }
+ $this->set('params', $this->_params);
+ $this->assign('trxn_id', $result['trxn_id']);
+ $this->assign('receive_date', $this->_params['receive_date']);
- // assign tax calculation for contribution receipts
- $taxRate = array();
- $getTaxDetails = FALSE;
- $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
- $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
- if ($invoicing) {
- if ($this->_action & CRM_Core_Action::ADD) {
- $line = $lineItem;
- }
- elseif ($this->_action & CRM_Core_Action::UPDATE) {
- $line = $this->_lineItems;
- }
- foreach ($line as $key => $value) {
- foreach ($value as $v) {
- if (isset($taxRate[(string) CRM_Utils_Array::value('tax_rate', $v)])) {
- $taxRate[(string) $v['tax_rate']] = $taxRate[(string) $v['tax_rate']] + CRM_Utils_Array::value('tax_amount', $v);
- }
- else {
- if (isset($v['tax_rate'])) {
- $taxRate[(string) $v['tax_rate']] = CRM_Utils_Array::value('tax_amount', $v);
- $getTaxDetails = TRUE;
- }
- }
- }
- }
- }
-
- if ($invoicing) {
- if ($this->_action & CRM_Core_Action::UPDATE) {
- if (isset($submittedValues['tax_amount'])) {
- $totalTaxAmount = $submittedValues['tax_amount'];
- }
- else {
- $totalTaxAmount = $this->_values['tax_amount'];
- }
- $this->assign('totalTaxAmount', $totalTaxAmount);
- $this->assign('dataArray', $taxRate);
- }
- else {
- if (!empty($submittedValues['price_set_id'])) {
- $this->assign('totalTaxAmount', $submittedValues['tax_amount']);
- $this->assign('getTaxDetails', $getTaxDetails);
- $this->assign('dataArray', $taxRate);
- $this->assign('taxTerm', CRM_Utils_Array::value('tax_term', $invoiceSettings));
- }
- else {
- $this->assign('totalTaxAmount', CRM_Utils_Array::value('tax_amount', $submittedValues));
- }
- }
- }
-
- //send receipt mail.
- if ($contribution->id && !empty($formValues['is_email_receipt'])) {
- $formValues['contact_id'] = $this->_contactID;
- $formValues['contribution_id'] = $contribution->id;
-
- $formValues += CRM_Contribute_BAO_ContributionSoft::getSoftContribution($contribution->id);
-
- // to get 'from email id' for send receipt
- $this->fromEmailId = $formValues['from_email_address'];
- $sendReceipt = CRM_Contribute_Form_AdditionalInfo::emailReceipt($this, $formValues);
- }
+ // Result has all the stuff we need
+ // lets archive it to a financial transaction
+ if ($contributionType->is_deductible) {
+ $this->assign('is_deductible', TRUE);
+ $this->set('is_deductible', TRUE);
+ }
- $pledgePaymentId = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_PledgePayment',
- $contribution->id,
- 'id',
- 'contribution_id'
+ // Set source if not set
+ if (empty($this->_params['source'])) {
+ $userID = CRM_Core_Session::singleton()->get('userID');
+ $userSortName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $userID,
+ 'sort_name'
);
+ $this->_params['source'] = ts('Submit Credit Card Payment by: %1', array(1 => $userSortName));
+ }
- //update pledge payment status.
- if ((($this->_ppID && $contribution->id) && $this->_action & CRM_Core_Action::ADD) ||
- (($pledgePaymentId) && $this->_action & CRM_Core_Action::UPDATE)
- ) {
+ // Build custom data getFields array
+ $customFieldsContributionType = CRM_Core_BAO_CustomField::getFields('Contribution', FALSE, FALSE,
+ CRM_Utils_Array::value('financial_type_id', $params)
+ );
+ $customFields = CRM_Utils_Array::crmArrayMerge($customFieldsContributionType,
+ CRM_Core_BAO_CustomField::getFields('Contribution', FALSE, FALSE, NULL, NULL, TRUE)
+ );
+ $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params,
+ $customFields,
+ $this->_id,
+ 'Contribution'
+ );
+ if (empty($paymentParams['is_recur'])) {
+ $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($this,
+ $this->_params,
+ $result,
+ $this->_contactID,
+ $contributionType,
+ FALSE, FALSE,
+ $isTest,
+ $this->_lineItem
+ );
+ }
- if ($this->_ppID) {
- //store contribution id in payment record.
- CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', $this->_ppID, 'contribution_id', $contribution->id);
- }
- else {
- $this->_ppID = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_PledgePayment',
- $contribution->id,
- 'id',
- 'contribution_id'
- );
- $this->_pledgeID = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_PledgePayment',
- $contribution->id,
- 'pledge_id',
- 'contribution_id'
- );
- }
+ // Send receipt mail.
+ if ($contribution->id && !empty($this->_params['is_email_receipt'])) {
+ $this->_params['trxn_id'] = CRM_Utils_Array::value('trxn_id', $result);
+ $this->_params['contact_id'] = $this->_contactID;
+ $this->_params['contribution_id'] = $contribution->id;
+ $sendReceipt = CRM_Contribute_Form_AdditionalInfo::emailReceipt($this, $this->_params, TRUE);
+ }
- $adjustTotalAmount = FALSE;
- if (CRM_Utils_Array::value('option_type', $formValues) == 2) {
- $adjustTotalAmount = TRUE;
- }
+ //process the note
+ if ($contribution->id && isset($params['note'])) {
+ CRM_Contribute_Form_AdditionalInfo::processNote($params, $contactID, $contribution->id, NULL);
+ }
+ //process premium
+ if ($contribution->id && isset($params['product_name'][0])) {
+ CRM_Contribute_Form_AdditionalInfo::processPremium($params, $contribution->id, NULL, $this->_options);
+ }
- $updatePledgePaymentStatus = FALSE;
- //do only if either the status or the amount has changed
- if ($this->_action & CRM_Core_Action::ADD) {
- $updatePledgePaymentStatus = TRUE;
- }
- elseif ($this->_action & CRM_Core_Action::UPDATE && (($this->_defaults['contribution_status_id'] != $formValues['contribution_status_id']) ||
- ($this->_defaults['total_amount'] != $formValues['total_amount']))
- ) {
- $updatePledgePaymentStatus = TRUE;
- }
+ //update pledge payment status.
+ if ($this->_ppID && $contribution->id) {
+ // Store contribution id in payment record.
+ CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', $this->_ppID, 'contribution_id', $contribution->id);
- if ($updatePledgePaymentStatus) {
- CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($this->_pledgeID,
- array($this->_ppID),
- $contribution->contribution_status_id,
- NULL,
- $contribution->total_amount,
- $adjustTotalAmount
- );
- }
- }
+ CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($this->_pledgeID,
+ array($this->_ppID),
+ $contribution->contribution_status_id,
+ NULL,
+ $contribution->total_amount
+ );
+ }
- $statusMsg = ts('The contribution record has been saved.');
- if (!empty($formValues['is_email_receipt']) && $sendReceipt) {
+ if ($contribution->id) {
+ $statusMsg = ts('The contribution record has been processed.');
+ if (!empty($this->_params['is_email_receipt']) && $sendReceipt) {
$statusMsg .= ' ' . ts('A receipt has been emailed to the contributor.');
}
-
- if ($relatedComponentStatusMsg) {
- $statusMsg .= ' ' . $relatedComponentStatusMsg;
- }
-
- CRM_Core_Session::setStatus($statusMsg, ts('Saved'), 'success');
- //Offline Contribution ends.
- }
- $session = CRM_Core_Session::singleton();
- $buttonName = $this->controller->getButtonName();
- if ($this->_context == 'standalone') {
- if ($buttonName == $this->getButtonName('upload', 'new')) {
- $session->replaceUserContext(CRM_Utils_System::url('civicrm/contribute/add',
- 'reset=1&action=add&context=standalone'
- ));
- }
- else {
- $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view',
- "reset=1&cid={$this->_contactID}&selectedChild=contribute"
- ));
- }
- }
- elseif ($this->_context == 'contribution' && $this->_mode && $buttonName == $this->getButtonName('upload', 'new')) {
- $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view/contribution',
- "reset=1&action=add&context={$this->_context}&cid={$this->_contactID}&mode={$this->_mode}"
- ));
- }
- elseif ($buttonName == $this->getButtonName('upload', 'new')) {
- $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view/contribution',
- "reset=1&action=add&context={$this->_context}&cid={$this->_contactID}"
- ));
- }
-
- //store contribution ID if not yet set (on create)
- if (empty($this->_id) && !empty($contribution->id)) {
- $this->_id = $contribution->id;
+ CRM_Core_Session::setStatus($statusMsg, ts('Complete'), 'success');
}
}
/**
- * Process credit card payment.
+ * Clean up DB after payment fails.
*
- * @param array $submittedValues
- * @param array $lineItem
+ * This function removes related DB entries. Note that it has been agreed in principle,
+ * but not implemented, that contributions should be retained as 'Failed' rather than
+ * deleted.
*
- * @throws CRM_Core_Exception
+ * @todo it doesn't clean up line items.
+ *
+ * @param array $paymentParams
+ * @param string $message
*/
- protected function processCreditCard($submittedValues, $lineItem) {
- $sendReceipt = $contribution = FALSE;
-
- $unsetParams = array(
- 'trxn_id',
- 'payment_instrument_id',
- 'contribution_status_id',
- 'cancel_date',
- 'cancel_reason',
- );
- foreach ($unsetParams as $key) {
- if (isset($submittedValues[$key])) {
- unset($submittedValues[$key]);
- }
+ public function cleanupDBAfterPaymentFailure($paymentParams, $message) {
+ // Make sure to cleanup db for recurring case.
+ if (!empty($paymentParams['contributionID'])) {
+ CRM_Core_Error::debug_log_message($message .
+ "contact id={$this->_contactID} (deleting contribution {$paymentParams['contributionID']}");
+ CRM_Contribute_BAO_Contribution::deleteContribution($paymentParams['contributionID']);
}
- $isTest = ($this->_mode == 'test') ? 1 : 0;
- // CRM-12680 set $_lineItem if its not set
- if (empty($this->_lineItem) && !empty($lineItem)) {
- $this->_lineItem = $lineItem;
+ if (!empty($paymentParams['contributionRecurID'])) {
+ CRM_Core_Error::debug_log_message($message .
+ "contact id={$this->_contactID} (deleting recurring contribution {$paymentParams['contributionRecurID']}");
+ CRM_Contribute_BAO_ContributionRecur::deleteRecurContribution($paymentParams['contributionRecurID']);
}
+ }
- //Get the require fields value only.
- $params = $this->_params = $submittedValues;
-
- $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($this->_params['payment_processor_id'],
- $this->_mode
- );
-
- // Get the payment processor id as per mode.
- $this->_params['payment_processor'] = $params['payment_processor_id']
- = $this->_params['payment_processor_id'] = $submittedValues['payment_processor_id'] = $this->_paymentProcessor['id'];
-
- $now = date('YmdHis');
- $fields = array();
-
- // we need to retrieve email address
- if ($this->_context == 'standalone' && !empty($submittedValues['is_email_receipt'])) {
- list($this->userDisplayName,
- $this->userEmail
- ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
- $this->assign('displayName', $this->userDisplayName);
- }
-
- // Set email for primary location.
- $fields['email-Primary'] = 1;
- $params['email-Primary'] = $this->userEmail;
-
- // now set the values for the billing location.
- foreach (array_keys($this->_fields) as $name) {
- $fields[$name] = 1;
- }
-
- // also add location name to the array
- $params["address_name-{$this->_bltID}"] = CRM_Utils_Array::value('billing_first_name', $params) . ' ' . CRM_Utils_Array::value('billing_middle_name', $params) . ' ' . CRM_Utils_Array::value('billing_last_name', $params);
-
- $params["address_name-{$this->_bltID}"] = trim($params["address_name-{$this->_bltID}"]);
- $fields["address_name-{$this->_bltID}"] = 1;
- $ctype = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
- $this->_contactID,
- 'contact_type'
- );
-
- $nameFields = array('first_name', 'middle_name', 'last_name');
- foreach ($nameFields as $name) {
- $fields[$name] = 1;
- if (array_key_exists("billing_$name", $params)) {
- $params[$name] = $params["billing_{$name}"];
- $params['preserveDBName'] = TRUE;
- }
+ /**
+ * Generate the data to construct a snippet based pane.
+ *
+ * This form also assigns the showAdditionalInfo var based on historical code.
+ * This appears to mean 'there is a pane to show'.
+ *
+ * @param string $type
+ * Type of Pane - this is generally used to determine the function name used to build it
+ * - e.g CreditCard, AdditionalDetail
+ * @param array $defaults
+ *
+ * @return array
+ * We aim to further refactor & simplify this but currently
+ * - the panes array
+ * - should additional info be shown?
+ */
+ protected function generatePane($type, $defaults) {
+ $urlParams = "snippet=4&formType={$type}";
+ if ($this->_mode) {
+ $urlParams .= "&mode={$this->_mode}";
}
- if (!empty($params['source'])) {
- unset($params['source']);
+ $open = 'false';
+ if ($type == 'CreditCard' ||
+ $type == 'DirectDebit'
+ ) {
+ $open = 'true';
}
- $contactID = CRM_Contact_BAO_Contact::createProfileContact($params, $fields,
- $this->_contactID,
- NULL, NULL,
- $ctype
- );
- // add all the additional payment params we need
- if (!empty($this->_params["billing_state_province_id-{$this->_bltID}"])) {
- $this->_params["state_province-{$this->_bltID}"] = $this->_params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($this->_params["billing_state_province_id-{$this->_bltID}"]);
- }
- if (!empty($this->_params["billing_country_id-{$this->_bltID}"])) {
- $this->_params["country-{$this->_bltID}"] = $this->_params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($this->_params["billing_country_id-{$this->_bltID}"]);
- }
- $legacyCreditCardExpiryCheck = FALSE;
- if ($this->_paymentProcessor['payment_type'] & CRM_Core_Payment::PAYMENT_TYPE_CREDIT_CARD && !isset($this->_paymentFields)) {
- $legacyCreditCardExpiryCheck = TRUE;
- }
- if ($legacyCreditCardExpiryCheck || in_array('credit_card_exp_date', array_keys($this->_paymentFields))) {
- $this->_params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($this->_params);
- $this->_params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($this->_params);
- }
- $this->_params['ip_address'] = CRM_Utils_System::ipAddress();
- $this->_params['amount'] = $this->_params['total_amount'];
- $this->_params['amount_level'] = 0;
- $this->_params['description'] = ts('Office Credit Card contribution');
- $this->_params['currencyID'] = CRM_Utils_Array::value('currency',
- $this->_params,
- CRM_Core_Config::singleton()->defaultCurrency
+ $pane = array(
+ 'url' => CRM_Utils_System::url('civicrm/contact/view/contribution', $urlParams),
+ 'open' => $open,
+ 'id' => $type,
);
- $this->_params['payment_action'] = 'Sale';
- if (!empty($this->_params['receive_date'])) {
- $this->_params['receive_date'] = CRM_Utils_Date::processDate($this->_params['receive_date'], $this->_params['receive_date_time']);
- }
- if (!empty($params['soft_credit_to'])) {
- $this->_params['soft_credit_to'] = $params['soft_credit_to'];
- $this->_params['pcp_made_through_id'] = $params['pcp_made_through_id'];
+ // See if we need to include this paneName in the current form.
+ if ($this->_formType == $type || !empty($_POST["hidden_{$type}"]) ||
+ CRM_Utils_Array::value("hidden_{$type}", $defaults)
+ ) {
+ $this->assign('showAdditionalInfo', TRUE);
+ $pane['open'] = 'true';
}
- $this->_params['pcp_display_in_roll'] = CRM_Utils_Array::value('pcp_display_in_roll', $params);
- $this->_params['pcp_roll_nickname'] = CRM_Utils_Array::value('pcp_roll_nickname', $params);
- $this->_params['pcp_personal_note'] = CRM_Utils_Array::value('pcp_personal_note', $params);
-
- //Add common data to formatted params
- CRM_Contribute_Form_AdditionalInfo::postProcessCommon($params, $this->_params, $this);
-
- if (empty($this->_params['invoice_id'])) {
- $this->_params['invoiceID'] = md5(uniqid(rand(), TRUE));
+ if ($type == 'CreditCard' || $type == 'DirectDebit') {
+ // @todo would be good to align tpl name with form name...
+ // @todo document why this hidden variable is required.
+ $this->add('hidden', 'hidden_' . $type, 1);
+ return $pane;
}
else {
- $this->_params['invoiceID'] = $this->_params['invoice_id'];
+ $additionalInfoFormFunction = 'build' . $type;
+ CRM_Contribute_Form_AdditionalInfo::$additionalInfoFormFunction($this);
+ return $pane;
}
+ }
- // At this point we've created a contact and stored its address etc
- // all the payment processors expect the name and address to be in the
- // so we copy stuff over to first_name etc.
- $paymentParams = $this->_params;
- $paymentParams['contactID'] = $this->_contactID;
- CRM_Core_Payment_Form::mapParams($this->_bltID, $this->_params, $paymentParams, TRUE);
-
- $contributionType = new CRM_Financial_DAO_FinancialType();
- $contributionType->id = $params['financial_type_id'];
+ /**
+ * Wrapper for unit testing the post process submit function.
+ *
+ * (If we expose through api we can get default additions 'for free').
+ *
+ * @param array $params
+ */
+ public function testSubmit($params) {
+ $defaults = array(
+ 'soft_credit_contact_id' => array(),
+ 'receipt_date' => '',
+ 'receipt_date_time' => '',
+ 'cancel_date' => '',
+ 'cancel_date_time' => '',
+ );
- // Add some financial type details to the params list
- // if folks need to use it.
- $paymentParams['contributionType_name'] = $this->_params['contributionType_name'] = $contributionType->name;
- $paymentParams['contributionPageID'] = NULL;
+ $this->submit(array_merge($defaults, $params));
+ }
- if (!empty($this->_params['is_email_receipt'])) {
- $paymentParams['email'] = $this->userEmail;
- $paymentParams['is_email_receipt'] = 1;
- }
- else {
- $paymentParams['is_email_receipt'] = 0;
- $this->_params['is_email_receipt'] = 0;
+ /**
+ * @param array $submittedValues
+ *
+ * @return array
+ * @throws \Exception
+ */
+ protected function submit($submittedValues) {
+ $softParams = $softIDs = array();
+ $pId = $contribution = $isRelatedId = FALSE;
+ if (!empty($submittedValues['price_set_id']) && $this->_action & CRM_Core_Action::UPDATE) {
+ $line = CRM_Price_BAO_LineItem::getLineItems($this->_id, 'contribution');
+ $lineID = key($line);
+ $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', CRM_Utils_Array::value('price_field_id', $line[$lineID]), 'price_set_id');
+ $quickConfig = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'is_quick_config');
+ if ($quickConfig) {
+ CRM_Price_BAO_LineItem::deleteLineItems($this->_id, 'civicrm_contribution');
+ }
}
- if (!empty($this->_params['receive_date'])) {
- $paymentParams['receive_date'] = $this->_params['receive_date'];
+
+ // Process price set and get total amount and line items.
+ $lineItem = array();
+ $priceSetId = CRM_Utils_Array::value('price_set_id', $submittedValues);
+ if (empty($priceSetId) && !$this->_id) {
+ $this->_priceSetId = $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', 'default_contribution_amount', 'id', 'name');
+ $this->_priceSet = current(CRM_Price_BAO_PriceSet::getSetDetail($priceSetId));
+ $fieldID = key($this->_priceSet['fields']);
+ $fieldValueId = key($this->_priceSet['fields'][$fieldID]['options']);
+ $this->_priceSet['fields'][$fieldID]['options'][$fieldValueId]['amount'] = $submittedValues['total_amount'];
+ $submittedValues['price_' . $fieldID] = 1;
}
- // For recurring contribution, create Contribution Record first.
- // Contribution ID, Recurring ID and Contact ID needed
- // When we get a callback from the payment processor, CRM-7115
+ if ($priceSetId) {
+ CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'],
+ $submittedValues, $lineItem[$priceSetId]);
- if (!empty($paymentParams['is_recur'])) {
- $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($this,
- $this->_params,
- NULL,
- $this->_contactID,
- $contributionType,
- TRUE,
- FALSE,
- $isTest,
- $this->_lineItem
- );
- $paymentParams['contributionID'] = $contribution->id;
- $paymentParams['contributionTypeID'] = $contribution->financial_type_id;
- $paymentParams['contributionPageID'] = $contribution->contribution_page_id;
- $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id;
+ // Unset tax amount for offline 'is_quick_config' contribution.
+ if ($this->_priceSet['is_quick_config'] &&
+ !array_key_exists($submittedValues['financial_type_id'], CRM_Core_PseudoConstant::getTaxRates())
+ ) {
+ unset($submittedValues['tax_amount']);
+ }
+ $submittedValues['total_amount'] = CRM_Utils_Array::value('amount', $submittedValues);
}
- $result = array();
- if ($paymentParams['amount'] > 0.0) {
- // force a re-get of the payment processor in case the form changed it, CRM-7179
- $payment = CRM_Core_Payment::singleton($this->_mode, $this->_paymentProcessor, $this, TRUE);
- try {
- $result = $payment->doPayment($paymentParams, 'contribute');
+ if ($this->_id) {
+ if ($this->_compId) {
+ if ($this->_context == 'participant') {
+ $pId = $this->_compId;
+ }
+ elseif ($this->_context == 'membership') {
+ $isRelatedId = TRUE;
+ }
+ else {
+ $pId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_id, 'participant_id', 'contribution_id');
+ }
}
- catch (CRM_Core_Exception $e) {
- $message = ts("Payment Processor Error message") . $e->getMessage();
- $this->cleanupDBAfterPaymentFailure($paymentParams, $message);
- // Set the contribution mode.
- $urlParams = "action=add&cid={$this->_contactID}";
- if ($this->_mode) {
- $urlParams .= "&mode={$this->_mode}";
+ else {
+ $contributionDetails = CRM_Contribute_BAO_Contribution::getComponentDetails($this->_id);
+ if (array_key_exists('membership', $contributionDetails)) {
+ $isRelatedId = TRUE;
}
- if (!empty($this->_ppID)) {
- $urlParams .= "&context=pledge&ppid={$this->_ppID}";
+ elseif (array_key_exists('participant', $contributionDetails)) {
+ $pId = $contributionDetails['participant'];
}
- CRM_Core_Error::statusBounce($message, $urlParams, ts('Payment Processor Error'));
}
}
+ if (!$priceSetId && !empty($submittedValues['total_amount']) && $this->_id) {
+ // CRM-10117 update the line items for participants.
+ if ($pId) {
+ $entityTable = 'participant';
+ $entityID = $pId;
+ $isRelatedId = FALSE;
+ $participantParams = array(
+ 'fee_amount' => $submittedValues['total_amount'],
+ 'id' => $entityID,
+ );
+ CRM_Event_BAO_Participant::add($participantParams);
+ if (empty($this->_lineItems)) {
+ $this->_lineItems[] = CRM_Price_BAO_LineItem::getLineItems($entityID, 'participant', 1);
+ }
+ }
+ else {
+ $entityTable = 'contribution';
+ $entityID = $this->_id;
+ }
- $this->_params = array_merge($this->_params, $result);
-
- $this->_params['receive_date'] = $now;
-
- if (!empty($this->_params['is_email_receipt'])) {
- $this->_params['receipt_date'] = $now;
- }
- else {
- $this->_params['receipt_date'] = CRM_Utils_Date::processDate($this->_params['receipt_date'],
- $params['receipt_date_time'], TRUE
- );
- }
-
- $this->set('params', $this->_params);
- $this->assign('trxn_id', $result['trxn_id']);
- $this->assign('receive_date', $this->_params['receive_date']);
+ $lineItems = CRM_Price_BAO_LineItem::getLineItems($entityID, $entityTable, NULL, TRUE, $isRelatedId);
+ foreach (array_keys($lineItems) as $id) {
+ $lineItems[$id]['id'] = $id;
+ }
+ $itemId = key($lineItems);
+ if ($itemId && !empty($lineItems[$itemId]['price_field_id'])) {
+ $this->_priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $lineItems[$itemId]['price_field_id'], 'price_set_id');
+ }
- // Result has all the stuff we need
- // lets archive it to a financial transaction
- if ($contributionType->is_deductible) {
- $this->assign('is_deductible', TRUE);
- $this->set('is_deductible', TRUE);
- }
+ if ($this->_priceSetId && CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
+ $lineItems[$itemId]['unit_price'] = $lineItems[$itemId]['line_total'] = CRM_Utils_Rule::cleanMoney(CRM_Utils_Array::value('total_amount', $submittedValues));
- // Set source if not set
- if (empty($this->_params['source'])) {
- $userID = CRM_Core_Session::singleton()->get('userID');
- $userSortName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $userID,
- 'sort_name'
- );
- $this->_params['source'] = ts('Submit Credit Card Payment by: %1', array(1 => $userSortName));
+ // Update line total and total amount with tax on edit.
+ $financialItemsId = CRM_Core_PseudoConstant::getTaxRates();
+ if (array_key_exists($submittedValues['financial_type_id'], $financialItemsId)) {
+ $lineItems[$itemId]['tax_rate'] = $financialItemsId[$submittedValues['financial_type_id']];
+ }
+ else {
+ $lineItems[$itemId]['tax_rate'] = $lineItems[$itemId]['tax_amount'] = "";
+ $submittedValues['tax_amount'] = 'null';
+ }
+ if ($lineItems[$itemId]['tax_rate']) {
+ $lineItems[$itemId]['tax_amount'] = ($lineItems[$itemId]['tax_rate'] / 100) * $lineItems[$itemId]['line_total'];
+ $submittedValues['total_amount'] = $lineItems[$itemId]['line_total'] + $lineItems[$itemId]['tax_amount'];
+ $submittedValues['tax_amount'] = $lineItems[$itemId]['tax_amount'];
+ }
+ }
+ // CRM-10117 update the line items for participants.
+ if (!empty($lineItems[$itemId]['price_field_id'])) {
+ $lineItem[$this->_priceSetId] = $lineItems;
+ }
}
- // Build custom data getFields array
- $customFieldsContributionType = CRM_Core_BAO_CustomField::getFields('Contribution', FALSE, FALSE,
- CRM_Utils_Array::value('financial_type_id', $params)
- );
- $customFields = CRM_Utils_Array::crmArrayMerge($customFieldsContributionType,
- CRM_Core_BAO_CustomField::getFields('Contribution', FALSE, FALSE, NULL, NULL, TRUE)
- );
- $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params,
- $customFields,
- $this->_id,
- 'Contribution'
- );
- if (empty($paymentParams['is_recur'])) {
- $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($this,
- $this->_params,
- $result,
- $this->_contactID,
- $contributionType,
- FALSE, FALSE,
- $isTest,
- $this->_lineItem
- );
+ $isQuickConfig = 0;
+ if ($this->_priceSetId && CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
+ $isQuickConfig = 1;
}
-
- // Send receipt mail.
- if ($contribution->id && !empty($this->_params['is_email_receipt'])) {
- $this->_params['trxn_id'] = CRM_Utils_Array::value('trxn_id', $result);
- $this->_params['contact_id'] = $this->_contactID;
- $this->_params['contribution_id'] = $contribution->id;
- $sendReceipt = CRM_Contribute_Form_AdditionalInfo::emailReceipt($this, $this->_params, TRUE);
+ //CRM-11529 for quick config back office transactions
+ //when financial_type_id is passed in form, update the
+ //line items with the financial type selected in form
+ if ($isQuickConfig && !empty($submittedValues['financial_type_id']) && CRM_Utils_Array::value($this->_priceSetId, $lineItem)
+ ) {
+ foreach ($lineItem[$this->_priceSetId] as &$values) {
+ $values['financial_type_id'] = $submittedValues['financial_type_id'];
+ }
}
- //process the note
- if ($contribution->id && isset($params['note'])) {
- CRM_Contribute_Form_AdditionalInfo::processNote($params, $contactID, $contribution->id, NULL);
- }
- //process premium
- if ($contribution->id && isset($params['product_name'][0])) {
- CRM_Contribute_Form_AdditionalInfo::processPremium($params, $contribution->id, NULL, $this->_options);
+ if (!isset($submittedValues['total_amount'])) {
+ $submittedValues['total_amount'] = CRM_Utils_Array::value('total_amount', $this->_values);
}
+ $this->assign('lineItem', !empty($lineItem) && !$isQuickConfig ? $lineItem : FALSE);
- //update pledge payment status.
- if ($this->_ppID && $contribution->id) {
- // Store contribution id in payment record.
- CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', $this->_ppID, 'contribution_id', $contribution->id);
-
- CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($this->_pledgeID,
- array($this->_ppID),
- $contribution->contribution_status_id,
- NULL,
- $contribution->total_amount
+ if (!empty($submittedValues['pcp_made_through_id'])) {
+ $pcp = array();
+ $fields = array(
+ 'pcp_made_through_id',
+ 'pcp_display_in_roll',
+ 'pcp_roll_nickname',
+ 'pcp_personal_note',
);
+ foreach ($fields as $f) {
+ $pcp[$f] = CRM_Utils_Array::value($f, $submittedValues);
+ }
}
- if ($contribution->id) {
- $statusMsg = ts('The contribution record has been processed.');
- if (!empty($this->_params['is_email_receipt']) && $sendReceipt) {
- $statusMsg .= ' ' . ts('A receipt has been emailed to the contributor.');
+ $isEmpty = array_keys(array_flip($submittedValues['soft_credit_contact_id']));
+ if ($this->_id && count($isEmpty) == 1 && key($isEmpty) == NULL) {
+ //Delete existing soft credit records if soft credit list is empty on update
+ CRM_Contribute_BAO_ContributionSoft::del(array('contribution_id' => $this->_id));
+ }
+ else {
+ //build soft credit params
+ foreach ($submittedValues['soft_credit_contact_id'] as $key => $val) {
+ if ($val && $submittedValues['soft_credit_amount'][$key]) {
+ $softParams[$key]['contact_id'] = $val;
+ $softParams[$key]['amount'] = CRM_Utils_Rule::cleanMoney($submittedValues['soft_credit_amount'][$key]);
+ $softParams[$key]['soft_credit_type_id'] = $submittedValues['soft_credit_type'][$key];
+ if (!empty($submittedValues['soft_credit_id'][$key])) {
+ $softIDs[] = $softParams[$key]['id'] = $submittedValues['soft_credit_id'][$key];
+ }
+ }
}
- CRM_Core_Session::setStatus($statusMsg, ts('Complete'), 'success');
}
- }
- /**
- * Clean up DB after payment fails.
- *
- * This function removes related DB entries. Note that it has been agreed in principle,
- * but not implemented, that contributions should be retained as 'Failed' rather than
- * deleted.
- *
- * @todo it doesn't clean up line items.
- *
- * @param array $paymentParams
- * @param string $message
- */
- public function cleanupDBAfterPaymentFailure($paymentParams, $message) {
- // Make sure to cleanup db for recurring case.
- if (!empty($paymentParams['contributionID'])) {
- CRM_Core_Error::debug_log_message($message .
- "contact id={$this->_contactID} (deleting contribution {$paymentParams['contributionID']}");
- CRM_Contribute_BAO_Contribution::deleteContribution($paymentParams['contributionID']);
- }
- if (!empty($paymentParams['contributionRecurID'])) {
- CRM_Core_Error::debug_log_message($message .
- "contact id={$this->_contactID} (deleting recurring contribution {$paymentParams['contributionRecurID']}");
- CRM_Contribute_BAO_ContributionRecur::deleteRecurContribution($paymentParams['contributionRecurID']);
+ // set the contact, when contact is selected
+ if (!empty($submittedValues['contact_id'])) {
+ $this->_contactID = $submittedValues['contact_id'];
}
- }
- /**
- * Generate the data to construct a snippet based pane.
- *
- * This form also assigns the showAdditionalInfo var based on historical code.
- * This appears to mean 'there is a pane to show'.
- *
- * @param string $type
- * Type of Pane - this is generally used to determine the function name used to build it
- * - e.g CreditCard, AdditionalDetail
- * @param array $defaults
- *
- * @return array
- * We aim to further refactor & simplify this but currently
- * - the panes array
- * - should additional info be shown?
- */
- protected function generatePane($type, $defaults) {
- $urlParams = "snippet=4&formType={$type}";
+ // Credit Card Contribution.
if ($this->_mode) {
- $urlParams .= "&mode={$this->_mode}";
+ $this->processCreditCard($submittedValues, $lineItem);
+ return FALSE;
}
+ else {
+ // Offline Contribution.
+ $submittedValues = $this->unsetCreditCardFields($submittedValues);
- $open = 'false';
- if ($type == 'CreditCard' ||
- $type == 'DirectDebit'
- ) {
- $open = 'true';
- }
+ // get the required field value only.
+ $formValues = $submittedValues;
+ $params = $ids = array();
- $pane = array(
- 'url' => CRM_Utils_System::url('civicrm/contact/view/contribution', $urlParams),
- 'open' => $open,
- 'id' => $type,
- );
+ $params['contact_id'] = $this->_contactID;
- // See if we need to include this paneName in the current form.
- if ($this->_formType == $type || !empty($_POST["hidden_{$type}"]) ||
- CRM_Utils_Array::value("hidden_{$type}", $defaults)
- ) {
- $this->assign('showAdditionalInfo', TRUE);
- $pane['open'] = 'true';
- }
+ $params['currency'] = $this->getCurrency($submittedValues);
- if ($type == 'CreditCard' || $type == 'DirectDebit') {
- // @todo would be good to align tpl name with form name...
- // @todo document why this hidden variable is required.
- $this->add('hidden', 'hidden_' . $type, 1);
- return $pane;
- }
- else {
- $additionalInfoFormFunction = 'build' . $type;
- CRM_Contribute_Form_AdditionalInfo::$additionalInfoFormFunction($this);
- return $pane;
- }
- }
+ $fields = array(
+ 'financial_type_id',
+ 'contribution_status_id',
+ 'payment_instrument_id',
+ 'cancel_reason',
+ 'source',
+ 'check_number',
+ );
+ foreach ($fields as $f) {
+ $params[$f] = CRM_Utils_Array::value($f, $formValues);
+ }
- /**
- * Wrapper for unit testing the post process submit function.
- *
- * (If we expose through api we can get default additions 'for free').
- *
- * @param array $params
- */
- public function testSubmit($params) {
- $defaults = array(
- 'soft_credit_contact_id' => array(),
- 'receipt_date' => '',
- 'receipt_date_time' => '',
- 'cancel_date' => '',
- 'cancel_date_time' => '',
- );
+ if (!empty($pcp)) {
+ $params['pcp'] = $pcp;
+ }
+ if (!empty($softParams)) {
+ $params['soft_credit'] = $softParams;
+ $params['soft_credit_ids'] = $softIDs;
+ }
- $this->submit(array_merge($defaults, $params));
+ // CRM-5740 if priceset is used, no need to cleanup money.
+ if ($priceSetId) {
+ $params['skipCleanMoney'] = 1;
+ }
+
+ $dates = array(
+ 'receive_date',
+ 'receipt_date',
+ 'cancel_date',
+ );
+
+ foreach ($dates as $d) {
+ $params[$d] = CRM_Utils_Date::processDate($formValues[$d], $formValues[$d . '_time'], TRUE);
+ }
+
+ if (!empty($formValues['is_email_receipt'])) {
+ $params['receipt_date'] = date("Y-m-d");
+ }
+
+ if ($params['contribution_status_id'] == CRM_Core_OptionGroup::getValue('contribution_status', 'Cancelled', 'name')
+ || $params['contribution_status_id'] == CRM_Core_OptionGroup::getValue('contribution_status', 'Refunded', 'name')
+ ) {
+ if (CRM_Utils_System::isNull(CRM_Utils_Array::value('cancel_date', $params))) {
+ $params['cancel_date'] = date('Y-m-d');
+ }
+ }
+ else {
+ $params['cancel_date'] = $params['cancel_reason'] = 'null';
+ }
+
+ // Set is_pay_later flag for back-office offline Pending status contributions CRM-8996
+ // else if contribution_status is changed to Completed is_pay_later flag is changed to 0, CRM-15041
+ if ($params['contribution_status_id'] == CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name')) {
+ $params['is_pay_later'] = 1;
+ }
+ elseif ($params['contribution_status_id'] == CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name')) {
+ $params['is_pay_later'] = 0;
+ }
+
+ $ids['contribution'] = $params['id'] = $this->_id;
+
+ // Add Additional common information to formatted params.
+ CRM_Contribute_Form_AdditionalInfo::postProcessCommon($formValues, $params, $this);
+ if ($pId) {
+ $params['contribution_mode'] = 'participant';
+ $params['participant_id'] = $pId;
+ $params['skipLineItem'] = 1;
+ }
+ elseif ($isRelatedId) {
+ $params['contribution_mode'] = 'membership';
+ }
+ $params['line_item'] = $lineItem;
+ $params['payment_processor_id'] = $params['payment_processor'] = CRM_Utils_Array::value('id', $this->_paymentProcessor);
+ if (isset($submittedValues['tax_amount'])) {
+ $params['tax_amount'] = $submittedValues['tax_amount'];
+ }
+ //create contribution.
+ if ($isQuickConfig) {
+ $params['is_quick_config'] = 1;
+ }
+
+ // CRM-11956
+ // if non_deductible_amount exists i.e. Additional Details field set was opened [and staff typed something] -
+ // if non_deductible_amount does NOT exist - then calculate it depending on:
+ // $ContributionType->is_deductible and whether there is a product (premium).
+ if (empty($params['non_deductible_amount'])) {
+ $contributionType = new CRM_Financial_DAO_FinancialType();
+ $contributionType->id = $params['financial_type_id'];
+ if (!$contributionType->find(TRUE)) {
+ CRM_Core_Error::fatal('Could not find a system table');
+ }
+ if ($contributionType->is_deductible) {
+
+ if (isset($formValues['product_name'][0])) {
+ $selectProduct = $formValues['product_name'][0];
+ }
+ // if there is a product - compare the value to the contribution amount
+ if (isset($selectProduct)) {
+ $productDAO = new CRM_Contribute_DAO_Product();
+ $productDAO->id = $selectProduct;
+ $productDAO->find(TRUE);
+ // product value exceeds contribution amount
+ if ($params['total_amount'] < $productDAO->price) {
+ $params['non_deductible_amount'] = $params['total_amount'];
+ }
+ // product value does NOT exceed contribution amount
+ else {
+ $params['non_deductible_amount'] = $productDAO->price;
+ }
+ }
+ // contribution is deductible - but there is no product
+ else {
+ $params['non_deductible_amount'] = '0.00';
+ }
+ }
+ // contribution is NOT deductible
+ else {
+ $params['non_deductible_amount'] = $params['total_amount'];
+ }
+ }
+
+ $contribution = CRM_Contribute_BAO_Contribution::create($params, $ids);
+
+ // process associated membership / participant, CRM-4395
+ $relatedComponentStatusMsg = NULL;
+ if ($contribution->id && $this->_action & CRM_Core_Action::UPDATE) {
+ $relatedComponentStatusMsg = $this->updateRelatedComponent($contribution->id,
+ $contribution->contribution_status_id,
+ CRM_Utils_Array::value('contribution_status_id',
+ $this->_values
+ ),
+ $contribution->receive_date
+ );
+ }
+
+ //process note
+ if ($contribution->id && isset($formValues['note'])) {
+ CRM_Contribute_Form_AdditionalInfo::processNote($formValues, $this->_contactID, $contribution->id, $this->_noteID);
+ }
+
+ //process premium
+ if ($contribution->id && isset($formValues['product_name'][0])) {
+ CRM_Contribute_Form_AdditionalInfo::processPremium($formValues, $contribution->id,
+ $this->_premiumID, $this->_options
+ );
+ }
+
+ // assign tax calculation for contribution receipts
+ $taxRate = array();
+ $getTaxDetails = FALSE;
+ $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
+ $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
+ if ($invoicing) {
+ if ($this->_action & CRM_Core_Action::ADD) {
+ $line = $lineItem;
+ }
+ elseif ($this->_action & CRM_Core_Action::UPDATE) {
+ $line = $this->_lineItems;
+ }
+ foreach ($line as $key => $value) {
+ foreach ($value as $v) {
+ if (isset($taxRate[(string) CRM_Utils_Array::value('tax_rate', $v)])) {
+ $taxRate[(string) $v['tax_rate']] = $taxRate[(string) $v['tax_rate']] + CRM_Utils_Array::value('tax_amount', $v);
+ }
+ else {
+ if (isset($v['tax_rate'])) {
+ $taxRate[(string) $v['tax_rate']] = CRM_Utils_Array::value('tax_amount', $v);
+ $getTaxDetails = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ if ($invoicing) {
+ if ($this->_action & CRM_Core_Action::UPDATE) {
+ if (isset($submittedValues['tax_amount'])) {
+ $totalTaxAmount = $submittedValues['tax_amount'];
+ }
+ else {
+ $totalTaxAmount = $this->_values['tax_amount'];
+ }
+ $this->assign('totalTaxAmount', $totalTaxAmount);
+ $this->assign('dataArray', $taxRate);
+ }
+ else {
+ if (!empty($submittedValues['price_set_id'])) {
+ $this->assign('totalTaxAmount', $submittedValues['tax_amount']);
+ $this->assign('getTaxDetails', $getTaxDetails);
+ $this->assign('dataArray', $taxRate);
+ $this->assign('taxTerm', CRM_Utils_Array::value('tax_term', $invoiceSettings));
+ }
+ else {
+ $this->assign('totalTaxAmount', CRM_Utils_Array::value('tax_amount', $submittedValues));
+ }
+ }
+ }
+
+ //send receipt mail.
+ if ($contribution->id && !empty($formValues['is_email_receipt'])) {
+ $formValues['contact_id'] = $this->_contactID;
+ $formValues['contribution_id'] = $contribution->id;
+
+ $formValues += CRM_Contribute_BAO_ContributionSoft::getSoftContribution($contribution->id);
+
+ // to get 'from email id' for send receipt
+ $this->fromEmailId = $formValues['from_email_address'];
+ $sendReceipt = CRM_Contribute_Form_AdditionalInfo::emailReceipt($this, $formValues);
+ }
+
+ $pledgePaymentId = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_PledgePayment',
+ $contribution->id,
+ 'id',
+ 'contribution_id'
+ );
+
+ //update pledge payment status.
+ if ((($this->_ppID && $contribution->id) && $this->_action & CRM_Core_Action::ADD) ||
+ (($pledgePaymentId) && $this->_action & CRM_Core_Action::UPDATE)
+ ) {
+
+ if ($this->_ppID) {
+ //store contribution id in payment record.
+ CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', $this->_ppID, 'contribution_id', $contribution->id);
+ }
+ else {
+ $this->_ppID = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_PledgePayment',
+ $contribution->id,
+ 'id',
+ 'contribution_id'
+ );
+ $this->_pledgeID = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_PledgePayment',
+ $contribution->id,
+ 'pledge_id',
+ 'contribution_id'
+ );
+ }
+
+ $adjustTotalAmount = FALSE;
+ if (CRM_Utils_Array::value('option_type', $formValues) == 2) {
+ $adjustTotalAmount = TRUE;
+ }
+
+ $updatePledgePaymentStatus = FALSE;
+ //do only if either the status or the amount has changed
+ if ($this->_action & CRM_Core_Action::ADD) {
+ $updatePledgePaymentStatus = TRUE;
+ }
+ elseif ($this->_action & CRM_Core_Action::UPDATE && (($this->_defaults['contribution_status_id'] != $formValues['contribution_status_id']) ||
+ ($this->_defaults['total_amount'] != $formValues['total_amount']))
+ ) {
+ $updatePledgePaymentStatus = TRUE;
+ }
+
+ if ($updatePledgePaymentStatus) {
+ CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($this->_pledgeID,
+ array($this->_ppID),
+ $contribution->contribution_status_id,
+ NULL,
+ $contribution->total_amount,
+ $adjustTotalAmount
+ );
+ }
+ }
+
+ $statusMsg = ts('The contribution record has been saved.');
+ if (!empty($formValues['is_email_receipt']) && $sendReceipt) {
+ $statusMsg .= ' ' . ts('A receipt has been emailed to the contributor.');
+ }
+
+ if ($relatedComponentStatusMsg) {
+ $statusMsg .= ' ' . $relatedComponentStatusMsg;
+ }
+
+ CRM_Core_Session::setStatus($statusMsg, ts('Saved'), 'success');
+ return $contribution;
+ //Offline Contribution ends.
+ }
}
}