if (!empty($relationships)) {
// get the total relationships
if ($params['context'] != 'user') {
- $params['total'] = CRM_Contact_BAO_Relationship::getRelationship($params['contact_id'],
- $relationshipStatus, 0, 1, 0, NULL, NULL, $permissionedContacts);
+ $params['total'] = count($relationships);
}
else {
- // FIX ME: we cannot directly determine total permissioned relationship, hence re-fire query
+ // FIXME: we cannot directly determine total permissioned relationship, hence re-fire query
$permissionedRelationships = CRM_Contact_BAO_Relationship::getRelationship($params['contact_id'],
$relationshipStatus,
0, 0, 0,
));
return;
}
-
- // 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');
- }
- }
-
- // 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;
- }
-
- if ($priceSetId) {
- CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'],
- $submittedValues, $lineItem[$priceSetId]);
- // 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);
+ try {
+ // Get the submitted form values.
+ $contribution = $this->submit($submittedValues, $this->_action, $this->_ppID);
}
- 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 (PaymentProcessorException $e) {
+ // 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;
- }
- elseif (array_key_exists('participant', $contributionDetails)) {
- $pId = $contributionDetails['participant'];
- }
+ if (!empty($this->_ppID)) {
+ $urlParams .= "&context=pledge&ppid={$this->_ppID}";
}
+
+ CRM_Core_Error::statusBounce($e->getMessage(), $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);
- }
+ $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 {
- $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');
- }
-
- if ($this->_priceSetId && CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
- //CRM-16833: Ensure tax is applied only once for membership conribution, when status changed.(e.g Pending to Completed).
- $componentDetails = CRM_Contribute_BAO_Contribution::getComponentDetails($this->_id);
- if (!CRM_Utils_Array::value('membership', $componentDetails) || !CRM_Utils_Array::value('participant', $componentDetails)) {
- if (!($this->_action & CRM_Core_Action::UPDATE && (($this->_defaults['contribution_status_id'] != $submittedValues['contribution_status_id'])))) {
- $lineItems[$itemId]['unit_price'] = $lineItems[$itemId]['line_total'] = CRM_Utils_Rule::cleanMoney(CRM_Utils_Array::value('total_amount', $submittedValues));
- }
- }
- // 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;
+ $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view',
+ "reset=1&cid={$this->_contactID}&selectedChild=contribute"
+ ));
}
}
-
- $isQuickConfig = 0;
- if ($this->_priceSetId && CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
- $isQuickConfig = 1;
+ 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}"
+ ));
}
- //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'];
- }
+ 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}"
+ ));
}
- if (!isset($submittedValues['total_amount'])) {
- $submittedValues['total_amount'] = CRM_Utils_Array::value('total_amount', $this->_values);
+ //store contribution ID if not yet set (on create)
+ if (empty($this->_id) && !empty($contribution->id)) {
+ $this->_id = $contribution->id;
}
- $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);
- }
+ /**
+ * Process credit card payment.
+ *
+ * @param array $submittedValues
+ * @param array $lineItem
+ *
+ * @param int $contactID
+ * Contact ID
+ *
+ * @return bool|\CRM_Contribute_DAO_Contribution
+ * @throws \CiviCRM_API3_Exception
+ * @throws \Civi\Payment\Exception\PaymentProcessorException
+ */
+ protected function processCreditCard($submittedValues, $lineItem, $contactID) {
-
+ $isTest = ($this->_mode == 'test') ? 1 : 0;
+ // CRM-12680 set $_lineItem if its not set
+ // @todo - I don't believe this would ever BE set. I can't find anywhere in the code.
+ // It would be better to pass line item out to functions than $this->_lineItem as
+ // we don't know what is being changed where.
+ if (empty($this->_lineItem) && !empty($lineItem)) {
+ $this->_lineItem = $lineItem;
}
- $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, 'pcp_id' => 0));
- }
- 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];
- }
- }
- }
- }
+ $this->_paymentObject = Civi\Payment\System::singleton()->getById($submittedValues['payment_processor_id']);
+ $this->_paymentProcessor = $this->_paymentObject->getPaymentProcessor();
- // set the contact, when contact is selected
- if (!empty($submittedValues['contact_id'])) {
- $this->_contactID = $submittedValues['contact_id'];
+ // Set source if not set
+ if (empty($submittedValues['source'])) {
+ $userID = CRM_Core_Session::singleton()->get('userID');
+ $userSortName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $userID,
+ 'sort_name'
+ );
+ $submittedValues['source'] = ts('Submit Credit Card Payment by: %1', array(1 => $userSortName));
}
- // Credit Card Contribution.
- if ($this->_mode) {
- $this->processCreditCard($submittedValues, $lineItem);
- }
- else {
- // Offline Contribution.
- $submittedValues = $this->unsetCreditCardFields($submittedValues);
+ $params = $this->_params = $submittedValues;
- // get the required field value only.
- $formValues = $submittedValues;
- $params = $ids = array();
+ // Mapping requiring documentation.
+ $this->_params['payment_processor'] = $submittedValues['payment_processor_id'];
- $params['contact_id'] = $this->_contactID;
+ $now = date('YmdHis');
+ $fields = array();
- $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);
- }
-
- $params['pcp'] = !empty($pcp) ? $pcp : NULL;
- $params['soft_credit'] = !empty($softParams) ? $softParams : array();
- $params['soft_credit_ids'] = !empty($softIDs) ? $softIDs : array();
-
- // 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');
- //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;
- }
- }
-
- /**
- * Process credit card payment.
- *
- * @param array $submittedValues
- * @param array $lineItem
- *
- * @throws CRM_Core_Exception
- */
- 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]);
- }
- }
- $isTest = ($this->_mode == 'test') ? 1 : 0;
- // CRM-12680 set $_lineItem if its not set
- if (empty($this->_lineItem) && !empty($lineItem)) {
- $this->_lineItem = $lineItem;
- }
-
- //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);
- }
+ // 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($contactID);
+ $this->assign('displayName', $this->userDisplayName);
+ }
// Set email for primary location.
$fields['email-Primary'] = 1;
}
}
- $lineItems[$itemId]['unit_price'] = $lineItems[$itemId]['line_total'] = CRM_Utils_Rule::cleanMoney(CRM_Utils_Array::value('total_amount', $submittedValues));
+ /**
+ * Wrapper for unit testing the post process submit function.
+ *
+ * (If we expose through api we can get default additions 'for free').
+ *
+ * @param array $params
+ * @param int $action
+ * @param string|null $creditCardMode
+ *
+ * @throws \CiviCRM_API3_Exception
+ */
+ public function testSubmit($params, $action, $creditCardMode = NULL) {
+ $defaults = array(
+ 'soft_credit_contact_id' => array(),
+ 'receipt_date' => '',
+ 'receipt_date_time' => '',
+ 'cancel_date' => '',
+ 'cancel_date_time' => '',
+ 'hidden_Premium' => 1,
+ );
+ $this->_bltID = 5;
+ if (!empty($params['id'])) {
+ $existingContribution = civicrm_api3('contribution', 'getsingle', array(
+ 'id' => $params['id'],
+ ));
+ $this->_id = $params['id'];
+ }
+ else {
+ $existingContribution = array();
+ }
+
+ $this->_defaults['contribution_status_id'] = CRM_Utils_Array::value('contribution_status_id',
+ $existingContribution
+ );
+
+ $this->_defaults['total_amount'] = CRM_Utils_Array::value('total_amount',
+ $existingContribution
+ );
+
+ if ($creditCardMode) {
+ $this->_mode = $creditCardMode;
+ }
+
+ // Required because processCreditCard calls set method on this.
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $this->controller = new CRM_Core_Controller();
+
+ CRM_Contribute_Form_AdditionalInfo::buildPremium($this);
+
+ $this->_fields = array();
+ $this->submit(array_merge($defaults, $params), $action, CRM_Utils_Array::value('pledge_payment_id', $params));
+
+ }
+
+ /**
+ * @param array $submittedValues
+ *
+ * @param int $action
+ * Action constant
+ * - CRM_Core_Action::UPDATE
+ *
+ * @param $pledgePaymentID
+ *
+ * @return array
+ * @throws \Exception
+ */
+ protected function submit($submittedValues, $action, $pledgePaymentID) {
+ $softParams = $softIDs = array();
+ $pId = $contribution = $isRelatedId = FALSE;
+
+ if (!empty($submittedValues['price_set_id']) && $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');
+ }
+ }
+
+ // 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;
+ }
+
+ if ($priceSetId) {
+ CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'],
+ $submittedValues, $lineItem[$priceSetId]);
+
+ // 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);
+ }
+ 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'];
+ }
+ }
+ }
+ 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');
+ }
+
+ if ($this->_priceSetId && CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
- CRM_Contribute_BAO_ContributionSoft::del(array('contribution_id' => $this->_id));
++ //CRM-16833: Ensure tax is applied only once for membership conribution, when status changed.(e.g Pending to Completed).
++ $componentDetails = CRM_Contribute_BAO_Contribution::getComponentDetails($this->_id);
++ if (!CRM_Utils_Array::value('membership', $componentDetails) || !CRM_Utils_Array::value('participant', $componentDetails)) {
++ if (!($this->_action & CRM_Core_Action::UPDATE && (($this->_defaults['contribution_status_id'] != $submittedValues['contribution_status_id'])))) {
++ $lineItems[$itemId]['unit_price'] = $lineItems[$itemId]['line_total'] = CRM_Utils_Rule::cleanMoney(CRM_Utils_Array::value('total_amount', $submittedValues));
++ }
++ }
+
+ // 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;
+ }
+ }
+
+ $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'];
+ }
+ }
+
+ if (!isset($submittedValues['total_amount'])) {
+ $submittedValues['total_amount'] = CRM_Utils_Array::value('total_amount', $this->_values);
+ }
+ $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);
+ }
+ }
+
+ $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, 'pcp_id' => 0));
+ }
+ 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];
+ }
+ }
+ }
+ }
+
+ // set the contact, when contact is selected
+ if (!empty($submittedValues['contact_id'])) {
+ $this->_contactID = $submittedValues['contact_id'];
+ }
+ $formValues = $submittedValues;
+
+ // Credit Card Contribution.
+ if ($this->_mode) {
+ $paramsSetByPaymentProcessingSubsystem = array(
+ 'trxn_id',
+ 'payment_instrument_id',
+ 'contribution_status_id',
+ 'cancel_date',
+ 'cancel_reason',
+ );
+ foreach ($paramsSetByPaymentProcessingSubsystem as $key) {
+ if (isset($formValues[$key])) {
+ unset($formValues[$key]);
+ }
+ }
+ $contribution = $this->processCreditCard($formValues, $lineItem, $this->_contactID);
+ foreach ($paramsSetByPaymentProcessingSubsystem as $key) {
+ $formValues[$key] = $contribution->$key;
+ }
+ }
+ else {
+ // Offline Contribution.
+ $submittedValues = $this->unsetCreditCardFields($submittedValues);
+
+ // get the required field value only.
+
+ $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($pcp)) {
+ $params['pcp'] = $pcp;
+ }
+ $params['soft_credit'] = !empty($softParams) ? $softParams : array();
+ $params['soft_credit_ids'] = !empty($softIDs) ? $softIDs : array();
+
+ // 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;
+ }
+ $params['non_deductible_amount'] = $this->calculateNonDeductibleAmount($params, $formValues);
+
+ $contribution = CRM_Contribute_BAO_Contribution::create($params, $ids);
+
+ // process associated membership / participant, CRM-4395
+ if ($contribution->id && $action & CRM_Core_Action::UPDATE) {
+ $this->statusMessage[] = $this->updateRelatedComponent($contribution->id,
+ $contribution->contribution_status_id,
+ CRM_Utils_Array::value('contribution_status_id',
+ $this->_values
+ ),
+ $contribution->receive_date
+ );
+ }
+
+ array_unshift($this->statusMessage, ts('The contribution record has been saved.'));
+
+ $this->invoicingPostProcessHook($submittedValues, $action, $lineItem);
+
+ //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'];
+ if (CRM_Contribute_Form_AdditionalInfo::emailReceipt($this, $formValues)) {
+ $this->statusMessage[] = ts('A receipt has been emailed to the contributor.');
+ }
+ }
+
+ $this->statusMessageTitle = ts('Saved');
+
+ }
+
+ if ($contribution->id && !empty($formValues['product_name'][0])) {
+ CRM_Contribute_Form_AdditionalInfo::processPremium($submittedValues, $contribution->id,
+ $this->_premiumID, $this->_options
+ );
+ }
+
+ if ($contribution->id && isset($submittedValues['note'])) {
+ CRM_Contribute_Form_AdditionalInfo::processNote($submittedValues, $this->_contactID, $contribution->id, $this->_noteID);
+ }
+
+ CRM_Core_Session::setStatus(implode(' ', $this->statusMessage), $this->statusMessageTitle, 'success');
+
+ CRM_Contribute_BAO_Contribution::updateRelatedPledge(
+ $action,
+ $pledgePaymentID,
+ $contribution->id,
+ (CRM_Utils_Array::value('option_type', $formValues) == 2) ? TRUE : FALSE,
+ $formValues['total_amount'],
+ CRM_Utils_Array::value('total_amount', $this->_defaults),
+ $formValues['contribution_status_id'],
+ CRM_Utils_Array::value('contribution_status_id', $this->_defaults)
+ );
+ return $contribution;
+ }
+
+ /**
+ * Assign tax calculations to contribution receipts.
+ *
+ * @param array $submittedValues
+ * @param int $action
+ * @param array $lineItem
+ */
+ protected function invoicingPostProcessHook($submittedValues, $action, $lineItem) {
+
+ $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
+ if (!CRM_Utils_Array::value('invoicing', $invoiceSettings)) {
+ return;
+ }
+ $taxRate = array();
+ $getTaxDetails = FALSE;
+ if ($action & CRM_Core_Action::ADD) {
+ $line = $lineItem;
+ }
+ elseif ($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 ($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));
+ }
+ }
+ }
+
+ /**
+ * Calculate non deductible amount.
+ *
+ * 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:
+ * $financialType->is_deductible and whether there is a product (premium).
+ *
+ * @param $params
+ * @param $formValues
+ *
+ * @return array
+ */
+ protected function calculateNonDeductibleAmount($params, $formValues) {
+ if (!empty($params['non_deductible_amount'])) {
+ return $params['non_deductible_amount'];
+ }
+
+ $financialType = new CRM_Financial_DAO_FinancialType();
+ $financialType->id = $params['financial_type_id'];
+
+ if ($financialType->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) {
+ return $params['total_amount'];
+ }
+ // product value does NOT exceed contribution amount
+ else {
+ return $productDAO->price;
+ }
+ }
+ // contribution is deductible - but there is no product
+ else {
+ return '0.00';
+ }
+ }
+ // contribution is NOT deductible
+ else {
+ return $params['total_amount'];
+ }
+
+ return 0;
+ }
+
}
}
}
- return $params;
- }
+ return $params;
+ }
+
+ /**
+ * Process membership.
+ *
+ * @param array $membershipParams
+ * @param int $contactID
+ * @param array $customFieldsFormatted
+ * @param array $fieldTypes
+ * @param array $premiumParams
+ * @param array $membershipLineItems
+ * Line items specifically relating to memberships.
+ * @param bool $isPayLater
+ */
+ public function processMembership($membershipParams, $contactID, $customFieldsFormatted, $fieldTypes, $premiumParams, $membershipLineItems, $isPayLater) {
+ try {
+ $membershipTypeIDs = (array) $membershipParams['selectMembership'];
+ $membershipTypes = CRM_Member_BAO_Membership::buildMembershipTypeValues($this, $membershipTypeIDs);
+ $membershipType = empty($membershipTypes) ? array() : reset($membershipTypes);
+ $isPending = $this->getIsPending();
+
+ $this->assign('membership_name', CRM_Utils_Array::value('name', $membershipType));
+
+ $isPaidMembership = FALSE;
+ if ($this->_amount >= 0.0 && isset($membershipParams['amount'])) {
+ //amount must be greater than zero for
+ //adding contribution record to contribution table.
+ //this condition arises when separate membership payment is
+ //enabled and contribution amount is not selected. fix for CRM-3010
+ $isPaidMembership = TRUE;
+ }
+ $isProcessSeparateMembershipTransaction = $this->isSeparateMembershipTransaction($this->_id, $this->_values['amount_block_is_active']);
+
+ if ($this->_values['amount_block_is_active']) {
+ $financialTypeID = $this->_values['financial_type_id'];
+ }
+ else {
+ $financialTypeID = CRM_Utils_Array::value('financial_type_id', $membershipType, CRM_Utils_Array::value('financial_type_id', $membershipParams));
+ }
+
+ if (CRM_Utils_Array::value('membership_source', $this->_params)) {
+ $membershipParams['contribution_source'] = $this->_params['membership_source'];
+ }
+
+ $this->postProcessMembership($membershipParams, $contactID,
+ $this, $premiumParams, $customFieldsFormatted, $fieldTypes, $membershipType, $membershipTypeIDs, $isPaidMembership, $this->_membershipId, $isProcessSeparateMembershipTransaction, $financialTypeID,
+ $membershipLineItems, $isPayLater, $isPending);
+
+ $this->assign('membership_assign', TRUE);
+ $this->set('membershipTypeID', $membershipParams['selectMembership']);
+ }
+ catch (CRM_Core_Exception $e) {
+ CRM_Core_Session::singleton()->setStatus($e->getMessage());
+ CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/transact', "_qf_Main_display=true&qfKey={$this->_params['qfKey']}"));
+ }
+ }
+
+ /**
+ * Process the Memberships.
+ *
+ * @param array $membershipParams
+ * Array of membership fields.
+ * @param int $contactID
+ * Contact id.
+ * @param CRM_Contribute_Form_Contribution_Confirm $form
+ * Confirmation form object.
+ *
+ * @param array $premiumParams
+ * @param null $customFieldsFormatted
+ * @param null $includeFieldTypes
+ *
+ * @param array $membershipDetails
+ *
+ * @param array $membershipTypeIDs
+ *
+ * @param bool $isPaidMembership
+ * @param array $membershipID
+ *
+ * @param bool $isProcessSeparateMembershipTransaction
+ *
+ * @param int $financialTypeID
+ * @param array $membershipLineItems
+ * Line items specific to membership payment that is separate to contribution.
+ * @param bool $isPayLater
+ * @param bool $isPending
+ *
+ * @throws \CRM_Core_Exception
+ */
+ protected function postProcessMembership(
+ $membershipParams, $contactID, &$form, $premiumParams,
+ $customFieldsFormatted = NULL, $includeFieldTypes = NULL, $membershipDetails, $membershipTypeIDs, $isPaidMembership, $membershipID,
+ $isProcessSeparateMembershipTransaction, $financialTypeID, $membershipLineItems, $isPayLater, $isPending) {
+ $membershipContribution = NULL;
+ $isTest = CRM_Utils_Array::value('is_test', $membershipParams, FALSE);
+ $errors = $createdMemberships = $paymentResult = array();
+
+ if ($isPaidMembership) {
+ if ($isProcessSeparateMembershipTransaction) {
+ // If we have 2 transactions only one can use the invoice id.
+ $membershipParams['invoiceID'] .= '-2';
+ }
+
+ $paymentResult = CRM_Contribute_BAO_Contribution_Utils::processConfirm($form, $membershipParams,
+ $contactID,
+ $financialTypeID,
+ 'membership',
+ array(),
+ $isTest,
+ $isPayLater
+ );
+
+ if (!empty($paymentResult['contribution'])) {
+ $this->postProcessPremium($premiumParams, $paymentResult['contribution']);
+ //note that this will be over-written if we are using a separate membership transaction. Otherwise there is only one
+ $membershipContribution = $paymentResult['contribution'];
+ // Save the contribution ID so that I can be used in email receipts
+ // For example, if you need to generate a tax receipt for the donation only.
+ $form->_values['contribution_other_id'] = $membershipContribution->id;
+ }
+ }
+
+ if ($isProcessSeparateMembershipTransaction) {
+ try {
+ $form->_lineItem = $membershipLineItems;
+ if (empty($form->_params['auto_renew']) && !empty($membershipParams['is_recur'])) {
+ unset($membershipParams['is_recur']);
+ }
+ $membershipContribution = $this->processSecondaryFinancialTransaction($contactID, $form, $membershipParams,
+ $isTest, $membershipLineItems, CRM_Utils_Array::value('minimum_fee', $membershipDetails, 0), CRM_Utils_Array::value('financial_type_id', $membershipDetails));
+ }
+ catch (CRM_Core_Exception $e) {
+ $errors[2] = $e->getMessage();
+ $membershipContribution = NULL;
+ }
+ }
+
+ $membership = NULL;
+ if (!empty($membershipContribution) && !is_a($membershipContribution, 'CRM_Core_Error')) {
+ $membershipContributionID = $membershipContribution->id;
+ }
+
+ //@todo - why is this nested so deep? it seems like it could be just set on the calling function on the form layer
+ if (isset($membershipParams['onbehalf']) && !empty($membershipParams['onbehalf']['member_campaign_id'])) {
+ $form->_params['campaign_id'] = $membershipParams['onbehalf']['member_campaign_id'];
+ }
+ //@todo it should no longer be possible for it to get to this point & membership to not be an array
+ if (is_array($membershipTypeIDs) && !empty($membershipContributionID)) {
+ $typesTerms = CRM_Utils_Array::value('types_terms', $membershipParams, array());
+ foreach ($membershipTypeIDs as $memType) {
+ $numTerms = CRM_Utils_Array::value($memType, $typesTerms, 1);
+ if (!empty($membershipContribution)) {
+ $pendingStatus = CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name');
+ $pending = ($membershipContribution->contribution_status_id == $pendingStatus) ? TRUE : FALSE;
+ }
+ else {
+ $pending = $isPending;
+ }
+ $contributionRecurID = isset($form->_params['contributionRecurID']) ? $form->_params['contributionRecurID'] : NULL;
+
+ $membershipSource = NULL;
+ if (!empty($form->_params['membership_source'])) {
+ $membershipSource = $form->_params['membership_source'];
+ }
+ elseif (isset($form->_values['title']) && !empty($form->_values['title'])) {
+ $membershipSource = ts('Online Contribution:') . ' ' . $form->_values['title'];
+ }
+ $isPayLater = NULL;
+ if (isset($form->_params)) {
+ $isPayLater = CRM_Utils_Array::value('is_pay_later', $form->_params);
+ }
+ $campaignId = NULL;
+ if (isset($form->_values) && is_array($form->_values) && !empty($form->_values)) {
+ $campaignId = CRM_Utils_Array::value('campaign_id', $form->_params);
+ if (!array_key_exists('campaign_id', $form->_params)) {
+ $campaignId = CRM_Utils_Array::value('campaign_id', $form->_values);
+ }
+ }
+
+ list($membership, $renewalMode, $dates) = CRM_Member_BAO_Membership::renewMembership(
+ $contactID, $memType, $isTest,
+ date('YmdHis'), CRM_Utils_Array::value('cms_contactID', $membershipParams),
+ $customFieldsFormatted,
+ $numTerms, $membershipID, $pending,
+ $contributionRecurID, $membershipSource, $isPayLater, $campaignId
+ );
+ $form->set('renewal_mode', $renewalMode);
+ if (!empty($dates)) {
+ $form->assign('mem_start_date',
+ CRM_Utils_Date::customFormat($dates['start_date'], '%Y%m%d')
+ );
+ $form->assign('mem_end_date',
+ CRM_Utils_Date::customFormat($dates['end_date'], '%Y%m%d')
+ );
+ }
+
+ if (!empty($membershipContribution)) {
+ // update recurring id for membership record
+ CRM_Member_BAO_Membership::updateRecurMembership($membership, $membershipContribution);
+ CRM_Member_BAO_Membership::linkMembershipPayment($membership, $membershipContribution);
+ }
+ }
+ if ($form->_priceSetId && !empty($form->_useForMember) && !empty($form->_lineItem)) {
+ foreach ($form->_lineItem[$form->_priceSetId] as & $priceFieldOp) {
+ if (!empty($priceFieldOp['membership_type_id']) &&
+ isset($createdMemberships[$priceFieldOp['membership_type_id']])
+ ) {
+ $membershipOb = $createdMemberships[$priceFieldOp['membership_type_id']];
+ $priceFieldOp['start_date'] = $membershipOb->start_date ? CRM_Utils_Date::customFormat($membershipOb->start_date, '%B %E%f, %Y') : '-';
+ $priceFieldOp['end_date'] = $membershipOb->end_date ? CRM_Utils_Date::customFormat($membershipOb->end_date, '%B %E%f, %Y') : '-';
+ }
+ else {
+ $priceFieldOp['start_date'] = $priceFieldOp['end_date'] = 'N/A';
+ }
+ }
+ $form->_values['lineItem'] = $form->_lineItem;
+ $form->assign('lineItem', $form->_lineItem);
+ }
+ }
+
+ if (!empty($errors)) {
+ $message = $this->compileErrorMessage($errors);
+ throw new CRM_Core_Exception($message);
+ }
+ $form->_params['createdMembershipIDs'] = array();
+
+ // CRM-7851 - Moved after processing Payment Errors
+ //@todo - the reasoning for this being here seems a little outdated
+ foreach ($createdMemberships as $createdMembership) {
+ CRM_Core_BAO_CustomValueTable::postProcess(
+ $form->_params,
+ 'civicrm_membership',
+ $createdMembership->id,
+ 'Membership'
+ );
+ $form->_params['createdMembershipIDs'][] = $createdMembership->id;
+ }
+ if (count($createdMemberships) == 1) {
+ //presumably this is only relevant for exactly 1 membership
+ $form->_params['membershipID'] = $createdMembership->id;
+ }
+
+ //CRM-15232: Check if membership is created and on the basis of it use
+ //membership receipt template to send payment receipt
+ if (count($createdMemberships)) {
+ $form->_values['isMembership'] = TRUE;
+ }
+ if (isset($membershipContributionID)) {
+ $form->_values['contribution_id'] = $membershipContributionID;
+ }
+ if ($form->_contributeMode) {
+ if ($form->_values['is_monetary'] && $form->_amount > 0.0 && !$form->_params['is_pay_later']) {
+ // call postProcess hook before leaving
+ $form->postProcessHook();
+ }
+ $payment = Civi\Payment\System::singleton()->getByProcessor($form->_paymentProcessor);
+ $result = $payment->doPayment($form->_params, 'contribute');
+
+ if (CRM_Utils_Array::value('payment_status_id', $result) == 1) {
+ // Refer to CRM-16737. Payment processors 'should' return payment_status_id
+ // to denote the outcome of the transaction.
+ try {
+ civicrm_api3('contribution', 'completetransaction', array(
+ 'id' => $paymentResult['contribution']->id,
+ 'trxn_id' => $paymentResult['contribution']->trxn_id,
+ 'is_transactional' => FALSE,
+ ));
+ }
+ catch (CiviCRM_API3_Exception $e) {
+ // if for any reason it is already completed this will fail - e.g extensions hacking around core not completing transactions prior to CRM-15296
+ // so let's be gentle here
+ CRM_Core_Error::debug_log_message('contribution ' . $membershipContribution->id . ' not completed with trxn_id ' . $membershipContribution->trxn_id . ' and message ' . $e->getMessage());
+ }
+ }
+ // Do not send an email if Recurring transaction is done via Direct Mode
+ // Email will we sent when the IPN is received.
+ return;
+ }
+
+ //finally send an email receipt
+ CRM_Contribute_BAO_ContributionPage::sendMail($contactID,
+ $form->_values,
+ $isTest, FALSE,
+ $includeFieldTypes
+ );
+ }
+
+ /**
+ * Turn array of errors into message string.
+ *
+ * @param array $errors
+ *
+ * @return string
+ */
+ protected function compileErrorMessage($errors) {
+ foreach ($errors as $error) {
+ if (is_string($error)) {
+ $message[] = $error;
+ }
+ }
+ return ts('Payment Processor Error message') . ': ' . implode('<br/>', $message);
+ }
+
+ /**
+ * Where a second separate financial transaction is supported we will process it here.
+ *
+ * @param int $contactID
+ * @param CRM_Contribute_Form_Contribution_Confirm $form
+ * @param array $tempParams
+ * @param bool $isTest
+ * @param array $lineItems
+ * @param $minimumFee
+ * @param int $financialTypeID
+ *
+ * @throws CRM_Core_Exception
+ * @throws Exception
+ * @return CRM_Contribute_BAO_Contribution
+ */
+ protected function processSecondaryFinancialTransaction($contactID, &$form, $tempParams, $isTest, $lineItems, $minimumFee,
+ $financialTypeID) {
+ $financialType = new CRM_Financial_DAO_FinancialType();
+ $financialType->id = $financialTypeID;
+ $financialType->find(TRUE);
+ $tempParams['amount'] = $minimumFee;
+ $tempParams['invoiceID'] = md5(uniqid(rand(), TRUE));
+
+ $result = NULL;
+ if ($form->_values['is_monetary'] && !$form->_params['is_pay_later'] && $minimumFee > 0.0) {
+ // At the moment our tests are calling this form in a way that leaves 'object' empty. For
+ // now we compensate here.
+ if (empty($form->_paymentProcessor['object'])) {
+ $payment = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
+ }
+ else {
+ $payment = $form->_paymentProcessor['object'];
+ }
+ $result = $payment->doPayment($tempParams, 'contribute');
+ }
+
+ //assign receive date when separate membership payment
+ //and contribution amount not selected.
+ if ($form->_amount == 0) {
+ $now = date('YmdHis');
+ $form->_params['receive_date'] = $now;
+ $receiveDate = CRM_Utils_Date::mysqlToIso($now);
+ $form->set('params', $form->_params);
+ $form->assign('receive_date', $receiveDate);
+ }
+
+ $form->set('membership_trx_id', $result['trxn_id']);
+ $form->set('membership_amount', $minimumFee);
+
+ $form->assign('membership_trx_id', $result['trxn_id']);
+ $form->assign('membership_amount', $minimumFee);
+
+ // we don't need to create the user twice, so lets disable cms_create_account
+ // irrespective of the value, CRM-2888
+ $tempParams['cms_create_account'] = 0;
+
+ //CRM-16165, scenarios are
+ // 1) If contribution is_pay_later and if contribution amount is > 0.0 we set pending = TRUE, vice-versa FALSE
+ // 2) If not pay later but auto-renewal membership is chosen then pending = TRUE as it later triggers
+ // pending recurring contribution, vice-versa FALSE
+ $pending = $form->_params['is_pay_later'] ? (($minimumFee > 0.0) ? TRUE : FALSE) : (!empty($form->_params['auto_renew']) ? TRUE : FALSE);
+
+ //set this variable as we are not creating pledge for
+ //separate membership payment contribution.
+ //so for differentiating membership contribution from
+ //main contribution.
+ $form->_params['separate_membership_payment'] = 1;
+ $membershipContribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($form,
+ $tempParams,
+ $result,
+ $contactID,
+ $financialType,
+ $pending,
+ TRUE,
+ $isTest,
+ $lineItems,
+ $form->_bltID
+ );
+ return $membershipContribution;
+ }
+
+ /**
+ * Is the payment a pending payment.
+ *
+ * We are moving towards always creating as pending and updating at the end (based on payment), so this should be
+ * an interim refactoring. It was shared with another unrelated form & some parameters may not apply to this form.
+ *
+ *
+ * @return bool
+ */
+ protected function getIsPending() {
+ if (((isset($this->_contributeMode)) || !empty
+ ($this->_params['is_pay_later'])
+ ) &&
+ (($this->_values['is_monetary'] && $this->_amount > 0.0))
+ ) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * Are we going to do 2 financial transactions.
+ *
+ * Ie the membership block supports a separate transactions AND the contribution form has been configured for a
+ * contribution
+ * transaction AND a membership transaction AND the payment processor supports double financial transactions (ie. NOT doTransferPayment style)
+ *
+ * @param int $formID
+ * @param bool $amountBlockActiveOnForm
+ *
+ * @return bool
+ */
+ public function isSeparateMembershipTransaction($formID, $amountBlockActiveOnForm) {
+ $memBlockDetails = CRM_Member_BAO_Membership::getMembershipBlock($formID);
+ if (!empty($memBlockDetails['is_separate_payment']) && $amountBlockActiveOnForm) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * This function sets the fields.
+ *
+ * - $this->_params['amount_level']
+ * - $this->_params['selectMembership']
+ * And under certain circumstances sets
+ * $this->_params['amount'] = null;
+ *
+ * @param int $priceSetID
+ */
+ public function setFormAmountFields($priceSetID) {
+ $isQuickConfig = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_params['priceSetId'], 'is_quick_config');
+ $priceField = new CRM_Price_DAO_PriceField();
+ $priceField->price_set_id = $priceSetID;
+ $priceField->orderBy('weight');
+ $priceField->find();
+ $paramWeDoNotUnderstand = NULL;
+
+ while ($priceField->fetch()) {
+ if ($priceField->name == "contribution_amount") {
+ $paramWeDoNotUnderstand = $priceField->id;
+ }
+ if ($isQuickConfig && !empty($this->_params["price_{$priceField->id}"])) {
+ if ($this->_values['fee'][$priceField->id]['html_type'] != 'Text') {
+ $this->_params['amount_level'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue',
+ $this->_params["price_{$priceField->id}"], 'label');
+ }
+ if ($priceField->name == "membership_amount") {
+ $this->_params['selectMembership'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue',
+ $this->_params["price_{$priceField->id}"], 'membership_type_id');
+ }
+ }
+ // If separate payment we set contribution amount to be null, so that it will not show contribution amount same
+ // as membership amount.
+ // @todo - this needs more documentation - it appears the setting to null is tied up with separate membership payments
+ // but the circumstances are very confusing. Many of these conditions are repeated in the next conditional
+ // so we should merge them together
+ // the quick config seems like a red-herring - if this is about a separate membership payment then there
+ // are 2 types of line items - membership ones & non-membership ones - regardless of whether quick config is set
+ elseif (
+ CRM_Utils_Array::value('is_separate_payment', $this->_membershipBlock)
+ && !empty($this->_values['fee'][$priceField->id])
+ && ($this->_values['fee'][$priceField->id]['name'] == "other_amount")
+ && CRM_Utils_Array::value("price_{$paramWeDoNotUnderstand}", $this->_params) < 1
+ && empty($this->_params["price_{$priceField->id}"])
+ ) {
+ $this->_params['amount'] = NULL;
+ }
+
+ // Fix for CRM-14375 - If we are using separate payments and "no
+ // thank you" is selected for the additional contribution, set
+ // contribution amount to be null, so that it will not show
+ // contribution amount same as membership amount.
+ //@todo - merge with section above
+ if ($this->_membershipBlock['is_separate_payment']
+ && !empty($this->_values['fee'][$priceField->id])
+ && CRM_Utils_Array::value('name', $this->_values['fee'][$priceField->id]) == 'contribution_amount'
+ && CRM_Utils_Array::value("price_{$priceField->id}", $this->_params) == '-1'
+ ) {
+ $this->_params['amount'] = NULL;
+ }
+ }
+ }
+
+ /**
+ * Submit function.
+ *
+ * @param array $params
+ *
+ * @throws CiviCRM_API3_Exception
+ */
+ public static function submit($params) {
+ $form = new CRM_Contribute_Form_Contribution_Confirm();
+ $form->_id = $params['id'];
+
+ CRM_Contribute_BAO_ContributionPage::setValues($form->_id, $form->_values);
+ $form->_separateMembershipPayment = CRM_Contribute_BAO_ContributionPage::getIsMembershipPayment($form->_id);
+ //this way the mocked up controller ignores the session stuff
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $form->controller = new CRM_Contribute_Controller_Contribution();
+ $params['invoiceID'] = md5(uniqid(rand(), TRUE));
+ $paramsProcessedForForm = $form->_params = self::getFormParams($params['id'], $params);
+ $form->_amount = $params['amount'];
+ $priceSetID = $form->_params['priceSetId'] = $paramsProcessedForForm['price_set_id'];
+ $priceFields = CRM_Price_BAO_PriceSet::getSetDetail($priceSetID);
+ $priceSetFields = reset($priceFields);
+ $form->_values['fee'] = $priceSetFields['fields'];
+ $form->_priceSetId = $priceSetID;
+ $form->setFormAmountFields($priceSetID);
+ if (!empty($params['payment_processor_id'])) {
+ $form->_paymentProcessor = civicrm_api3('payment_processor', 'getsingle', array(
+ 'id' => $params['payment_processor_id'],
+ ));
+ if ($form->_paymentProcessor['billing_mode'] == 1) {
+ $form->_contributeMode = 'direct';
+ }
+ else {
+ $form->_contributeMode = 'notify';
+ }
+ }
+ else {
+ $form->_params['payment_processor_id'] = 0;
+ }
+ $priceFields = $priceFields[$priceSetID]['fields'];
+ CRM_Price_BAO_PriceSet::processAmount($priceFields, $paramsProcessedForForm, $lineItems, 'civicrm_contribution');
+ $form->_lineItem = array($priceSetID => $lineItems);
+ $form->processFormSubmission(CRM_Utils_Array::value('contact_id', $params));
+ }
+
+ /**
+ * Helper function for static submit function.
+ *
+ * Set relevant params - help us to build up an array that we can pass in.
+ *
+ * @param int $id
+ * @param array $params
+ *
+ * @return array
+ * @throws CiviCRM_API3_Exception
+ */
+ public static function getFormParams($id, array $params) {
+ if (!isset($params['is_pay_later'])) {
+ if (!empty($params['payment_processor_id'])) {
+ $params['is_pay_later'] = 0;
+ }
+ else {
+ $params['is_pay_later'] = civicrm_api3('contribution_page', 'getvalue', array(
+ 'id' => $id,
+ 'return' => 'is_pay_later',
+ ));
+ }
+ }
+ if (empty($params['price_set_id'])) {
+ $params['price_set_id'] = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $params['id']);
+ }
+ return $params;
+ }
+
+ /**
+ * Post form submission handling.
+ *
+ * This is also called from the test suite.
+ *
+ * @param int $contactID
+ *
+ * @return array
+ */
+ protected function processFormSubmission($contactID) {
+ $isPayLater = $this->_params['is_pay_later'];
+ if (isset($this->_params['payment_processor_id']) && $this->_params['payment_processor_id'] == 0) {
+ $this->_params['is_pay_later'] = $isPayLater = TRUE;
+ }
+ // add a description field at the very beginning
+ $this->_params['description'] = ts('Online Contribution') . ': ' . (($this->_pcpInfo['title']) ? $this->_pcpInfo['title'] : $this->_values['title']);
+
+ $this->_params['accountingCode'] = CRM_Utils_Array::value('accountingCode', $this->_values);
+
+ // fix currency ID
+ $this->_params['currencyID'] = CRM_Core_Config::singleton()->defaultCurrency;
+
+ //carry payment processor id.
+ if (CRM_Utils_Array::value('id', $this->_paymentProcessor)) {
+ $this->_params['payment_processor_id'] = $this->_paymentProcessor['id'];
+ }
++
++ $premiumParams = $membershipParams = $params = $this->_params;
+ if (!empty($params['image_URL'])) {
+ CRM_Contact_BAO_Contact::processImageParams($params);
+ }
- $premiumParams = $membershipParams = $params = $this->_params;
++
+ $fields = array('email-Primary' => 1);
+
+ // get the add to groups
+ $addToGroups = array();
+
+ // now set the values for the billing location.
+ foreach ($this->_fields as $name => $value) {
+ $fields[$name] = 1;
+
+ // get the add to groups for uf fields
+ if (!empty($value['add_to_group_id'])) {
+ $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id'];
+ }
+ }
+
+ if (!array_key_exists('first_name', $fields)) {
+ $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;
+ }
+ }
+ }
+
+ // billing email address
+ $fields["email-{$this->_bltID}"] = 1;
+
+ //unset the billing parameters if it is pay later mode
+ //to avoid creation of billing location
+ if ($isPayLater && !$this->_isBillingAddressRequiredForPayLater) {
+ $billingFields = array(
+ 'billing_first_name',
+ 'billing_middle_name',
+ 'billing_last_name',
+ "billing_street_address-{$this->_bltID}",
+ "billing_city-{$this->_bltID}",
+ "billing_state_province-{$this->_bltID}",
+ "billing_state_province_id-{$this->_bltID}",
+ "billing_postal_code-{$this->_bltID}",
+ "billing_country-{$this->_bltID}",
+ "billing_country_id-{$this->_bltID}",
+ );
+
+ foreach ($billingFields as $value) {
+ unset($params[$value]);
+ unset($fields[$value]);
+ }
+ }
+
+ // if onbehalf-of-organization contribution, take out
+ // organization params in a separate variable, to make sure
+ // normal behavior is continued. And use that variable to
+ // process on-behalf-of functionality.
+ if (!empty($this->_params['hidden_onbehalf_profile'])) {
+ $behalfOrganization = array();
+ $orgFields = array('organization_name', 'organization_id', 'org_option');
+ foreach ($orgFields as $fld) {
+ if (array_key_exists($fld, $params)) {
+ $behalfOrganization[$fld] = $params[$fld];
+ unset($params[$fld]);
+ }
+ }
+
+ if (is_array($params['onbehalf']) && !empty($params['onbehalf'])) {
+ foreach ($params['onbehalf'] as $fld => $values) {
+ if (strstr($fld, 'custom_')) {
+ $behalfOrganization[$fld] = $values;
+ }
+ elseif (!(strstr($fld, '-'))) {
+ if (in_array($fld, array(
+ 'contribution_campaign_id',
+ 'member_campaign_id',
+ ))) {
+ $fld = 'campaign_id';
+ }
+ else {
+ $behalfOrganization[$fld] = $values;
+ }
+ $this->_params[$fld] = $values;
+ }
+ }
+ }
+
+ if (array_key_exists('onbehalf_location', $params) && is_array($params['onbehalf_location'])) {
+ foreach ($params['onbehalf_location'] as $block => $vals) {
+ //fix for custom data (of type checkbox, multi-select)
+ if (substr($block, 0, 7) == 'custom_') {
+ continue;
+ }
+ // fix the index of block elements
+ if (is_array($vals)) {
+ foreach ($vals as $key => $val) {
+ //dont adjust the index of address block as
+ //it's index is WRT to location type
+ $newKey = ($block == 'address') ? $key : ++$key;
+ $behalfOrganization[$block][$newKey] = $val;
+ }
+ }
+ }
+ unset($params['onbehalf_location']);
+ }
+ if (!empty($params['onbehalf[image_URL]'])) {
+ $behalfOrganization['image_URL'] = $params['onbehalf[image_URL]'];
+ }
+ }
+
+ // check for profile double opt-in and get groups to be subscribed
+ $subscribeGroupIds = CRM_Core_BAO_UFGroup::getDoubleOptInGroupIds($params, $contactID);
+
+ // since we are directly adding contact to group lets unset it from mailing
+ if (!empty($addToGroups)) {
+ foreach ($addToGroups as $groupId) {
+ if (isset($subscribeGroupIds[$groupId])) {
+ unset($subscribeGroupIds[$groupId]);
+ }
+ }
+ }
+
+ foreach ($addToGroups as $k) {
+ if (array_key_exists($k, $subscribeGroupIds)) {
+ unset($addToGroups[$k]);
+ }
+ }
+
+ if (empty($contactID)) {
+ $dupeParams = $params;
+ if (!empty($dupeParams['onbehalf'])) {
+ unset($dupeParams['onbehalf']);
+ }
+ if (!empty($dupeParams['honor'])) {
+ unset($dupeParams['honor']);
+ }
+
+ $dedupeParams = CRM_Dedupe_Finder::formatParams($dupeParams, 'Individual');
+ $dedupeParams['check_permission'] = FALSE;
+ $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Individual');
+
+ // if we find more than one contact, use the first one
+ $contactID = CRM_Utils_Array::value(0, $ids);
+
+ // Fetch default greeting id's if creating a contact
+ if (!$contactID) {
+ foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
+ if (!isset($params[$greeting])) {
+ $params[$greeting] = CRM_Contact_BAO_Contact_Utils::defaultGreeting('Individual', $greeting);
+ }
+ }
+ }
+ $contactType = NULL;
+ }
+ else {
+ $contactType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactID, 'contact_type');
+ }
+ $contactID = CRM_Contact_BAO_Contact::createProfileContact(
+ $params,
+ $fields,
+ $contactID,
+ $addToGroups,
+ NULL,
+ $contactType,
+ TRUE
+ );
+
+ // Make the contact ID associated with the contribution available at the Class level.
+ // Also make available to the session.
+ //@todo consider handling this in $this->getContactID();
+ $this->set('contactID', $contactID);
+ $this->_contactID = $contactID;
+
+ //get email primary first if exist
+ $subscriptionEmail = array('email' => CRM_Utils_Array::value('email-Primary', $params));
+ if (!$subscriptionEmail['email']) {
+ $subscriptionEmail['email'] = CRM_Utils_Array::value("email-{$this->_bltID}", $params);
+ }
+ // subscribing contact to groups
+ if (!empty($subscribeGroupIds) && $subscriptionEmail['email']) {
+ CRM_Mailing_Event_BAO_Subscribe::commonSubscribe($subscribeGroupIds, $subscriptionEmail, $contactID);
+ }
+
+ // If onbehalf-of-organization contribution / signup, add organization
+ // and it's location.
+ if (isset($params['hidden_onbehalf_profile']) && isset($behalfOrganization['organization_name'])) {
+ $ufFields = array();
+ foreach ($this->_fields['onbehalf'] as $name => $value) {
+ $ufFields[$name] = 1;
+ }
+ self::processOnBehalfOrganization($behalfOrganization, $contactID, $this->_values,
+ $this->_params, $ufFields
+ );
+ }
+ elseif (!empty($this->_membershipContactID) && $contactID != $this->_membershipContactID) {
+ // this is an onbehalf renew case for inherited membership. For e.g a permissioned member of household,
+ // store current user id as related contact for later use for mailing / activity..
+ $this->_values['related_contact'] = $contactID;
+ $this->_params['related_contact'] = $contactID;
+ // swap contact like we do for on-behalf-org case, so parent/primary membership is affected
+ $contactID = $this->_membershipContactID;
+ }
+
+ // lets store the contactID in the session
+ // for things like tell a friend
+ $session = CRM_Core_Session::singleton();
+ if (!$session->get('userID')) {
+ $session->set('transaction.userID', $contactID);
+ }
+ else {
+ $session->set('transaction.userID', NULL);
+ }
- /**
- * Process membership.
- *
- * @param array $membershipParams
- * @param int $contactID
- * @param array $customFieldsFormatted
- * @param array $fieldTypes
- * @param array $premiumParams
- * @param array $membershipLineItems
- * Line items specifically relating to memberships.
- * @param $isPayLater
- */
- public function processMembership($membershipParams, $contactID, $customFieldsFormatted, $fieldTypes, $premiumParams, $membershipLineItems, $isPayLater) {
- try {
- $membershipTypeIDs = (array) $membershipParams['selectMembership'];
- $membershipTypes = CRM_Member_BAO_Membership::buildMembershipTypeValues($this, $membershipTypeIDs);
- $membershipType = empty($membershipTypes) ? array() : reset($membershipTypes);
- $this->assign('membership_name', CRM_Utils_Array::value('name', $membershipType));
+ $this->_useForMember = $this->get('useForMember');
- $isPaidMembership = FALSE;
- if ($this->_amount >= 0.0 && isset($membershipParams['amount'])) {
- //amount must be greater than zero for
- //adding contribution record to contribution table.
- //this condition arises when separate membership payment is
- //enabled and contribution amount is not selected. fix for CRM-3010
- $isPaidMembership = TRUE;
+ // store the fact that this is a membership and membership type is selected
+ if ((!empty($membershipParams['selectMembership']) &&
+ $membershipParams['selectMembership'] != 'no_thanks'
+ ) ||
+ $this->_useForMember
+ ) {
+ if (!$this->_useForMember) {
+ $this->assign('membership_assign', TRUE);
+ $this->set('membershipTypeID', $this->_params['selectMembership']);
}
- $isProcessSeparateMembershipTransaction = $this->isSeparateMembershipTransaction($this->_id, $this->_values['amount_block_is_active']);
- if ($this->_values['amount_block_is_active']) {
- $contributionTypeId = $this->_values['financial_type_id'];
+ if ($this->_action & CRM_Core_Action::PREVIEW) {
+ $membershipParams['is_test'] = 1;
}
- else {
- $contributionTypeId = CRM_Utils_Array::value('financial_type_id', $membershipType, CRM_Utils_Array::value('financial_type_id', $membershipParams));
+ if ($this->_params['is_pay_later']) {
+ $membershipParams['is_pay_later'] = 1;
}
- CRM_Member_BAO_Membership::postProcessMembership($membershipParams, $contactID,
- $this, $premiumParams, $customFieldsFormatted, $fieldTypes, $membershipType, $membershipTypeIDs, $isPaidMembership, $this->_membershipId, $isProcessSeparateMembershipTransaction, $contributionTypeId,
- $membershipLineItems, $isPayLater
- );
- $this->assign('membership_assign', TRUE);
- $this->set('membershipTypeID', $membershipParams['selectMembership']);
- }
- catch (CRM_Core_Exception $e) {
- CRM_Core_Session::singleton()->setStatus($e->getMessage());
- CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/transact', "_qf_Main_display=true&qfKey={$this->_params['qfKey']}"));
- }
- }
+ //inherit campaign from contribution page.
+ if (!array_key_exists('campaign_id', $membershipParams)) {
+ $membershipParams['campaign_id'] = CRM_Utils_Array::value('campaign_id', $this->_values);
+ }
- /**
- * Are we going to do 2 financial transactions.
- *
- * Ie the membership block supports a separate transactions AND the contribution form has been configured for a
- * contribution
- * transaction AND a membership transaction AND the payment processor supports double financial transactions (ie. NOT doTransferPayment style)
- *
- * @param int $formID
- * @param bool $amountBlockActiveOnForm
- *
- * @return bool
- */
- public function isSeparateMembershipTransaction($formID, $amountBlockActiveOnForm) {
- $memBlockDetails = CRM_Member_BAO_Membership::getMembershipBlock($formID);
- if (!empty($memBlockDetails['is_separate_payment']) && $amountBlockActiveOnForm) {
- return TRUE;
+ CRM_Core_Payment_Form::mapParams($this->_bltID, $this->_params, $membershipParams, TRUE);
+ $this->doMembershipProcessing($contactID, $membershipParams, $premiumParams, $isPayLater);
}
- return FALSE;
- }
-
- /**
- * This function sets the fields.
- *
- * - $this->_params['amount_level']
- * - $this->_params['selectMembership']
- * And under certain circumstances sets
- * $this->_params['amount'] = null;
- *
- * @param int $priceSetID
- */
- public function setFormAmountFields($priceSetID) {
- $isQuickConfig = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_params['priceSetId'], 'is_quick_config');
- $priceField = new CRM_Price_DAO_PriceField();
- $priceField->price_set_id = $priceSetID;
- $priceField->orderBy('weight');
- $priceField->find();
- $paramWeDoNotUnderstand = NULL;
+ else {
+ // 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;
+ $contributionTypeId = $this->_values['financial_type_id'];
- while ($priceField->fetch()) {
- if ($priceField->name == "contribution_amount") {
- $paramWeDoNotUnderstand = $priceField->id;
- }
- if ($isQuickConfig && !empty($this->_params["price_{$priceField->id}"])) {
- if ($this->_values['fee'][$priceField->id]['html_type'] != 'Text') {
- $this->_params['amount_level'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue',
- $this->_params["price_{$priceField->id}"], 'label');
- }
- if ($priceField->name == "membership_amount") {
- $this->_params['selectMembership'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue',
- $this->_params["price_{$priceField->id}"], 'membership_type_id');
- }
- }
- // If separate payment we set contribution amount to be null, so that it will not show contribution amount same
- // as membership amount.
- // @todo - this needs more documentation - it appears the setting to null is tied up with separate membership payments
- // but the circumstances are very confusing. Many of these conditions are repeated in the next conditional
- // so we should merge them together
- // the quick config seems like a red-herring - if this is about a separate membership payment then there
- // are 2 types of line items - membership ones & non-membership ones - regardless of whether quick config is set
- elseif (
- CRM_Utils_Array::value('is_separate_payment', $this->_membershipBlock)
- && !empty($this->_values['fee'][$priceField->id])
- && ($this->_values['fee'][$priceField->id]['name'] == "other_amount")
- && CRM_Utils_Array::value("price_{$paramWeDoNotUnderstand}", $this->_params) < 1
- && empty($this->_params["price_{$priceField->id}"])
+ $fieldTypes = array();
+ if (!empty($paymentParams['onbehalf']) &&
+ is_array($paymentParams['onbehalf'])
) {
- $this->_params['amount'] = NULL;
+ foreach ($paymentParams['onbehalf'] as $key => $value) {
+ if (strstr($key, 'custom_')) {
+ $this->_params[$key] = $value;
+ }
+ }
+ $fieldTypes = array('Contact', 'Organization', 'Contribution');
}
+ $financialTypeID = $this->wrangleFinancialTypeID($contributionTypeId);
- // Fix for CRM-14375 - If we are using separate payments and "no
- // thank you" is selected for the additional contribution, set
- // contribution amount to be null, so that it will not show
- // contribution amount same as membership amount.
- //@todo - merge with section above
- if ($this->_membershipBlock['is_separate_payment']
- && !empty($this->_values['fee'][$priceField->id])
- && CRM_Utils_Array::value('name', $this->_values['fee'][$priceField->id]) == 'contribution_amount'
- && CRM_Utils_Array::value("price_{$priceField->id}", $this->_params) == '-1'
- ) {
- $this->_params['amount'] = NULL;
+ $result = CRM_Contribute_BAO_Contribution_Utils::processConfirm($this, $paymentParams,
+ $contactID,
+ $financialTypeID,
+ 'contribution',
+ $fieldTypes,
+ ($this->_mode == 'test') ? 1 : 0,
+ $isPayLater
+ );
+
+ if (!empty($result['is_payment_failure'])) {
+ return $result;
}
+ // @todo move premium processing to complete transaction if it truly is an 'after' action.
+ $this->postProcessPremium($premiumParams, $result['contribution']);
+ if (CRM_Utils_Array::value('payment_status_id', $result) == 1) {
+ civicrm_api3('contribution', 'completetransaction', array(
+ 'id' => $result['contribution']->id,
+ 'trxn_id' => CRM_Utils_Array::value('trxn_id', $result),
+ )
+ );
+ }
+ return $result;
}
}
$this->_id = $membership->id;
}
-
+ $statusMsg = '';
+ if (($this->_action & CRM_Core_Action::UPDATE)) {
+ $statusMsg = $this->getStatusMessageForUpdate($membership, $endDate, $receiptSend);
+ }
+ elseif (($this->_action & CRM_Core_Action::ADD)) {
+ $statusMsg = $this->getStatusMessageForCreate($endDate, $receiptSend, $membershipTypes, $createdMemberships,
+ $params, $calcDates, $mailSend);
+ }
+
CRM_Core_Session::setStatus($statusMsg, ts('Complete'), 'success');
+ return $createdMemberships;
+ }
+
+ /**
+ * Set context in session.
+ */
+ protected function setUserContext() {
$buttonName = $this->controller->getButtonName();
+ $session = CRM_Core_Session::singleton();
+
if ($this->_context == 'standalone') {
if ($buttonName == $this->getButtonName('upload', 'new')) {
$session->replaceUserContext(CRM_Utils_System::url('civicrm/member/add',
}
/**
- * Send email receipt.
+ * Get status message for updating membership.
*
- * @param CRM_Core_Form $form
- * Form object.
- * @param array $formValues
- * @param object $membership
- * Object.
+ * @param CRM_Member_BAO_Membership $membership
+ * @param string $endDate
+ * @param bool $receiptSend
*
- * @return bool
- * true if mail was sent successfully
+ * @return string
*/
- public static function emailReceipt(&$form, &$formValues, &$membership) {
- // retrieve 'from email id' for acknowledgement
- $receiptFrom = $formValues['from_email_address'];
-
- if (!empty($formValues['payment_instrument_id'])) {
- $paymentInstrument = CRM_Contribute_PseudoConstant::paymentInstrument();
- $formValues['paidBy'] = $paymentInstrument[$formValues['payment_instrument_id']];
- }
-
- // retrieve custom data
- $customFields = $customValues = array();
- if (property_exists($form, '_groupTree')
- && !empty($form->_groupTree)
- ) {
- foreach ($form->_groupTree as $groupID => $group) {
- if ($groupID == 'info') {
- continue;
- }
- foreach ($group['fields'] as $k => $field) {
- $field['title'] = $field['label'];
- $customFields["custom_{$k}"] = $field;
- }
- }
- }
-
- $members = array(array('member_id', '=', $membership->id, 0, 0));
- // check whether its a test drive
- if ($form->_mode == 'test') {
- $members[] = array('member_test', '=', 1, 0, 0);
- }
-
- CRM_Core_BAO_UFGroup::getValues($formValues['contact_id'], $customFields, $customValues, FALSE, $members);
-
- if ($form->_mode) {
- if (!empty($form->_params['billing_first_name'])) {
- $name = $form->_params['billing_first_name'];
- }
-
- if (!empty($form->_params['billing_middle_name'])) {
- $name .= " {$form->_params['billing_middle_name']}";
- }
-
- if (!empty($form->_params['billing_last_name'])) {
- $name .= " {$form->_params['billing_last_name']}";
- }
-
- $form->assign('billingName', $name);
-
- // assign the address formatted up for display
- $addressParts = array(
- "street_address-{$form->_bltID}",
- "city-{$form->_bltID}",
- "postal_code-{$form->_bltID}",
- "state_province-{$form->_bltID}",
- "country-{$form->_bltID}",
- );
- $addressFields = array();
- foreach ($addressParts as $part) {
- list($n, $id) = explode('-', $part);
- if (isset($form->_params['billing_' . $part])) {
- $addressFields[$n] = $form->_params['billing_' . $part];
- }
- }
- $form->assign('address', CRM_Utils_Address::format($addressFields));
+ protected function getStatusMessageForUpdate($membership, $endDate, $receiptSend) {
+ // End date can be modified by hooks, so if end date is set then use it.
+ $endDate = ($membership->end_date) ? $membership->end_date : $endDate;
- $date = CRM_Utils_Date::format($form->_params['credit_card_exp_date']);
- $date = CRM_Utils_Date::mysqlToIso($date);
- $form->assign('credit_card_exp_date', $date);
- $form->assign('credit_card_number',
- CRM_Utils_System::mungeCreditCard($form->_params['credit_card_number'])
- );
- $form->assign('credit_card_type', $form->_params['credit_card_type']);
- $form->assign('contributeMode', 'direct');
- $form->assign('isAmountzero', 0);
- $form->assign('is_pay_later', 0);
- $form->assign('isPrimary', 1);
+ $statusMsg = ts('Membership for %1 has been updated.', array(1 => $this->_memberDisplayName));
+ if ($endDate && $endDate !== 'null') {
+ $endDate = CRM_Utils_Date::customFormat($endDate);
+ $statusMsg .= ' ' . ts('The membership End Date is %1.', array(1 => $endDate));
}
- $form->assign('module', 'Membership');
- $form->assign('contactID', $formValues['contact_id']);
-
- $form->assign('membershipID', CRM_Utils_Array::value('membership_id', $form->_params, CRM_Utils_Array::value('membership_id', $form->_defaultValues)));
-
- if (!empty($formValues['contribution_id'])) {
- $form->assign('contributionID', $formValues['contribution_id']);
- }
- elseif (isset($form->_onlinePendingContributionId)) {
- $form->assign('contributionID', $form->_onlinePendingContributionId);
+ if ($receiptSend) {
+ $statusMsg .= ' ' . ts('A confirmation and receipt has been sent to %1.', array(1 => $this->_contributorEmail));
}
+ return $statusMsg;
+ }
- if (!empty($formValues['contribution_status_id'])) {
- $form->assign('contributionStatusID', $formValues['contribution_status_id']);
- $form->assign('contributionStatus', CRM_Contribute_PseudoConstant::contributionStatus($formValues['contribution_status_id'], 'name'));
- }
+ /**
+ * Get status message for create action.
+ *
+ * @param string $endDate
+ * @param bool $receiptSend
+ * @param array $membershipTypes
+ * @param array $createdMemberships
+ * @param array $params
+ * @param array $calcDates
+ * @param bool $mailSent
+ *
+ * @return array|string
+ */
+ protected function getStatusMessageForCreate($endDate, $receiptSend, $membershipTypes, $createdMemberships,
+ $params, $calcDates, $mailSent) {
+ // FIX ME: fix status messages
+
+ $statusMsg = array();
+ foreach ($membershipTypes as $memType => $membershipType) {
+ $statusMsg[$memType] = ts('%1 membership for %2 has been added.', array(
+ 1 => $membershipType,
+ 2 => $this->_memberDisplayName,
+ ));
- if (!empty($formValues['is_renew'])) {
- $form->assign('receiptType', 'membership renewal');
- }
- else {
- $form->assign('receiptType', 'membership signup');
- }
- $form->assign('receive_date', CRM_Utils_Date::processDate(CRM_Utils_Array::value('receive_date', $formValues)));
- $form->assign('formValues', $formValues);
+ $membership = $createdMemberships[$memType];
+ $memEndDate = ($membership->end_date) ? $membership->end_date : $endDate;
- if (empty($lineItem)) {
- $form->assign('mem_start_date', CRM_Utils_Date::customFormat($membership->start_date, '%B %E%f, %Y'));
- if (!CRM_Utils_System::isNull($membership->end_date)) {
- $form->assign('mem_end_date', CRM_Utils_Date::customFormat($membership->end_date, '%B %E%f, %Y'));
+ //get the end date from calculated dates.
+ if (!$memEndDate && empty($params['is_recur'])) {
+ $memEndDate = CRM_Utils_Array::value('end_date', $calcDates[$memType]);
}
- $form->assign('membership_name', CRM_Member_PseudoConstant::membershipType($membership->membership_type_id));
- }
- $form->assign('customValues', $customValues);
- $isBatchProcess = is_a($form, 'CRM_Batch_Form_Entry');
- if ((empty($form->_contributorDisplayName) || empty($form->_contributorEmail)) || $isBatchProcess) {
- // in this case the form is being called statically from the batch editing screen
- // having one class in the form layer call another statically is not greate
- // & we should aim to move this function to the BAO layer in future.
- // however, we can assume that the contact_id passed in by the batch
- // function will be the recipient
- list($form->_contributorDisplayName, $form->_contributorEmail)
- = CRM_Contact_BAO_Contact_Location::getEmailDetails($formValues['contact_id']);
- if (empty($form->_receiptContactId) || $isBatchProcess) {
- $form->_receiptContactId = $formValues['contact_id'];
+ if ($memEndDate && $memEndDate !== 'null') {
+ $memEndDate = CRM_Utils_Date::customFormat($memEndDate);
+ $statusMsg[$memType] .= ' ' . ts('The new membership End Date is %1.', array(1 => $memEndDate));
}
}
- $template = CRM_Core_Smarty::singleton();
- $taxAmt = $template->get_template_vars('dataArray');
- $eventTaxAmt = $template->get_template_vars('totalTaxAmount');
- $prefixValue = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
- $invoicing = CRM_Utils_Array::value('invoicing', $prefixValue);
- if ((!empty($taxAmt) || isset($eventTaxAmt)) && (isset($invoicing) && isset($prefixValue['is_email_pdf']))) {
- $isEmailPdf = TRUE;
- }
- else {
- $isEmailPdf = FALSE;
+ $statusMsg = implode('<br/>', $statusMsg);
- if ($receiptSend && $mailSent) {
++ if ($receiptSend && !empty($mailSent)) {
+ $statusMsg .= ' ' . ts('A membership confirmation and receipt has been sent to %1.', array(1 => $this->_contributorEmail));
}
-
- list($mailSend, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate(
- array(
- 'groupName' => 'msg_tpl_workflow_membership',
- 'valueName' => 'membership_offline_receipt',
- 'contactId' => $form->_receiptContactId,
- 'from' => $receiptFrom,
- 'toName' => $form->_contributorDisplayName,
- 'toEmail' => $form->_contributorEmail,
- 'PDFFilename' => ts('receipt') . '.pdf',
- 'isEmailPdf' => $isEmailPdf,
- 'contributionId' => $formValues['contribution_id'],
- 'isTest' => (bool) ($form->_action & CRM_Core_Action::PREVIEW),
- )
- );
-
- return TRUE;
+ return $statusMsg;
}
}
"google-code-prettify": "~1.0",
"select2": "colemanw/select2#stable/3.5",
"jquery-validation": "~1.13",
- "font-awesome": "~4.3"
+ "datatables": "~1.10",
+ "ckeditor": "~4.5",
++ "font-awesome": "~4.3",
+ "angular-sanitize": "~1.3.15"
},
"resolutions": {
"angular": "~1.3.8"
"symfony/dependency-injection": "2.3.*",
"symfony/event-dispatcher": "2.3.*",
"symfony/process": "2.3.*",
- "psr/log": "1.0.0",
+ "psr/log": "~1.0.0",
"symfony/finder": "2.3.*",
- "totten/ca-config": "~13.02"
+ "totten/ca-config": "~13.02",
+ "civicrm/civicrm-cxn-rpc": "~0.15.07.07"
},
"scripts": {
"post-install-cmd": [
flag = true;
}
});
- cj('.price-set-option-content input').change( function () {
++
+ cj('.price-set-option-content input[data-amount]').change( function () {
if (cj(this).attr('data-amount').replace(/[^\/\d]/g,'') == 0 ) {
flag = true;
} else {
</tr>
<tr class="crm-membership-form-block-record_contribution"><td colspan="2">
<fieldset id="recordContribution"><legend>{ts}Membership Payment and Receipt{/ts}</legend>
- <table>
- <tr class="crm-membership-form-block-contribution-contact">
- <td class="label">{$form.is_different_contribution_contact.label}</td>
- <td>{$form.is_different_contribution_contact.html} {help id="id-contribution_contact"}</td>
- </tr>
- <tr id="record-different-contact">
- <td> </td>
- <td>
- <table class="compressed">
- <tr class="crm-membership-form-block-soft-credit-type">
- <td class="label">{$form.soft_credit_type_id.label}</td>
- <td>{$form.soft_credit_type_id.html}</td>
- </tr>
- <tr class="crm-membership-form-block-soft-credit-contact-id">
- <td class="label">{$form.soft_credit_contact_id.label}</td>
- <td>{$form.soft_credit_contact_id.html}</td>
- </tr>
- </table>
- </td>
- </tr>
- <tr class="crm-membership-form-block-financial_type_id">
- <td class="label">{$form.financial_type_id.label}</td>
- <td>{$form.financial_type_id.html}<br />
- <span class="description">{ts}Select the appropriate financial type for this payment.{/ts}</span></td>
- </tr>
- <tr class="crm-membership-form-block-total_amount">
- <td class="label">{$form.total_amount.label}</td>
- <td>{$form.total_amount.html}<br />
- <span class="description">{ts}Membership payment amount. A contribution record will be created for this amount.{/ts}</span><div class="totaltaxAmount"></div></td>
- </tr>
- <tr class="crm-membership-form-block-receive_date">
- <td class="label">{$form.receive_date.label}</td>
- <td>{include file="CRM/common/jcalendar.tpl" elementName=receive_date}</td>
- </tr>
- <tr class="crm-membership-form-block-payment_instrument_id">
- <td class="label">{$form.payment_instrument_id.label}<span class="marker"> *</span></td>
- <td>{$form.payment_instrument_id.html} {help id="payment_instrument_id" file="CRM/Contribute/Page/Tab.hlp"}</td>
- </tr>
- <tr id="checkNumber" class="crm-membership-form-block-check_number">
- <td class="label">{$form.check_number.label}</td>
- <td>{$form.check_number.html|crmAddClass:six}</td>
- </tr>
- {if $action neq 2 }
- <tr class="crm-membership-form-block-trxn_id">
- <td class="label">{$form.trxn_id.label}</td>
- <td>{$form.trxn_id.html}</td>
- </tr>
- {/if}
- <tr class="crm-membership-form-block-contribution_status_id">
- <td class="label">{$form.contribution_status_id.label}</td>
- <td>{$form.contribution_status_id.html}</td>
- </tr>
- </table>
- </fieldset>
- </td></tr>
- {else}
- <div class="spacer"></div>
- {/if}
+ {/if}
+ {include file="CRM/Member/Form/MembershipCommon.tpl"}
- {if $emailExists and $outBound_option != 2 }
+ {if $emailExists and $outBound_option != 2}
<tr id="send-receipt" class="crm-membership-form-block-send_receipt">
<td class="label">{$form.send_receipt.label}</td><td>{$form.send_receipt.html}<br />
- <span class="description">{ts 1=$emailExists}Automatically email a membership confirmation and receipt to %1?{/ts}</span></td>
+ <span class="description">{ts 1=$emailExists}Automatically email a membership confirmation and receipt to %1 ?{/ts} {ts}OR if the payment is from a different contact, this email will only go to them.{/ts}</span></td>
</tr>
- {elseif $context eq 'standalone' and $outBound_option != 2 }
+ {elseif $context eq 'standalone' and $outBound_option != 2}
<tr id="email-receipt" style="display:none;">
<td class="label">{$form.send_receipt.label}</td><td>{$form.send_receipt.html}<br />
- <span class="description">{ts}Automatically email a membership confirmation and receipt to {/ts}<span id="email-address"></span>?</span></td>
+ <span class="description">{ts}Automatically email a membership confirmation and receipt to {/ts}<span id="email-address"></span>? {ts}OR if the payment is from a different contact, this email will only go to them.{/ts}</span></td>
</tr>
{/if}
<tr id="fromEmail" style="display:none;">