/** * Process the form submission. * * * @return void */ public function postProcess() { if ($this->_action & CRM_Core_Action::DELETE) { CRM_Member_BAO_Membership::del($this->_id); return; } $allMemberStatus = CRM_Member_PseudoConstant::membershipStatus(); $allContributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(); $isTest = $this->_mode == 'test' ? 1 : 0; $lineItems = NULL; if (!empty($this->_lineItem)) { $lineItems = $this->_lineItem; } $config = CRM_Core_Config::singleton(); // get the submitted form values. $this->_params = $formValues = $this->controller->exportValues($this->_name); $this->convertDateFieldsToMySQL($formValues); $params = $softParams = $ids = array(); $membershipTypeValues = array(); foreach ($this->_memTypeSelected as $memType) { $membershipTypeValues[$memType]['membership_type_id'] = $memType; } //take the required membership recur values. if ($this->_mode && !empty($this->_params['auto_renew'])) { $params['is_recur'] = $this->_params['is_recur'] = $formValues['is_recur'] = TRUE; $mapping = array('frequency_interval' => 'duration_interval', 'frequency_unit' => 'duration_unit'); $count = 0; foreach ($this->_memTypeSelected as $memType) { $recurMembershipTypeValues = CRM_Utils_Array::value($memType, $this->_recurMembershipTypes, array()); foreach ($mapping as $mapVal => $mapParam) { $membershipTypeValues[$memType][$mapVal] = CRM_Utils_Array::value($mapParam, $recurMembershipTypeValues); if (!$count) { $this->_params[$mapVal] = $formValues[$mapVal] = CRM_Utils_Array::value($mapParam, $recurMembershipTypeValues); } } $count++; } } // process price set and get total amount and line items. $lineItem = array(); $priceSetId = NULL; if (!($priceSetId = CRM_Utils_Array::value('price_set_id', $formValues))) { CRM_Member_BAO_Membership::createLineItems($this, $formValues['membership_type_id'], $priceSetId); } $isQuickConfig = 0; if ($this->_priceSetId && CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) { $isQuickConfig = 1; } $termsByType = array(); if ($priceSetId) { CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'], $this->_params, $lineItem[$priceSetId]); if (CRM_Utils_Array::value('tax_amount', $this->_params)) { $params['tax_amount'] = $this->_params['tax_amount']; } $params['total_amount'] = CRM_Utils_Array::value('amount', $this->_params); $submittedFinancialType = CRM_Utils_Array::value('financial_type_id', $formValues); if (!empty($lineItem[$priceSetId])) { foreach ($lineItem[$priceSetId] as &$li) { if (!empty($li['membership_type_id'])) { if (!empty($li['membership_num_terms'])) { $termsByType[$li['membership_type_id']] = $li['membership_num_terms']; } } ///CRM-11529 for quick config backoffice transactions //when financial_type_id is passed in form, update the //lineitems with the financial type selected in form if ($isQuickConfig && $submittedFinancialType) { $li['financial_type_id'] = $submittedFinancialType; } } } } $this->storeContactFields($formValues); $params['contact_id'] = $this->_contactID; $fields = array('status_id', 'source', 'is_override', 'campaign_id'); foreach ($fields as $f) { $params[$f] = CRM_Utils_Array::value($f, $formValues); } // fix for CRM-3724 // when is_override false ignore is_admin statuses during membership // status calculation. similarly we did fix for import in CRM-3570. if (empty($params['is_override'])) { $params['exclude_is_admin'] = TRUE; } // process date params to mysql date format. $dateTypes = array('join_date' => 'joinDate', 'start_date' => 'startDate', 'end_date' => 'endDate'); foreach ($dateTypes as $dateField => $dateVariable) { ${$dateVariable} = CRM_Utils_Date::processDate($formValues[$dateField]); } $memTypeNumTerms = empty($termsByType) ? CRM_Utils_Array::value('num_terms', $formValues) : NULL; $calcDates = array(); foreach ($this->_memTypeSelected as $memType) { if (empty($memTypeNumTerms)) { $memTypeNumTerms = CRM_Utils_Array::value($memType, $termsByType, 1); } $calcDates[$memType] = CRM_Member_BAO_MembershipType::getDatesForMembershipType($memType, $joinDate, $startDate, $endDate, $memTypeNumTerms); } foreach ($calcDates as $memType => $calcDate) { foreach (array_keys($dateTypes) as $d) { //first give priority to form values then calDates. $date = CRM_Utils_Array::value($d, $formValues); if (!$date) { $date = CRM_Utils_Array::value($d, $calcDate); } $membershipTypeValues[$memType][$d] = CRM_Utils_Date::processDate($date); //$params[$d] = CRM_Utils_Date::processDate( $date ); } } // max related memberships - take from form or inherit from membership type foreach ($this->_memTypeSelected as $memType) { if (array_key_exists('max_related', $formValues)) { $membershipTypeValues[$memType]['max_related'] = CRM_Utils_Array::value('max_related', $formValues); } } if ($this->_id) { $ids['membership'] = $params['id'] = $this->_id; } $session = CRM_Core_Session::singleton(); $ids['userId'] = $session->get('userID'); // membership type custom data foreach ($this->_memTypeSelected as $memType) { $customFields = CRM_Core_BAO_CustomField::getFields('Membership', FALSE, FALSE, $memType); $customFields = CRM_Utils_Array::crmArrayMerge($customFields, CRM_Core_BAO_CustomField::getFields('Membership', FALSE, FALSE, NULL, NULL, TRUE)); $membershipTypeValues[$memType]['custom'] = CRM_Core_BAO_CustomField::postProcess($formValues, $customFields, $this->_id, 'Membership'); } foreach ($this->_memTypeSelected as $memType) { $membershipTypes[$memType] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $memType); } $membershipType = implode(', ', $membershipTypes); // Retrieve the name and email of the current user - this will be the FROM for the receipt email list($userName, $userEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($ids['userId']); //CRM-13981, allow different person as a soft-contributor of chosen type if ($this->_contributorContactID != $this->_contactID) { $params['contribution_contact_id'] = $this->_contributorContactID; if (!empty($this->_params['soft_credit_type_id'])) { $softParams['soft_credit_type_id'] = $this->_params['soft_credit_type_id']; $softParams['contact_id'] = $this->_contactID; } } if (!empty($formValues['record_contribution'])) { $recordContribution = array('total_amount', 'financial_type_id', 'payment_instrument_id', 'trxn_id', 'contribution_status_id', 'check_number', 'campaign_id', 'receive_date'); foreach ($recordContribution as $f) { $params[$f] = CRM_Utils_Array::value($f, $formValues); } if (!$this->_onlinePendingContributionId) { if (empty($formValues['source'])) { $params['contribution_source'] = ts('%1 Membership: Offline signup (by %2)', array(1 => $membershipType, 2 => $userName)); } else { $params['contribution_source'] = $formValues['source']; } } if (empty($params['is_override']) && CRM_Utils_Array::value('contribution_status_id', $params) == array_search('Pending', CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'))) { $params['status_id'] = array_search('Pending', $allMemberStatus); $params['skipStatusCal'] = TRUE; $params['is_pay_later'] = 1; $this->assign('is_pay_later', 1); } if (!empty($formValues['send_receipt'])) { $params['receipt_date'] = CRM_Utils_Array::value('receive_date', $formValues); } //insert financial type name in receipt. $formValues['contributionType_name'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType', $formValues['financial_type_id']); } // process line items, until no previous line items. if (!empty($lineItem)) { $params['lineItems'] = $lineItem; $params['processPriceSet'] = TRUE; } $createdMemberships = array(); if ($this->_mode) { if (empty($formValues['total_amount']) && !$priceSetId) { // if total amount not provided minimum for membership type is used $params['total_amount'] = $formValues['total_amount'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $formValues['membership_type_id'][1], 'minimum_fee'); } else { $params['total_amount'] = CRM_Utils_Array::value('total_amount', $formValues, 0); } if ($priceSetId && !$isQuickConfig) { $params['financial_type_id'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'financial_type_id'); } else { $params['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $formValues); } $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($formValues['payment_processor_id'], $this->_mode); //get the payment processor id as per mode. $params['payment_processor_id'] = $this->_params['payment_processor_id'] = $formValues['payment_processor_id'] = $this->_paymentProcessor['id']; $now = date('YmdHis'); $fields = array(); // set email for primary location. $fields['email-Primary'] = 1; $formValues['email-5'] = $formValues['email-Primary'] = $this->_memberEmail; $params['register_date'] = $now; // now set the values for the billing location. foreach ($this->_fields as $name => $dontCare) { $fields[$name] = 1; } // also add location name to the array $formValues["address_name-{$this->_bltID}"] = CRM_Utils_Array::value('billing_first_name', $formValues) . ' ' . CRM_Utils_Array::value('billing_middle_name', $formValues) . ' ' . CRM_Utils_Array::value('billing_last_name', $formValues); $formValues["address_name-{$this->_bltID}"] = trim($formValues["address_name-{$this->_bltID}"]); $fields["address_name-{$this->_bltID}"] = 1; //ensure we don't over-write the payer's email with the member's email if ($this->_contributorContactID == $this->_contactID) { $fields["email-{$this->_bltID}"] = 1; } $ctype = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactID, 'contact_type'); $nameFields = array('first_name', 'middle_name', 'last_name'); foreach ($nameFields as $name) { $fields[$name] = 1; if (array_key_exists("billing_{$name}", $formValues)) { $formValues[$name] = $formValues["billing_{$name}"]; $formValues['preserveDBName'] = TRUE; } } if ($this->_contributorContactID == $this->_contactID) { //see CRM-12869 for discussion of why we don't do this for separate payee payments CRM_Contact_BAO_Contact::createProfileContact($formValues, $fields, $this->_contributorContactID, NULL, NULL, $ctype); } // add all the additional payment params we need $this->_params["state_province-{$this->_bltID}"] = $this->_params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($this->_params["billing_state_province_id-{$this->_bltID}"]); $this->_params["country-{$this->_bltID}"] = $this->_params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($this->_params["billing_country_id-{$this->_bltID}"]); $this->_params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($this->_params); $this->_params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($this->_params); $this->_params['ip_address'] = CRM_Utils_System::ipAddress(); $this->_params['amount'] = $params['total_amount']; $this->_params['currencyID'] = $config->defaultCurrency; $this->_params['description'] = ts('Office Credit Card Membership Signup Contribution'); $this->_params['payment_action'] = 'Sale'; $this->_params['invoiceID'] = md5(uniqid(rand(), TRUE)); $this->_params['financial_type_id'] = $params['financial_type_id']; // at this point we've created a contact and stored its address etc // all the payment processors expect the name and address to be in the // so we copy stuff over to first_name etc. $paymentParams = $this->_params; $paymentParams['contactID'] = $this->_contributorContactID; //CRM-10377 if payment is by an alternate contact then we need to set that person // as the contact in the payment params if ($this->_contributorContactID != $this->_contactID) { if (!empty($this->_params['soft_credit_type_id'])) { $softParams['contact_id'] = $params['contact_id']; $softParams['soft_credit_type_id'] = $this->_params['soft_credit_type_id']; } } if (!empty($this->_params['send_receipt'])) { $paymentParams['email'] = $this->_contributorEmail; } CRM_Core_Payment_Form::mapParams($this->_bltID, $this->_params, $paymentParams, TRUE); // CRM-7137 -for recurring membership, // we do need contribution and recuring records. $result = NULL; if (!empty($paymentParams['is_recur'])) { $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'); } $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($this, $paymentParams, $result, $this->_contributorContactID, $contributionType, TRUE, FALSE, $isTest, $lineItems); //create new soft-credit record, CRM-13981 if ($softParams) { $softParams['contribution_id'] = $contribution->id; $softParams['currency'] = $contribution->currency; $softParams['amount'] = $contribution->total_amount; CRM_Contribute_BAO_ContributionSoft::add($softParams); } $paymentParams['contactID'] = $this->_contactID; $paymentParams['contributionID'] = $contribution->id; $paymentParams['contributionTypeID'] = $contribution->financial_type_id; $paymentParams['contributionPageID'] = $contribution->contribution_page_id; $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id; $ids['contribution'] = $contribution->id; $params['contribution_recur_id'] = $paymentParams['contributionRecurID']; } if ($params['total_amount'] > 0.0) { $payment = CRM_Core_Payment::singleton($this->_mode, $this->_paymentProcessor, $this); $result = $payment->doDirectPayment($paymentParams); } if (is_a($result, 'CRM_Core_Error')) { //make sure to cleanup db for recurring case. if (!empty($paymentParams['contributionID'])) { CRM_Contribute_BAO_Contribution::deleteContribution($paymentParams['contributionID']); } if (!empty($paymentParams['contributionRecurID'])) { CRM_Contribute_BAO_ContributionRecur::deleteRecurContribution($paymentParams['contributionRecurID']); } CRM_Core_Error::displaySessionError($result); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/view/membership', "reset=1&action=add&cid={$this->_contactID}&context=&mode={$this->_mode}")); } if ($result) { $this->_params = array_merge($this->_params, $result); //assign amount to template if payment was successful $this->assign('amount', $params['total_amount']); } // if the payment processor returns a contribution_status_id -> use it! if (isset($result['contribution_status_id'])) { $result['payment_status_id'] = $result['contribution_status_id']; } if (isset($result['payment_status_id'])) { // CRM-16737 $result['contribution_status_id'] is deprecated in favour // of payment_status_id as the payment processor only knows whether the payment is complete // not whether payment completes the contribution $params['contribution_status_id'] = $result['payment_status_id']; } else { $params['contribution_status_id'] = !empty($paymentParams['is_recur']) ? 2 : 1; } if ($params['contribution_status_id'] != array_search('Completed', $allContributionStatus)) { $params['status_id'] = array_search('Pending', $allMemberStatus); $params['skipStatusCal'] = TRUE; // unset send-receipt option, since receipt will be sent when ipn is received. unset($this->_params['send_receipt'], $formValues['send_receipt']); //as membership is pending set dates to null. $memberDates = array('join_date' => 'joinDate', 'start_date' => 'startDate', 'end_date' => 'endDate'); foreach ($memberDates as $dp => $dv) { ${$dv} = NULL; foreach ($this->_memTypeSelected as $memType) { $membershipTypeValues[$memType][$dv] = NULL; } } } $params['receive_date'] = $now; $params['invoice_id'] = $this->_params['invoiceID']; $params['contribution_source'] = ts('%1 Membership Signup: Credit card or direct debit (by %2)', array(1 => $membershipType, 2 => $userName)); $params['source'] = $formValues['source'] ? $formValues['source'] : $params['contribution_source']; $params['trxn_id'] = CRM_Utils_Array::value('trxn_id', $result); $params['payment_instrument_id'] = 1; $params['is_test'] = $this->_mode == 'live' ? 0 : 1; if (!empty($this->_params['send_receipt'])) { $params['receipt_date'] = $now; } else { $params['receipt_date'] = NULL; } $this->set('params', $this->_params); $this->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $result)); $this->assign('receive_date', CRM_Utils_Date::mysqlToIso($params['receive_date'])); // required for creating membership for related contacts $params['action'] = $this->_action; //create membership record. $count = 0; foreach ($this->_memTypeSelected as $memType) { if ($count && ($relateContribution = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id))) { $membershipTypeValues[$memType]['relate_contribution_id'] = $relateContribution; } $membershipParams = array_merge($membershipTypeValues[$memType], $params); //CRM-15366 if (!empty($softParams) && empty($paymentParams['is_recur'])) { $membershipParams['soft_credit'] = $softParams; } if (!empty($paymentParams['is_recur']) && CRM_Utils_Array::value('payment_status_id', $result) == 1) { // CRM-16993 we have a situation where line items have already been created. unset($membershipParams['lineItems']); } $membership = CRM_Member_BAO_Membership::create($membershipParams, $ids); $params['contribution'] = CRM_Utils_Array::value('contribution', $membershipParams); unset($params['lineItems']); $this->_membershipIDs[] = $membership->id; $createdMemberships[$memType] = $membership; $count++; } } else { $params['action'] = $this->_action; if ($this->_onlinePendingContributionId && !empty($formValues['record_contribution'])) { // update membership as well as contribution object, CRM-4395 $params['contribution_id'] = $this->_onlinePendingContributionId; $params['componentId'] = $params['id']; $params['componentName'] = 'contribute'; $result = CRM_Contribute_BAO_Contribution::transitionComponents($params, TRUE); if (!empty($result) && !empty($params['contribution_id'])) { $lineItem = array(); $lineItems = CRM_Price_BAO_LineItem::getLineItems($params['contribution_id'], 'contribution', NULL, TRUE, TRUE); $itemId = key($lineItems); $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $lineItems[$itemId]['price_field_id'], 'price_set_id'); $fieldType = NULL; if ($itemId && !empty($lineItems[$itemId]['price_field_id'])) { $fieldType = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $lineItems[$itemId]['price_field_id'], 'html_type'); } $lineItems[$itemId]['unit_price'] = $params['total_amount']; $lineItems[$itemId]['line_total'] = $params['total_amount']; $lineItems[$itemId]['id'] = $itemId; $lineItem[$priceSetId] = $lineItems; $contributionBAO = new CRM_Contribute_BAO_Contribution(); $contributionBAO->id = $params['contribution_id']; $contributionBAO->contact_id = $params['contact_id']; $contributionBAO->find(); CRM_Price_BAO_LineItem::processPriceSet($params['contribution_id'], $lineItem, $contributionBAO, 'civicrm_membership'); //create new soft-credit record, CRM-13981 if ($softParams) { $softParams['contribution_id'] = $params['contribution_id']; while ($contributionBAO->fetch()) { $softParams['currency'] = $contributionBAO->currency; $softParams['amount'] = $contributionBAO->total_amount; } CRM_Contribute_BAO_ContributionSoft::add($softParams); } } //carry updated membership object. $membership = new CRM_Member_DAO_Membership(); $membership->id = $this->_id; $membership->find(TRUE); $cancelled = TRUE; if ($membership->end_date) { //display end date w/ status message. $endDate = $membership->end_date; if (!in_array($membership->status_id, array(array_search('Cancelled', CRM_Member_PseudoConstant::membershipStatus(NULL, " name = 'Cancelled' ", 'name', FALSE, TRUE)), array_search('Expired', CRM_Member_PseudoConstant::membershipStatus())))) { $cancelled = FALSE; } } // suppress form values in template. $this->assign('cancelled', $cancelled); // FIX ME: need to recheck this // here we might updated dates, so get from object. foreach ($calcDates[$membership->membership_type_id] as $date => &$val) { if ($membership->{$date}) { $val = $membership->{$date}; } } $createdMemberships[] = $membership; } else { $count = 0; foreach ($this->_memTypeSelected as $memType) { if ($count && !empty($formValues['record_contribution']) && ($relateContribution = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id))) { $membershipTypeValues[$memType]['relate_contribution_id'] = $relateContribution; } $membershipParams = array_merge($params, $membershipTypeValues[$memType]); if (!empty($formValues['int_amount'])) { $init_amount = array(); foreach ($formValues as $key => $value) { if (strstr($key, 'txt-price')) { $init_amount[$key] = $value; } } $membershipParams['init_amount'] = $init_amount; } if (!empty($softParams)) { $membershipParams['soft_credit'] = $softParams; } $membership = CRM_Member_BAO_Membership::create($membershipParams, $ids); $params['contribution'] = CRM_Utils_Array::value('contribution', $membershipParams); unset($params['lineItems']); $this->_membershipIDs[] = $membership->id; $createdMemberships[$memType] = $membership; $count++; } } } if (!empty($lineItem[$priceSetId])) { $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings'); $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings); $taxAmount = FALSE; $totalTaxAmount = 0; foreach ($lineItem[$priceSetId] as &$priceFieldOp) { if (!empty($priceFieldOp['membership_type_id'])) { $priceFieldOp['start_date'] = $membershipTypeValues[$priceFieldOp['membership_type_id']]['start_date'] ? CRM_Utils_Date::customFormat($membershipTypeValues[$priceFieldOp['membership_type_id']]['start_date'], '%B %E%f, %Y') : '-'; $priceFieldOp['end_date'] = $membershipTypeValues[$priceFieldOp['membership_type_id']]['end_date'] ? CRM_Utils_Date::customFormat($membershipTypeValues[$priceFieldOp['membership_type_id']]['end_date'], '%B %E%f, %Y') : '-'; } else { $priceFieldOp['start_date'] = $priceFieldOp['end_date'] = 'N/A'; } if ($invoicing && isset($priceFieldOp['tax_amount'])) { $taxAmount = TRUE; $totalTaxAmount += $priceFieldOp['tax_amount']; } } if ($invoicing) { $dataArray = array(); foreach ($lineItem[$priceSetId] as $key => $value) { if (isset($value['tax_amount']) && isset($value['tax_rate'])) { if (isset($dataArray[$value['tax_rate']])) { $dataArray[$value['tax_rate']] = $dataArray[$value['tax_rate']] + CRM_Utils_Array::value('tax_amount', $value); } else { $dataArray[$value['tax_rate']] = CRM_Utils_Array::value('tax_amount', $value); } } } if ($taxAmount) { $this->assign('totalTaxAmount', $totalTaxAmount); $this->assign('taxTerm', CRM_Utils_Array::value('tax_term', $invoiceSettings)); } $this->assign('dataArray', $dataArray); } } $this->assign('lineItem', !empty($lineItem) && !$isQuickConfig ? $lineItem : FALSE); $receiptSend = FALSE; $contributionId = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id); $membershipIds = $this->_membershipIDs; if ($contributionId && !empty($membershipIds)) { $contributionDetails = CRM_Contribute_BAO_Contribution::getContributionDetails(CRM_Export_Form_Select::MEMBER_EXPORT, $this->_membershipIDs); if ($contributionDetails[$membership->id]['contribution_status'] == 'Completed') { $receiptSend = TRUE; } } if (!empty($formValues['send_receipt']) && $receiptSend) { $formValues['contact_id'] = $this->_contactID; $formValues['contribution_id'] = $contributionId; // send email receipt $mailSend = self::emailReceipt($this, $formValues, $membership); } if ($this->_action & CRM_Core_Action::UPDATE) { //end date can be modified by hooks, so if end date is set then use it. $endDate = $membership->end_date ? $membership->end_date : $endDate; $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)); } if ($receiptSend) { $statusMsg .= ' ' . ts('A confirmation and receipt has been sent to %1.', array(1 => $this->_contributorEmail)); } } elseif ($this->_action & CRM_Core_Action::ADD) { // 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)); $membership = $createdMemberships[$memType]; $memEndDate = $membership->end_date ? $membership->end_date : $endDate; //get the end date from calculated dates. if (!$memEndDate && empty($params['is_recur'])) { $memEndDate = CRM_Utils_Array::value('end_date', $calcDates[$memType]); } if ($memEndDate && $memEndDate !== 'null') { $memEndDate = CRM_Utils_Date::customFormat($memEndDate); $statusMsg[$memType] .= ' ' . ts('The new membership End Date is %1.', array(1 => $memEndDate)); } } $statusMsg = implode('<br/>', $statusMsg); if ($receiptSend && !empty($mailSend)) { $statusMsg .= ' ' . ts('A membership confirmation and receipt has been sent to %1.', array(1 => $this->_contributorEmail)); } } // finally set membership id if already not set if (!$this->_id) { $this->_id = $membership->id; } CRM_Core_Session::setStatus($statusMsg, ts('Complete'), 'success'); $buttonName = $this->controller->getButtonName(); if ($this->_context == 'standalone') { if ($buttonName == $this->getButtonName('upload', 'new')) { $session->replaceUserContext(CRM_Utils_System::url('civicrm/member/add', 'reset=1&action=add&context=standalone')); } else { $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_contactID}&selectedChild=member")); } } elseif ($buttonName == $this->getButtonName('upload', 'new')) { $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view/membership', "reset=1&action=add&context=membership&cid={$this->_contactID}")); } }
/** * Record contribution record associated with membership. * * @param array $params * Array of submitted params. * @param array $ids * (param in process of being removed - try to use params) array of ids. * * @return CRM_Contribute_BAO_Contribution */ public static function recordMembershipContribution(&$params, $ids = array()) { $membershipId = $params['membership_id']; $contributionParams = array(); $config = CRM_Core_Config::singleton(); $contributionParams['currency'] = $config->defaultCurrency; $contributionParams['receipt_date'] = CRM_Utils_Array::value('receipt_date', $params) ? $params['receipt_date'] : 'null'; $contributionParams['source'] = CRM_Utils_Array::value('contribution_source', $params); $contributionParams['non_deductible_amount'] = 'null'; $contributionParams['payment_processor'] = CRM_Utils_Array::value('payment_processor_id', $params); $contributionSoftParams = CRM_Utils_Array::value('soft_credit', $params); $recordContribution = array('contact_id', 'fee_amount', 'total_amount', 'receive_date', 'financial_type_id', 'payment_instrument_id', 'trxn_id', 'invoice_id', 'is_test', 'contribution_status_id', 'check_number', 'campaign_id', 'is_pay_later', 'membership_id', 'tax_amount', 'skipLineItem', 'contribution_recur_id'); foreach ($recordContribution as $f) { $contributionParams[$f] = CRM_Utils_Array::value($f, $params); } // make entry in batch entity batch table if (!empty($params['batch_id'])) { $contributionParams['batch_id'] = $params['batch_id']; } if (!empty($params['contribution_contact_id'])) { // deal with possibility of a different person paying for contribution $contributionParams['contact_id'] = $params['contribution_contact_id']; } if (!empty($params['processPriceSet']) && !empty($params['lineItems'])) { $contributionParams['line_item'] = CRM_Utils_Array::value('lineItems', $params, NULL); } $contribution = CRM_Contribute_BAO_Contribution::create($contributionParams, $ids); //CRM-13981, create new soft-credit record as to record payment from different person for this membership if (!empty($contributionSoftParams)) { if (!empty($params['batch_id'])) { foreach ($contributionSoftParams as $contributionSoft) { $contributionSoft['contribution_id'] = $contribution->id; $contributionSoft['currency'] = $contribution->currency; CRM_Contribute_BAO_ContributionSoft::add($contributionSoft); } } else { $contributionSoftParams['contribution_id'] = $contribution->id; $contributionSoftParams['currency'] = $contribution->currency; $contributionSoftParams['amount'] = $contribution->total_amount; CRM_Contribute_BAO_ContributionSoft::add($contributionSoftParams); } } // store contribution id $params['contribution_id'] = $contribution->id; //insert payment record for this membership if (empty($ids['contribution']) || !empty($params['is_recur'])) { CRM_Member_BAO_MembershipPayment::create(array('membership_id' => $membershipId, 'contribution_id' => $contribution->id)); } return $contribution; }
/** * Function used to save pcp / soft credit entry * This is used by contribution and also event pcps * * @param array $params associated array * @param object $contribution contribution object * * @static * @access public */ static function processPcpSoft(&$params, &$contribution) { //add soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin. if (!empty($params['soft_credit_to'])) { $contribSoftParams = array(); foreach (array('pcp_display_in_roll', 'pcp_roll_nickname', 'pcp_personal_note', 'amount') as $val) { if (!empty($params[$val])) { $contribSoftParams[$val] = $params[$val]; } } $contribSoftParams['contact_id'] = $params['soft_credit_to']; // add contribution id $contribSoftParams['contribution_id'] = $contribution->id; // add pcp id $contribSoftParams['pcp_id'] = $params['pcp_made_through_id']; $contribSoftParams['soft_credit_type_id'] = CRM_Core_OptionGroup::getValue('soft_credit_type', 'pcp', 'name'); $softContribution = CRM_Contribute_BAO_ContributionSoft::add($contribSoftParams); } }
/** * Takes an associative array and creates a contribution object. * * @param array $params * (reference ) an assoc array of name/value pairs. * @param array $ids * The array that holds all the db ids. * * @return CRM_Contribute_BAO_Contribution */ public static function create(&$params, $ids = array()) { $dateFields = array('receive_date', 'cancel_date', 'receipt_date', 'thankyou_date'); foreach ($dateFields as $df) { if (isset($params[$df])) { $params[$df] = CRM_Utils_Date::isoToMysql($params[$df]); } } $transaction = new CRM_Core_Transaction(); $contribution = self::add($params, $ids); if (is_a($contribution, 'CRM_Core_Error')) { $transaction->rollback(); return $contribution; } $params['contribution_id'] = $contribution->id; if (!empty($params['custom']) && is_array($params['custom'])) { CRM_Core_BAO_CustomValueTable::store($params['custom'], 'civicrm_contribution', $contribution->id); } $session = CRM_Core_Session::singleton(); if (!empty($params['note'])) { $noteParams = array('entity_table' => 'civicrm_contribution', 'note' => $params['note'], 'entity_id' => $contribution->id, 'contact_id' => $session->get('userID'), 'modified_date' => date('Ymd')); if (!$noteParams['contact_id']) { $noteParams['contact_id'] = $params['contact_id']; } CRM_Core_BAO_Note::add($noteParams); } // make entry in batch entity batch table if (!empty($params['batch_id'])) { // in some update cases we need to get extra fields - ie an update that doesn't pass in all these params $titleFields = array('contact_id', 'total_amount', 'currency', 'financial_type_id'); $retrieveRequired = 0; foreach ($titleFields as $titleField) { if (!isset($contribution->{$titleField})) { $retrieveRequired = 1; break; } } if ($retrieveRequired == 1) { $contribution->find(TRUE); } } // Handle soft credit and / or link to personal campaign page $softIDs = CRM_Contribute_BAO_ContributionSoft::getSoftCreditIds($contribution->id); $pcpId = CRM_Contribute_BAO_ContributionSoft::getSoftCreditIds($contribution->id, TRUE); if ($pcp = CRM_Utils_Array::value('pcp', $params)) { $softParams = array(); $softParams['id'] = $pcpId ? $pcpId : NULL; $softParams['contribution_id'] = $contribution->id; $softParams['pcp_id'] = $pcp['pcp_made_through_id']; $softParams['contact_id'] = CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCP', $pcp['pcp_made_through_id'], 'contact_id'); $softParams['currency'] = $contribution->currency; $softParams['amount'] = $contribution->total_amount; $softParams['pcp_display_in_roll'] = CRM_Utils_Array::value('pcp_display_in_roll', $pcp); $softParams['pcp_roll_nickname'] = CRM_Utils_Array::value('pcp_roll_nickname', $pcp); $softParams['pcp_personal_note'] = CRM_Utils_Array::value('pcp_personal_note', $pcp); $softParams['soft_credit_type_id'] = CRM_Core_OptionGroup::getValue('soft_credit_type', 'pcp', 'name'); $contributionSoft = CRM_Contribute_BAO_ContributionSoft::add($softParams); //Send notification to owner for PCP if ($contributionSoft->pcp_id && empty($pcpId)) { CRM_Contribute_Form_Contribution_Confirm::pcpNotifyOwner($contribution, $contributionSoft); } } elseif (array_key_exists('pcp', $params) && $pcpId) { $deleteParams = array('id' => $pcpId); CRM_Contribute_BAO_ContributionSoft::del($deleteParams); } if (isset($params['soft_credit'])) { $softParams = $params['soft_credit']; foreach ($softParams as $softParam) { if (!empty($softIDs)) { $key = key($softIDs); $softParam['id'] = $softIDs[$key]; unset($softIDs[$key]); } $softParam['contribution_id'] = $contribution->id; $softParam['currency'] = $contribution->currency; //case during Contribution Import when we assign soft contribution amount as contribution's total_amount by default if (empty($softParam['amount'])) { $softParam['amount'] = $contribution->total_amount; } CRM_Contribute_BAO_ContributionSoft::add($softParam); } if (!empty($softIDs)) { foreach ($softIDs as $softID) { if (!in_array($softID, $params['soft_credit_ids'])) { $deleteParams = array('id' => $softID); CRM_Contribute_BAO_ContributionSoft::del($deleteParams); } } } } $transaction->commit(); // check if activity record exist for this contribution, if // not add activity $activity = new CRM_Activity_DAO_Activity(); $activity->source_record_id = $contribution->id; $activity->activity_type_id = CRM_Core_OptionGroup::getValue('activity_type', 'Contribution', 'name'); if (!$activity->find(TRUE)) { if (empty($contribution->contact_id)) { $contribution->find(TRUE); } CRM_Activity_BAO_Activity::addActivity($contribution, 'Offline'); } else { // CRM-13237 : if activity record found, update it with campaign id of contribution CRM_Core_DAO::setFieldValue('CRM_Activity_BAO_Activity', $activity->id, 'campaign_id', $contribution->campaign_id); } // do not add to recent items for import, CRM-4399 if (empty($params['skipRecentView'])) { $url = CRM_Utils_System::url('civicrm/contact/view/contribution', "action=view&reset=1&id={$contribution->id}&cid={$contribution->contact_id}&context=home"); // in some update cases we need to get extra fields - ie an update that doesn't pass in all these params $titleFields = array('contact_id', 'total_amount', 'currency', 'financial_type_id'); $retrieveRequired = 0; foreach ($titleFields as $titleField) { if (!isset($contribution->{$titleField})) { $retrieveRequired = 1; break; } } if ($retrieveRequired == 1) { $contribution->find(TRUE); } $contributionTypes = CRM_Contribute_PseudoConstant::financialType(); $title = CRM_Contact_BAO_Contact::displayName($contribution->contact_id) . ' - (' . CRM_Utils_Money::format($contribution->total_amount, $contribution->currency) . ' ' . ' - ' . $contributionTypes[$contribution->financial_type_id] . ')'; $recentOther = array(); if (CRM_Core_Permission::checkActionPermission('CiviContribute', CRM_Core_Action::UPDATE)) { $recentOther['editUrl'] = CRM_Utils_System::url('civicrm/contact/view/contribution', "action=update&reset=1&id={$contribution->id}&cid={$contribution->contact_id}&context=home"); } if (CRM_Core_Permission::checkActionPermission('CiviContribute', CRM_Core_Action::DELETE)) { $recentOther['deleteUrl'] = CRM_Utils_System::url('civicrm/contact/view/contribution', "action=delete&reset=1&id={$contribution->id}&cid={$contribution->contact_id}&context=home"); } // add the recently created Contribution CRM_Utils_Recent::add($title, $url, $contribution->id, 'Contribution', $contribution->contact_id, NULL, $recentOther); } return $contribution; }
/** * Create honor-contact method */ public function testcreateAndGetHonorContact() { $firstName = 'John_' . substr(sha1(rand()), 0, 7); $lastName = 'Smith_' . substr(sha1(rand()), 0, 7); $email = "{$firstName}.{$lastName}@example.com"; //Get profile id of name honoree_individual used to create profileContact $honoreeProfileId = NULL; $ufGroupDAO = new CRM_Core_DAO_UFGroup(); $ufGroupDAO->name = 'honoree_individual'; if ($ufGroupDAO->find(TRUE)) { $honoreeProfileId = $ufGroupDAO->id; } $params = array('prefix_id' => 3, 'first_name' => $firstName, 'last_name' => $lastName, 'email-1' => $email); $softParam = array('soft_credit_type_id' => 1); $honoreeContactId = CRM_Contact_BAO_Contact::createProfileContact($params, CRM_Core_DAO::$_nullArray, NULL, NULL, $honoreeProfileId); $this->assertDBCompareValue('CRM_Contact_DAO_Contact', $honoreeContactId, 'first_name', 'id', $firstName, 'Database check for created honor contact record.'); //create contribution on behalf of honary. $contactId = Contact::createIndividual(); $softParam['contact_id'] = $honoreeContactId; $ids = array('contribution' => NULL); $param = array('contact_id' => $contactId, 'currency' => 'USD', 'financial_type_id' => 4, 'contribution_status_id' => 1, 'receive_date' => date('Ymd'), 'total_amount' => 66); $contribution = CRM_Contribute_BAO_Contribution::create($param, $ids); $id = $contribution->id; $softParam['contribution_id'] = $id; $softParam['currency'] = $contribution->currency; $softParam['amount'] = $contribution->total_amount; //Create Soft Contribution for honoree contact CRM_Contribute_BAO_ContributionSoft::add($softParam); $this->assertDBCompareValue('CRM_Contribute_DAO_ContributionSoft', $id, 'contact_id', 'contribution_id', $honoreeContactId, 'Check DB for honor contact of the contribution'); //get honorary information $getHonorContact = CRM_Contribute_BAO_Contribution::getHonorContacts($honoreeContactId); $this->assertEquals(array($id => array('honor_type' => 'In Honor of', 'honorId' => $id, 'display_name' => 'John Doe', 'type' => 'Event Fee', 'type_id' => '4', 'amount' => '$ 66.00', 'source' => NULL, 'receive_date' => date('Y-m-d 00:00:00'), 'contribution_status' => 'Completed')), $getHonorContact); $this->assertDBCompareValue('CRM_Contact_DAO_Contact', $honoreeContactId, 'first_name', 'id', $firstName, 'Database check for created honor contact record.'); //get annual contribution information $annual = CRM_Contribute_BAO_Contribution::annual($contactId); $config = CRM_Core_Config::singleton(); $currencySymbol = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_Currency', $config->defaultCurrency, 'symbol', 'name'); $this->assertDBCompareValue('CRM_Contribute_DAO_Contribution', $id, 'total_amount', 'id', ltrim($annual[2], $currencySymbol), 'Check DB for total amount of the contribution'); //Delete honor contact Contact::delete($honoreeContactId); //Delete Contribution record $this->contributionDelete($contribution->id); //Delete contributor contact Contact::delete($contactId); }
/** * Submit function. * * This is also accessed by unit tests. * * @param array $formValues * * @return array */ public function submit($formValues) { $isTest = $this->_mode == 'test' ? 1 : 0; $joinDate = $startDate = $endDate = NULL; $membershipTypes = $membership = $calcDate = array(); $membershipType = NULL; $mailSend = FALSE; $formValues = $this->setPriceSetParameters($formValues); $params = $softParams = $ids = array(); $allMemberStatus = CRM_Member_PseudoConstant::membershipStatus(); $allContributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(); if ($this->_id) { $ids['membership'] = $params['id'] = $this->_id; } $ids['userId'] = CRM_Core_Session::singleton()->get('userID'); // Set variables that we normally get from context. // In form mode these are set in preProcess. //TODO: set memberships, fixme $this->setContextVariables($formValues); $this->_memTypeSelected = self::getSelectedMemberships($this->_priceSet, $formValues); if (empty($formValues['financial_type_id'])) { $formValues['financial_type_id'] = $this->_priceSet['financial_type_id']; } $config = CRM_Core_Config::singleton(); $this->convertDateFieldsToMySQL($formValues); $membershipTypeValues = array(); foreach ($this->_memTypeSelected as $memType) { $membershipTypeValues[$memType]['membership_type_id'] = $memType; } //take the required membership recur values. if ($this->_mode && !empty($formValues['auto_renew'])) { $params['is_recur'] = $formValues['is_recur'] = TRUE; $mapping = array('frequency_interval' => 'duration_interval', 'frequency_unit' => 'duration_unit'); $count = 0; foreach ($this->_memTypeSelected as $memType) { $recurMembershipTypeValues = CRM_Utils_Array::value($memType, $this->_recurMembershipTypes, array()); foreach ($mapping as $mapVal => $mapParam) { $membershipTypeValues[$memType][$mapVal] = CRM_Utils_Array::value($mapParam, $recurMembershipTypeValues); if (!$count) { $formValues[$mapVal] = CRM_Utils_Array::value($mapParam, $recurMembershipTypeValues); } } $count++; } } $isQuickConfig = $this->_priceSet['is_quick_config']; $termsByType = array(); $lineItem = array($this->_priceSetId => array()); CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'], $formValues, $lineItem[$this->_priceSetId]); if (CRM_Utils_Array::value('tax_amount', $formValues)) { $params['tax_amount'] = $formValues['tax_amount']; } $params['total_amount'] = CRM_Utils_Array::value('amount', $formValues); $submittedFinancialType = CRM_Utils_Array::value('financial_type_id', $formValues); if (!empty($lineItem[$this->_priceSetId])) { foreach ($lineItem[$this->_priceSetId] as &$li) { if (!empty($li['membership_type_id'])) { if (!empty($li['membership_num_terms'])) { $termsByType[$li['membership_type_id']] = $li['membership_num_terms']; } } ///CRM-11529 for quick config backoffice transactions //when financial_type_id is passed in form, update the //lineitems with the financial type selected in form if ($isQuickConfig && $submittedFinancialType) { $li['financial_type_id'] = $submittedFinancialType; } } } $this->storeContactFields($formValues); $params['contact_id'] = $this->_contactID; $fields = array('status_id', 'source', 'is_override', 'campaign_id'); foreach ($fields as $f) { $params[$f] = CRM_Utils_Array::value($f, $formValues); } // fix for CRM-3724 // when is_override false ignore is_admin statuses during membership // status calculation. similarly we did fix for import in CRM-3570. if (empty($params['is_override'])) { $params['exclude_is_admin'] = TRUE; } // process date params to mysql date format. $dateTypes = array('join_date' => 'joinDate', 'start_date' => 'startDate', 'end_date' => 'endDate'); foreach ($dateTypes as $dateField => $dateVariable) { ${$dateVariable} = CRM_Utils_Date::processDate($formValues[$dateField]); } $memTypeNumTerms = empty($termsByType) ? CRM_Utils_Array::value('num_terms', $formValues) : NULL; $calcDates = array(); foreach ($this->_memTypeSelected as $memType) { if (empty($memTypeNumTerms)) { $memTypeNumTerms = CRM_Utils_Array::value($memType, $termsByType, 1); } $calcDates[$memType] = CRM_Member_BAO_MembershipType::getDatesForMembershipType($memType, $joinDate, $startDate, $endDate, $memTypeNumTerms); } foreach ($calcDates as $memType => $calcDate) { foreach (array_keys($dateTypes) as $d) { //first give priority to form values then calDates. $date = CRM_Utils_Array::value($d, $formValues); if (!$date) { $date = CRM_Utils_Array::value($d, $calcDate); } $membershipTypeValues[$memType][$d] = CRM_Utils_Date::processDate($date); } } // max related memberships - take from form or inherit from membership type foreach ($this->_memTypeSelected as $memType) { if (array_key_exists('max_related', $formValues)) { $membershipTypeValues[$memType]['max_related'] = CRM_Utils_Array::value('max_related', $formValues); } $membershipTypeValues[$memType]['custom'] = CRM_Core_BAO_CustomField::postProcess($formValues, $this->_id, 'Membership'); $membershipTypes[$memType] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $memType); } $membershipType = implode(', ', $membershipTypes); // Retrieve the name and email of the current user - this will be the FROM for the receipt email list($userName) = CRM_Contact_BAO_Contact_Location::getEmailDetails($ids['userId']); //CRM-13981, allow different person as a soft-contributor of chosen type if ($this->_contributorContactID != $this->_contactID) { $params['contribution_contact_id'] = $this->_contributorContactID; if (!empty($formValues['soft_credit_type_id'])) { $softParams['soft_credit_type_id'] = $formValues['soft_credit_type_id']; $softParams['contact_id'] = $this->_contactID; } } if (!empty($formValues['record_contribution'])) { $recordContribution = array('total_amount', 'financial_type_id', 'payment_instrument_id', 'trxn_id', 'contribution_status_id', 'check_number', 'campaign_id', 'receive_date'); foreach ($recordContribution as $f) { $params[$f] = CRM_Utils_Array::value($f, $formValues); } if (!$this->_onlinePendingContributionId) { if (empty($formValues['source'])) { $params['contribution_source'] = ts('%1 Membership: Offline signup (by %2)', array(1 => $membershipType, 2 => $userName)); } else { $params['contribution_source'] = $formValues['source']; } } if (empty($params['is_override']) && CRM_Utils_Array::value('contribution_status_id', $params) == array_search('Pending', CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'))) { $params['status_id'] = array_search('Pending', $allMemberStatus); $params['skipStatusCal'] = TRUE; $params['is_pay_later'] = 1; $this->assign('is_pay_later', 1); } if (!empty($formValues['send_receipt'])) { $params['receipt_date'] = CRM_Utils_Array::value('receive_date', $formValues); } //insert financial type name in receipt. $formValues['contributionType_name'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType', $formValues['financial_type_id']); } // process line items, until no previous line items. if (!empty($lineItem)) { $params['lineItems'] = $lineItem; $params['processPriceSet'] = TRUE; } $createdMemberships = array(); if ($this->_mode) { $params['total_amount'] = CRM_Utils_Array::value('total_amount', $formValues, 0); if (!$isQuickConfig) { $params['financial_type_id'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'financial_type_id'); } else { $params['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $formValues); } $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($formValues['payment_processor_id'], $this->_mode); //get the payment processor id as per mode. $params['payment_processor_id'] = $formValues['payment_processor_id'] = $this->_paymentProcessor['id']; $now = date('YmdHis'); $fields = array(); // set email for primary location. $fields['email-Primary'] = 1; $formValues['email-5'] = $formValues['email-Primary'] = $this->_memberEmail; $params['register_date'] = $now; // now set the values for the billing location. foreach ($this->_fields as $name => $dontCare) { $fields[$name] = 1; } // also add location name to the array $formValues["address_name-{$this->_bltID}"] = CRM_Utils_Array::value('billing_first_name', $formValues) . ' ' . CRM_Utils_Array::value('billing_middle_name', $formValues) . ' ' . CRM_Utils_Array::value('billing_last_name', $formValues); $formValues["address_name-{$this->_bltID}"] = trim($formValues["address_name-{$this->_bltID}"]); $fields["address_name-{$this->_bltID}"] = 1; //ensure we don't over-write the payer's email with the member's email if ($this->_contributorContactID == $this->_contactID) { $fields["email-{$this->_bltID}"] = 1; } $nameFields = array('first_name', 'middle_name', 'last_name'); foreach ($nameFields as $name) { $fields[$name] = 1; if (array_key_exists("billing_{$name}", $formValues)) { $formValues[$name] = $formValues["billing_{$name}"]; $formValues['preserveDBName'] = TRUE; } } if ($this->_contributorContactID == $this->_contactID) { //see CRM-12869 for discussion of why we don't do this for separate payee payments CRM_Contact_BAO_Contact::createProfileContact($formValues, $fields, $this->_contributorContactID, NULL, NULL, CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactID, 'contact_type')); } // add all the additional payment params we need $formValues["state_province-{$this->_bltID}"] = $formValues["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($formValues["billing_state_province_id-{$this->_bltID}"]); $formValues["country-{$this->_bltID}"] = $formValues["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($formValues["billing_country_id-{$this->_bltID}"]); $formValues['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($formValues); $formValues['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($formValues); $formValues['ip_address'] = CRM_Utils_System::ipAddress(); $formValues['amount'] = $params['total_amount']; $formValues['currencyID'] = $config->defaultCurrency; $formValues['description'] = ts("Contribution submitted by a staff person using member's credit card for signup"); $formValues['invoiceID'] = md5(uniqid(rand(), TRUE)); $formValues['financial_type_id'] = $params['financial_type_id']; // 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 = $formValues; $paymentParams['contactID'] = $this->_contributorContactID; //CRM-10377 if payment is by an alternate contact then we need to set that person // as the contact in the payment params if ($this->_contributorContactID != $this->_contactID) { if (!empty($formValues['soft_credit_type_id'])) { $softParams['contact_id'] = $params['contact_id']; $softParams['soft_credit_type_id'] = $formValues['soft_credit_type_id']; } } if (!empty($formValues['send_receipt'])) { $paymentParams['email'] = $this->_contributorEmail; } CRM_Core_Payment_Form::mapParams($this->_bltID, $formValues, $paymentParams, TRUE); // CRM-7137 -for recurring membership, // we do need contribution and recurring records. $result = NULL; if (!empty($paymentParams['is_recur'])) { $financialType = new CRM_Financial_DAO_FinancialType(); $financialType->id = $params['financial_type_id']; $financialType->find(TRUE); $this->_params = $formValues; $contribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($this, $paymentParams, NULL, array('contact_id' => $this->_contributorContactID, 'line_item' => $lineItem, 'is_test' => $isTest, 'campaign_id' => CRM_Utils_Array::value('campaign_id', $paymentParams), 'contribution_page_id' => CRM_Utils_Array::value('contribution_page_id', $formValues), 'source' => CRM_Utils_Array::value('source', $paymentParams, CRM_Utils_Array::value('description', $paymentParams)), 'thankyou_date' => CRM_Utils_Array::value('thankyou_date', $paymentParams), 'payment_instrument_id' => $this->_paymentProcessor['payment_instrument_id']), $financialType, TRUE, FALSE, $this->_bltID); //create new soft-credit record, CRM-13981 if ($softParams) { $softParams['contribution_id'] = $contribution->id; $softParams['currency'] = $contribution->currency; $softParams['amount'] = $contribution->total_amount; CRM_Contribute_BAO_ContributionSoft::add($softParams); } $paymentParams['contactID'] = $this->_contactID; $paymentParams['contributionID'] = $contribution->id; $paymentParams['contributionTypeID'] = $contribution->financial_type_id; $paymentParams['contributionPageID'] = $contribution->contribution_page_id; $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id; $ids['contribution'] = $contribution->id; $params['contribution_recur_id'] = $paymentParams['contributionRecurID']; } if ($params['total_amount'] > 0.0) { $payment = $this->_paymentProcessor['object']; try { $result = $payment->doPayment($paymentParams); $formValues = array_merge($formValues, $result); // Assign amount to template if payment was successful. $this->assign('amount', $params['total_amount']); } catch (PaymentProcessorException $e) { if (!empty($paymentParams['contributionID'])) { CRM_Contribute_BAO_Contribution::failPayment($paymentParams['contributionID'], $this->_contactID, $e->getMessage()); } if (!empty($paymentParams['contributionRecurID'])) { CRM_Contribute_BAO_ContributionRecur::deleteRecurContribution($paymentParams['contributionRecurID']); } CRM_Core_Error::displaySessionError($result); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/view/membership', "reset=1&action=add&cid={$this->_contactID}&context=&mode={$this->_mode}")); } } if ($formValues['payment_status_id'] != array_search('Completed', $allContributionStatus)) { $params['status_id'] = array_search('Pending', $allMemberStatus); $params['skipStatusCal'] = TRUE; // unset send-receipt option, since receipt will be sent when ipn is received. unset($formValues['send_receipt'], $formValues['send_receipt']); //as membership is pending set dates to null. $memberDates = array('join_date' => 'joinDate', 'start_date' => 'startDate', 'end_date' => 'endDate'); foreach ($memberDates as $dv) { ${$dv} = NULL; foreach ($this->_memTypeSelected as $memType) { $membershipTypeValues[$memType][$dv] = NULL; } } } $params['receive_date'] = $now; $params['invoice_id'] = $formValues['invoiceID']; $params['contribution_source'] = ts('%1 Membership Signup: Credit card or direct debit (by %2)', array(1 => $membershipType, 2 => $userName)); $params['source'] = $formValues['source'] ? $formValues['source'] : $params['contribution_source']; $params['trxn_id'] = CRM_Utils_Array::value('trxn_id', $result); $params['payment_instrument_id'] = 1; $params['is_test'] = $this->_mode == 'live' ? 0 : 1; if (!empty($formValues['send_receipt'])) { $params['receipt_date'] = $now; } else { $params['receipt_date'] = NULL; } $this->set('params', $formValues); $this->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $result)); $this->assign('receive_date', CRM_Utils_Date::mysqlToIso($params['receive_date'])); // required for creating membership for related contacts $params['action'] = $this->_action; //create membership record. $count = 0; foreach ($this->_memTypeSelected as $memType) { if ($count && ($relateContribution = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id))) { $membershipTypeValues[$memType]['relate_contribution_id'] = $relateContribution; } $membershipParams = array_merge($membershipTypeValues[$memType], $params); //CRM-15366 if (!empty($softParams) && empty($paymentParams['is_recur'])) { $membershipParams['soft_credit'] = $softParams; } // This is required to trigger the recording of the membership contribution in the // CRM_Member_BAO_Membership::Create function. // @todo stop setting this & 'teach' the create function to respond to something // appropriate as part of our 2-step always create the pending contribution & then finally add the payment // process - // @see http://wiki.civicrm.org/confluence/pages/viewpage.action?pageId=261062657#Payments&AccountsRoadmap-Movetowardsalwaysusinga2-steppaymentprocess $membershipParams['contribution_status_id'] = CRM_Utils_Array::value('payment_status_id', $result); if (!empty($paymentParams['is_recur'])) { // The earlier process created the line items (although we want to get rid of the earlier one in favour // of a single path! unset($membershipParams['lineItems']); } $membership = CRM_Member_BAO_Membership::create($membershipParams, $ids); $params['contribution'] = CRM_Utils_Array::value('contribution', $membershipParams); unset($params['lineItems']); $this->_membershipIDs[] = $membership->id; $createdMemberships[$memType] = $membership; $count++; } } else { $params['action'] = $this->_action; if ($this->_onlinePendingContributionId && !empty($formValues['record_contribution'])) { // update membership as well as contribution object, CRM-4395 $params['contribution_id'] = $this->_onlinePendingContributionId; $params['componentId'] = $params['id']; $params['componentName'] = 'contribute'; $result = CRM_Contribute_BAO_Contribution::transitionComponents($params, TRUE); if (!empty($result) && !empty($params['contribution_id'])) { $lineItem = array(); $lineItems = CRM_Price_BAO_LineItem::getLineItems($params['contribution_id'], 'contribution', NULL, TRUE, TRUE); $itemId = key($lineItems); $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $lineItems[$itemId]['price_field_id'], 'price_set_id'); $lineItems[$itemId]['unit_price'] = $params['total_amount']; $lineItems[$itemId]['line_total'] = $params['total_amount']; $lineItems[$itemId]['id'] = $itemId; $lineItem[$priceSetId] = $lineItems; $contributionBAO = new CRM_Contribute_BAO_Contribution(); $contributionBAO->id = $params['contribution_id']; $contributionBAO->contact_id = $params['contact_id']; $contributionBAO->find(); CRM_Price_BAO_LineItem::processPriceSet($params['contribution_id'], $lineItem, $contributionBAO, 'civicrm_membership'); //create new soft-credit record, CRM-13981 if ($softParams) { $softParams['contribution_id'] = $params['contribution_id']; while ($contributionBAO->fetch()) { $softParams['currency'] = $contributionBAO->currency; $softParams['amount'] = $contributionBAO->total_amount; } CRM_Contribute_BAO_ContributionSoft::add($softParams); } } //carry updated membership object. $membership = new CRM_Member_DAO_Membership(); $membership->id = $this->_id; $membership->find(TRUE); $cancelled = TRUE; if ($membership->end_date) { //display end date w/ status message. $endDate = $membership->end_date; if (!in_array($membership->status_id, array(array_search('Cancelled', CRM_Member_PseudoConstant::membershipStatus(NULL, " name = 'Cancelled' ", 'name', FALSE, TRUE)), array_search('Expired', CRM_Member_PseudoConstant::membershipStatus())))) { $cancelled = FALSE; } } // suppress form values in template. $this->assign('cancelled', $cancelled); $createdMemberships[] = $membership; } else { $count = 0; foreach ($this->_memTypeSelected as $memType) { if ($count && !empty($formValues['record_contribution']) && ($relateContribution = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id))) { $membershipTypeValues[$memType]['relate_contribution_id'] = $relateContribution; } $membershipParams = array_merge($params, $membershipTypeValues[$memType]); if (!empty($formValues['int_amount'])) { $init_amount = array(); foreach ($formValues as $key => $value) { if (strstr($key, 'txt-price')) { $init_amount[$key] = $value; } } $membershipParams['init_amount'] = $init_amount; } if (!empty($softParams)) { $membershipParams['soft_credit'] = $softParams; } $membership = CRM_Member_BAO_Membership::create($membershipParams, $ids); $params['contribution'] = CRM_Utils_Array::value('contribution', $membershipParams); unset($params['lineItems']); $this->_membershipIDs[] = $membership->id; $createdMemberships[$memType] = $membership; $count++; } } } if (!empty($lineItem[$this->_priceSetId])) { $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings'); $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings); $taxAmount = FALSE; $totalTaxAmount = 0; foreach ($lineItem[$this->_priceSetId] as &$priceFieldOp) { if (!empty($priceFieldOp['membership_type_id'])) { $priceFieldOp['start_date'] = $membershipTypeValues[$priceFieldOp['membership_type_id']]['start_date'] ? CRM_Utils_Date::customFormat($membershipTypeValues[$priceFieldOp['membership_type_id']]['start_date'], '%B %E%f, %Y') : '-'; $priceFieldOp['end_date'] = $membershipTypeValues[$priceFieldOp['membership_type_id']]['end_date'] ? CRM_Utils_Date::customFormat($membershipTypeValues[$priceFieldOp['membership_type_id']]['end_date'], '%B %E%f, %Y') : '-'; } else { $priceFieldOp['start_date'] = $priceFieldOp['end_date'] = 'N/A'; } if ($invoicing && isset($priceFieldOp['tax_amount'])) { $taxAmount = TRUE; $totalTaxAmount += $priceFieldOp['tax_amount']; } } if ($invoicing) { $dataArray = array(); foreach ($lineItem[$this->_priceSetId] as $key => $value) { if (isset($value['tax_amount']) && isset($value['tax_rate'])) { if (isset($dataArray[$value['tax_rate']])) { $dataArray[$value['tax_rate']] = $dataArray[$value['tax_rate']] + CRM_Utils_Array::value('tax_amount', $value); } else { $dataArray[$value['tax_rate']] = CRM_Utils_Array::value('tax_amount', $value); } } } if ($taxAmount) { $this->assign('totalTaxAmount', $totalTaxAmount); $this->assign('taxTerm', CRM_Utils_Array::value('tax_term', $invoiceSettings)); } $this->assign('dataArray', $dataArray); } } $this->assign('lineItem', !empty($lineItem) && !$isQuickConfig ? $lineItem : FALSE); $receiptSend = FALSE; $contributionId = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id); $membershipIds = $this->_membershipIDs; if ($contributionId && !empty($membershipIds)) { $contributionDetails = CRM_Contribute_BAO_Contribution::getContributionDetails(CRM_Export_Form_Select::MEMBER_EXPORT, $this->_membershipIDs); if ($contributionDetails[$membership->id]['contribution_status'] == 'Completed') { $receiptSend = TRUE; } } if (!empty($formValues['send_receipt']) && $receiptSend) { $formValues['contact_id'] = $this->_contactID; $formValues['contribution_id'] = $contributionId; // We really don't need a distinct receipt_text_signup vs receipt_text_renewal as they are // handled in the receipt. But by setting one we avoid breaking templates for now // although at some point we should switch in the templates. $formValues['receipt_text_signup'] = $formValues['receipt_text']; // send email receipt $mailSend = self::emailReceipt($this, $formValues, $membership); } // finally set membership id if already not set if (!$this->_id) { $this->_id = $membership->id; } $isRecur = CRM_Utils_Array::value('is_recur', $params); $this->setStatusMessage($membership, $endDate, $receiptSend, $membershipTypes, $createdMemberships, $isRecur, $calcDates, $mailSend); return $createdMemberships; }
/** * Process the soft contribution and/or link to personal campaign page. * * @param array $params * @param object $contribution CRM_Contribute_DAO_Contribution * */ public static function processSoftContribution($params, $contribution) { //retrieve existing soft-credit and pcp id(s) if any against $contribution $softIDs = self::getSoftCreditIds($contribution->id); $pcpId = self::getSoftCreditIds($contribution->id, TRUE); if ($pcp = CRM_Utils_Array::value('pcp', $params)) { $softParams = array(); $softParams['id'] = $pcpId ? $pcpId : NULL; $softParams['contribution_id'] = $contribution->id; $softParams['pcp_id'] = $pcp['pcp_made_through_id']; $softParams['contact_id'] = CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCP', $pcp['pcp_made_through_id'], 'contact_id'); $softParams['currency'] = $contribution->currency; $softParams['amount'] = $contribution->total_amount; $softParams['pcp_display_in_roll'] = CRM_Utils_Array::value('pcp_display_in_roll', $pcp); $softParams['pcp_roll_nickname'] = CRM_Utils_Array::value('pcp_roll_nickname', $pcp); $softParams['pcp_personal_note'] = CRM_Utils_Array::value('pcp_personal_note', $pcp); $softParams['soft_credit_type_id'] = CRM_Core_OptionGroup::getValue('soft_credit_type', 'pcp', 'name'); $contributionSoft = self::add($softParams); //Send notification to owner for PCP if ($contributionSoft->pcp_id && empty($pcpId)) { CRM_Contribute_Form_Contribution_Confirm::pcpNotifyOwner($contribution, $contributionSoft); } } elseif (array_key_exists('pcp', $params) && $pcpId) { $deleteParams = array('id' => $pcpId); CRM_Contribute_BAO_ContributionSoft::del($deleteParams); } if (isset($params['soft_credit'])) { $softParams = $params['soft_credit']; foreach ($softParams as $softParam) { if (!empty($softIDs)) { $key = key($softIDs); $softParam['id'] = $softIDs[$key]; unset($softIDs[$key]); } $softParam['contribution_id'] = $contribution->id; $softParam['currency'] = $contribution->currency; //case during Contribution Import when we assign soft contribution amount as contribution's total_amount by default if (empty($softParam['amount'])) { $softParam['amount'] = $contribution->total_amount; } CRM_Contribute_BAO_ContributionSoft::add($softParam); } // delete any extra soft-credit while updating back-office contribution foreach ((array) $softIDs as $softID) { if (!in_array($softID, $params['soft_credit_ids'])) { $deleteParams = array('id' => $softID); CRM_Contribute_BAO_ContributionSoft::del($deleteParams); } } } }
/** * @param $form * @param array $params Parameters from the form. */ public static function postProcess($form, $params) { if (!empty($form->_honor_block_is_active) && !empty($params['soft_credit_type_id'])) { $honorId = NULL; //check if there is any duplicate contact $profileContactType = CRM_Core_BAO_UFGroup::getContactType($params['honoree_profile_id']); $dedupeParams = CRM_Dedupe_Finder::formatParams($params['honor'], $profileContactType); $dedupeParams['check_permission'] = FALSE; $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, $profileContactType); if (count($ids)) { $honorId = CRM_Utils_Array::value(0, $ids); } $honorId = CRM_Contact_BAO_Contact::createProfileContact($params['honor'], CRM_Core_DAO::$_nullArray, $honorId, NULL, $params['honoree_profile_id']); $softParams = array(); $softParams['contribution_id'] = $form->_contributionID; $softParams['contact_id'] = $honorId; $softParams['soft_credit_type_id'] = $params['soft_credit_type_id']; $contribution = new CRM_Contribute_DAO_Contribution(); $contribution->id = $form->_contributionID; $contribution->find(); while ($contribution->fetch()) { $softParams['currency'] = $contribution->currency; $softParams['amount'] = $contribution->total_amount; } CRM_Contribute_BAO_ContributionSoft::add($softParams); if (CRM_Utils_Array::value('is_email_receipt', $form->_values)) { $form->_values['honor'] = array('soft_credit_type' => CRM_Utils_Array::value($params['soft_credit_type_id'], CRM_Core_OptionGroup::values("soft_credit_type")), 'honor_id' => $honorId, 'honor_profile_id' => $params['honoree_profile_id'], 'honor_profile_values' => $params['honor']); } } }
/** * Function used to save pcp / soft credit entry. * * This is used by contribution and also event pcps * * @param array $params * @param object $contribution * Contribution object. */ public static function processPcpSoft(&$params, &$contribution) { // Add soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin. if (!empty($params['soft_credit_to'])) { $contributionSoftParams = array(); foreach (array('pcp_display_in_roll', 'pcp_roll_nickname', 'pcp_personal_note', 'amount') as $val) { if (!empty($params[$val])) { $contributionSoftParams[$val] = $params[$val]; } } $contributionSoftParams['contact_id'] = $params['soft_credit_to']; // add contribution id $contributionSoftParams['contribution_id'] = $contribution->id; // add pcp id $contributionSoftParams['pcp_id'] = $params['pcp_made_through_id']; $contributionSoftParams['soft_credit_type_id'] = CRM_Core_OptionGroup::getValue('soft_credit_type', 'pcp', 'name'); $contributionSoft = CRM_Contribute_BAO_ContributionSoft::add($contributionSoftParams); //Send notification to owner for PCP if ($contributionSoft->id && $contributionSoft->pcp_id) { CRM_Contribute_Form_Contribution_Confirm::pcpNotifyOwner($contribution, $contributionSoft); } } }