/** * Takes an associative array and creates a price set object. * * @param array $params * (reference) an assoc array of name/value pairs. * * @return CRM_Price_DAO_PriceSet */ public static function create(&$params) { if (empty($params['id']) && empty($params['name'])) { $params['name'] = CRM_Utils_String::munge($params['title'], '_', 242); } $priceSetID = NULL; $validatePriceSet = TRUE; if (!empty($params['extends']) && is_array($params['extends'])) { if (!array_key_exists(CRM_Core_Component::getComponentID('CiviEvent'), $params['extends']) || !array_key_exists(CRM_Core_Component::getComponentID('CiviMember'), $params['extends'])) { $validatePriceSet = FALSE; } $params['extends'] = CRM_Utils_Array::implodePadded($params['extends']); } else { $priceSetID = CRM_Utils_Array::value('id', $params); } // CRM-16189 if ($validatePriceSet && !empty($params['financial_type_id'])) { CRM_Financial_BAO_FinancialAccount::validateFinancialType($params['financial_type_id'], $priceSetID); } $priceSetBAO = new CRM_Price_BAO_PriceSet(); $priceSetBAO->copyValues($params); if (self::eventPriceSetDomainID()) { $priceSetBAO->domain_id = CRM_Core_Config::domainID(); } return $priceSetBAO->save(); }
/** * @param $config */ public static function jqFinancialRelation($config) { if (!isset($_GET['_value']) || empty($_GET['_value'])) { CRM_Utils_System::civiExit(); } if ($_GET['_value'] != 'select') { $financialAccountType = CRM_Financial_BAO_FinancialAccount::getfinancialAccountRelations(TRUE); $financialAccountId = CRM_Utils_Request::retrieve('_value', 'Positive', CRM_Core_DAO::$_nullObject); $financialAccountTypeId = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', $financialAccountId, 'financial_account_type_id'); } $params['orderColumn'] = 'label'; $result = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship', $params); $elements = array(array('name' => ts('- Select Financial Account Relationship -'), 'value' => 'select')); $countResult = count($financialAccountType[$financialAccountTypeId]); if (!empty($result)) { foreach ($result as $id => $name) { if (in_array($id, $financialAccountType[$financialAccountTypeId]) && $_GET['_value'] != 'select') { if ($countResult != 1) { $elements[] = array('name' => $name, 'value' => $id); } else { $elements[] = array('name' => $name, 'value' => $id, 'selected' => 'Selected'); } } elseif ($_GET['_value'] == 'select') { $elements[] = array('name' => $name, 'value' => $id); } } } CRM_Utils_JSON::output($elements); }
/** */ public function __construct() { $this->_autoIncludeIndexedFieldsAsOrderBys = 1; $this->_deferredFinancialAccount = CRM_Financial_BAO_FinancialAccount::getAllDeferredFinancialAccount(); $this->_columns = array('civicrm_financial_account' => array('dao' => 'CRM_Financial_DAO_FinancialAccount', 'alias' => 'financial_account_deferred', 'filters' => array('id' => array('title' => ts('Deferred Financial Account'), 'operatorType' => CRM_Report_Form::OP_MULTISELECT, 'options' => $this->_deferredFinancialAccount, 'type' => CRM_Utils_Type::T_INT)))); parent::__construct(); }
public function setUp() { parent::setUp(); $this->_individualId = $this->individualCreate(); $this->_orgId = $this->organizationCreate(NULL); $this->params = array('title' => "Test Contribution Page" . substr(sha1(rand()), 0, 7), 'financial_type_id' => 1, 'payment_processor' => 1, 'currency' => 'NZD', 'goal_amount' => 350, 'is_pay_later' => 1, 'pay_later_text' => 'I will pay later', 'pay_later_receipt' => "I will pay later", 'is_monetary' => TRUE, 'is_billing_required' => TRUE); $this->_priceSetParams = array('name' => 'tax_contribution' . substr(sha1(rand()), 0, 7), 'title' => 'contributiontax' . substr(sha1(rand()), 0, 7), 'is_active' => 1, 'help_pre' => "Where does your goat sleep", 'help_post' => "thank you for your time", 'extends' => 2, 'financial_type_id' => 3, 'is_quick_config' => 0, 'is_reserved' => 0); // Financial Account with 20% tax rate $financialAccountSetparams = array('name' => 'vat full taxrate account' . substr(sha1(rand()), 0, 7), 'contact_id' => $this->_orgId, 'financial_account_type_id' => 2, 'is_tax' => 1, 'tax_rate' => 20.0, 'is_reserved' => 0, 'is_active' => 1, 'is_default' => 0); $financialAccount = $this->callAPISuccess('financial_account', 'create', $financialAccountSetparams); $this->financialAccountId = $financialAccount['id']; // Financial type having 'Sales Tax Account is' with liability financail account $financialType = array('name' => 'grassvariety1' . substr(sha1(rand()), 0, 7), 'is_reserved' => 0, 'is_active' => 1); $priceField = $this->callAPISuccess('financial_type', 'create', $financialType); $this->financialtypeID = $priceField['id']; $financialRelationParams = array('entity_table' => 'civicrm_financial_type', 'entity_id' => $this->financialtypeID, 'account_relationship' => 10, 'financial_account_id' => $this->financialAccountId); $financialRelation = CRM_Financial_BAO_FinancialTypeAccount::add($financialRelationParams); // Financial type with 5% tax rate $financialAccHalftax = array('name' => 'vat half taxrate account' . substr(sha1(rand()), 0, 7), 'contact_id' => $this->_orgId, 'financial_account_type_id' => 2, 'is_tax' => 1, 'tax_rate' => 5.0, 'is_reserved' => 0, 'is_active' => 1, 'is_default' => 0); $halfFinancialAccount = CRM_Financial_BAO_FinancialAccount::add($financialAccHalftax); $this->halfFinancialAccId = $halfFinancialAccount->id; $halfFinancialtypeHalftax = array('name' => 'grassvariety2' . substr(sha1(rand()), 0, 7), 'is_reserved' => 0, 'is_active' => 1); $halfFinancialType = CRM_Financial_BAO_FinancialType::add($halfFinancialtypeHalftax); $this->halfFinancialTypeId = $halfFinancialType->id; $financialRelationHalftax = array('entity_table' => 'civicrm_financial_type', 'entity_id' => $this->halfFinancialTypeId, 'account_relationship' => 10, 'financial_account_id' => $this->halfFinancialAccId); $halfFinancialRelation = CRM_Financial_BAO_FinancialTypeAccount::add($financialRelationHalftax); // Enable component contribute setting $contributeSetting = array('invoicing' => 1, 'invoice_prefix' => 'INV_', 'credit_notes_prefix' => 'CN_', 'due_date' => 10, 'due_date_period' => 'days', 'notes' => '', 'is_email_pdf' => 1, 'tax_term' => 'Sales Tax', 'tax_display_settings' => 'Inclusive'); $setInvoiceSettings = CRM_Core_BAO_Setting::setItem($contributeSetting, CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings'); // Payment Processor $paymentProceParams = array('domain_id' => 1, 'name' => 'dummy' . substr(sha1(rand()), 0, 7), 'payment_processor_type_id' => 10, 'financial_account_id' => 12, 'is_active' => 1, 'is_default' => 1, 'user_name' => 'dummy', 'url_site' => 'http://dummy.com', 'url_recur' => 'http://dummyrecur.com', 'class_name' => 'Payment_Dummy', 'billing_mode' => 1, 'is_recur' => 1, 'payment_type' => 1); $result = $this->callAPISuccess('payment_processor', 'create', $paymentProceParams); $this->_ids['paymentProcessID'] = $result['id']; require_once 'api/v3/examples/PaymentProcessor/Create.php'; $this->assertAPISuccess($result); }
/** * Get the accounting code from the financial type id. * * @param int $financialTypeID * * * @return string */ public static function getAccountCode($financialTypeID) { static $codes = array(); if (!in_array($financialTypeID, $codes)) { $codes[$financialTypeID] = CRM_Financial_BAO_FinancialAccount::getAccountingCode($financialTypeID); } return $codes[$financialTypeID]; }
/** * Create default entity financial accounts * for financial type * CRM-12470 * * @param $financialType * * @return array */ public static function createDefaultFinancialAccounts($financialType) { $titles = array(); $financialAccountTypeID = CRM_Core_OptionGroup::values('financial_account_type', FALSE, FALSE, FALSE, NULL, 'name'); $accountRelationship = CRM_Core_OptionGroup::values('account_relationship', FALSE, FALSE, FALSE, NULL, 'name'); $relationships = array(array_search('Accounts Receivable Account is', $accountRelationship) => array_search('Asset', $financialAccountTypeID), array_search('Expense Account is', $accountRelationship) => array_search('Expenses', $financialAccountTypeID), array_search('Cost of Sales Account is', $accountRelationship) => array_search('Cost of Sales', $financialAccountTypeID), array_search('Income Account is', $accountRelationship) => array_search('Revenue', $financialAccountTypeID)); $dao = CRM_Core_DAO::executeQuery('SELECT id, financial_account_type_id FROM civicrm_financial_account WHERE name LIKE %1', array(1 => array($financialType->name, 'String'))); $dao->fetch(); $existingFinancialAccount = array(); if (!$dao->N) { $params = array('name' => $financialType->name, 'contact_id' => CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Domain', CRM_Core_Config::domainID(), 'contact_id'), 'financial_account_type_id' => array_search('Revenue', $financialAccountTypeID), 'description' => $financialType->description, 'account_type_code' => 'INC', 'is_active' => 1); $financialAccount = CRM_Financial_BAO_FinancialAccount::add($params, CRM_Core_DAO::$_nullArray); } else { $existingFinancialAccount[$dao->financial_account_type_id] = $dao->id; } $params = array('entity_table' => 'civicrm_financial_type', 'entity_id' => $financialType->id); foreach ($relationships as $key => $value) { if (!array_key_exists($value, $existingFinancialAccount)) { if ($accountRelationship[$key] == 'Accounts Receivable Account is') { $params['financial_account_id'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', 'Accounts Receivable', 'id', 'name'); if (!empty($params['financial_account_id'])) { $titles[] = 'Accounts Receivable'; } else { $query = "SELECT financial_account_id, name FROM civicrm_entity_financial_account\n LEFT JOIN civicrm_financial_account ON civicrm_financial_account.id = civicrm_entity_financial_account.financial_account_id\n WHERE account_relationship = {$key} AND entity_table = 'civicrm_financial_type' LIMIT 1"; $dao = CRM_Core_DAO::executeQuery($query); $dao->fetch(); $params['financial_account_id'] = $dao->financial_account_id; $titles[] = $dao->name; } } elseif ($accountRelationship[$key] == 'Income Account is' && empty($existingFinancialAccount)) { $params['financial_account_id'] = $financialAccount->id; } else { $query = "SELECT id, name FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = {$value}"; $dao = CRM_Core_DAO::executeQuery($query); $dao->fetch(); $params['financial_account_id'] = $dao->id; $titles[] = $dao->name; } } else { $params['financial_account_id'] = $existingFinancialAccount[$value]; $titles[] = $financialType->name; } $params['account_relationship'] = $key; self::add($params); } if (!empty($existingFinancialAccount)) { $titles = array(); } return $titles; }
/** * Validate account relationship with financial account type * * @param obj $financialTypeAccount of CRM_Financial_DAO_EntityFinancialAccount * */ public static function validateRelationship($financialTypeAccount) { $financialAccountLinks = CRM_Financial_BAO_FinancialAccount::getfinancialAccountRelations(); $financialAccountType = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', $financialTypeAccount->financial_account_id, 'financial_account_type_id'); if (CRM_Utils_Array::value($financialTypeAccount->account_relationship, $financialAccountLinks) != $financialAccountType) { $accountRelationships = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship'); $params = array(1 => $accountRelationships[$financialTypeAccount->account_relationship]); throw new Exception(ts("This financial account cannot have '%1' relationship.", $params)); } }
/** * check method getInstrumentFinancialAccount() */ function testGetInstrumentFinancialAccount() { $paymentInstrumentValue = 1; $params = array('name' => 'Donations', 'is_deductible' => 0, 'is_active' => 1); $ids = array(); $financialAccount = CRM_Financial_BAO_FinancialAccount::add($params, $ids); $optionParams = array('name' => 'Credit Card', 'value' => $paymentInstrumentValue); $optionValue = CRM_Core_BAO_OptionValue::retrieve($optionParams, $defaults); $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Asset Account is' ")); $financialParams = array('entity_table' => 'civicrm_option_value', 'entity_id' => $optionValue->id, 'account_relationship' => $relationTypeId, 'financial_account_id' => $financialAccount->id); CRM_Financial_BAO_FinancialTypeAccount::add($financialParams, $ids); $financialAccountId = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($paymentInstrumentValue); $this->assertEquals($financialAccountId, $financialAccount->id, 'Verify Payment Instrument'); }
/** * Get the financial account for the item associated with the new transaction. * * @param array $params * @param CRM_Financial_BAO_FinancialItem $prevFinancialItem * * @return int */ public static function getFinancialAccountForStatusChangeTrxn($params, $prevFinancialItem) { if (!empty($params['financial_account_id'])) { return $params['financial_account_id']; } $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($params['contribution_status_id'], 'name'); $preferredAccountsRelationships = array('Refunded' => 'Credit/Contra Revenue Account is', 'Chargeback' => 'Chargeback Account is'); if (in_array($contributionStatus, array_keys($preferredAccountsRelationships))) { $financialTypeID = !empty($params['financial_type_id']) ? $params['financial_type_id'] : $params['prevContribution']->financial_type_id; return CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship($financialTypeID, $preferredAccountsRelationships[$contributionStatus]); } return $prevFinancialItem->financial_account_id; }
/** * Function to create Financial Account. * * @param string $financialAccountType * * @param string $relationType * * @return array * obj CRM_Financial_DAO_FinancialAccount, obj CRM_Financial_DAO_FinancialType, obj CRM_Financial_DAO_EntityFinancialAccount */ public function createFinancialAccount($financialAccountType, $relationType = NULL) { $params = array('labelColumn' => 'name'); $relationTypes = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship', $params); $financialAccountTypes = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialAccount', 'financial_account_type_id', $params); $params = array('name' => 'TestFinancialAccount_' . rand(), 'contact_id' => 1, 'is_deductible' => 0, 'is_active' => 1, 'is_reserved' => 0, 'financial_account_type_id' => array_search($financialAccountType, $financialAccountTypes)); $financialAccount = CRM_Financial_BAO_FinancialAccount::add($params); $financialType = $financialAccountType = NULL; if ($relationType) { $params['name'] = 'test_financialType1'; $financialType = CRM_Financial_BAO_FinancialType::add($params); $financialParams = array('entity_table' => 'civicrm_financial_type', 'entity_id' => $financialType->id, 'account_relationship' => array_search($relationType, $relationTypes), 'financial_account_id' => $financialAccount->id); $financialAccountType = CRM_Financial_BAO_FinancialTypeAccount::add($financialParams); } return array($financialAccount, $financialType, $financialAccountType); }
/** * Function to process payment after confirmation * * @param object $form form object * @param array $paymentParams array with payment related key * value pairs * @param array $premiumParams array with premium related key * value pairs * @param int $contactID contact id * @param int $contributionTypeId financial type id * @param int $component component id * * @return array associated array * * @static * @access public */ static function processConfirm(&$form, &$paymentParams, &$premiumParams, $contactID, $contributionTypeId, $component = 'contribution', $fieldTypes = NULL) { CRM_Core_Payment_Form::mapParams($form->_bltID, $form->_params, $paymentParams, TRUE); $contributionType = new CRM_Financial_DAO_FinancialType(); if (isset($paymentParams['financial_type'])) { $contributionType->id = $paymentParams['financial_type']; } elseif (!empty($form->_values['pledge_id'])) { $contributionType->id = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_Pledge', $form->_values['pledge_id'], 'financial_type_id'); } else { $contributionType->id = $contributionTypeId; } if (!$contributionType->find(TRUE)) { CRM_Core_Error::fatal('Could not find a system table'); } // add some financial type details to the params list // if folks need to use it $paymentParams['contributionType_name'] = $form->_params['contributionType_name'] = $contributionType->name; //CRM-11456 $paymentParams['contributionType_accounting_code'] = $form->_params['contributionType_accounting_code'] = CRM_Financial_BAO_FinancialAccount::getAccountingCode($contributionType->id); $paymentParams['contributionPageID'] = $form->_params['contributionPageID'] = $form->_values['id']; $payment = NULL; $paymentObjError = ts('The system did not record payment details for this payment and so could not process the transaction. Please report this error to the site administrator.'); if ($form->_values['is_monetary'] && $form->_amount > 0.0 && is_array($form->_paymentProcessor)) { $payment = CRM_Core_Payment::singleton($form->_mode, $form->_paymentProcessor, $form); } //fix for CRM-2062 $now = date('YmdHis'); $result = NULL; if ($form->_contributeMode == 'notify' || $form->_params['is_pay_later']) { // this is not going to come back, i.e. we fill in the other details // when we get a callback from the payment processor // also add the contact ID and contribution ID to the params list $paymentParams['contactID'] = $form->_params['contactID'] = $contactID; $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($form, $paymentParams, NULL, $contactID, $contributionType, TRUE, TRUE, TRUE); if ($contribution) { $form->_params['contributionID'] = $contribution->id; } $form->_params['contributionTypeID'] = $contributionType->id; $form->_params['item_name'] = $form->_params['description']; $form->_params['receive_date'] = $now; if ($contribution && $form->_values['is_recur'] && $contribution->contribution_recur_id) { $form->_params['contributionRecurID'] = $contribution->contribution_recur_id; } $form->set('params', $form->_params); $form->postProcessPremium($premiumParams, $contribution); if ($form->_values['is_monetary'] && $form->_amount > 0.0) { // add qfKey so we can send to paypal $form->_params['qfKey'] = $form->controller->_key; if ($component == 'membership') { $membershipResult = array(1 => $contribution); return $membershipResult; } else { if (!$form->_params['is_pay_later']) { if (is_object($payment)) { // call postprocess hook before leaving $form->postProcessHook(); // this does not return $result =& $payment->doTransferCheckout($form->_params, 'contribute'); } else { CRM_Core_Error::fatal($paymentObjError); } } else { // follow similar flow as IPN // send the receipt mail $form->set('params', $form->_params); if ($contributionType->is_deductible) { $form->assign('is_deductible', TRUE); $form->set('is_deductible', TRUE); } if (isset($paymentParams['contribution_source'])) { $form->_params['source'] = $paymentParams['contribution_source']; } // get the price set values for receipt. if ($form->_priceSetId && $form->_lineItem) { $form->_values['lineItem'] = $form->_lineItem; $form->_values['priceSetID'] = $form->_priceSetId; } $form->_values['contribution_id'] = $contribution->id; $form->_values['contribution_page_id'] = $contribution->contribution_page_id; CRM_Contribute_BAO_ContributionPage::sendMail($contactID, $form->_values, $contribution->is_test); return; } } } } elseif ($form->_contributeMode == 'express') { if ($form->_values['is_monetary'] && $form->_amount > 0.0) { // determine if express + recurring and direct accordingly if ($paymentParams['is_recur'] == 1) { if (is_object($payment)) { $result = $payment->createRecurringPayments($paymentParams); } else { CRM_Core_Error::fatal($paymentObjError); } } else { if (is_object($payment)) { $result = $payment->doExpressCheckout($paymentParams); } else { CRM_Core_Error::fatal($paymentObjError); } } } } elseif ($form->_values['is_monetary'] && $form->_amount > 0.0) { if (!empty($paymentParams['is_recur']) && $form->_contributeMode == 'direct') { // For recurring contribution, create Contribution Record first. // Contribution ID, Recurring ID and Contact ID needed // When we get a callback from the payment processor $paymentParams['contactID'] = $contactID; $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($form, $paymentParams, NULL, $contactID, $contributionType, TRUE, TRUE, TRUE); $paymentParams['contributionID'] = $contribution->id; $paymentParams['contributionTypeID'] = $contribution->financial_type_id; $paymentParams['contributionPageID'] = $contribution->contribution_page_id; if ($form->_values['is_recur'] && $contribution->contribution_recur_id) { $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id; } } if (is_object($payment)) { $result = $payment->doDirectPayment($paymentParams); } else { CRM_Core_Error::fatal($paymentObjError); } } if ($component == 'membership') { $membershipResult = array(); } 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']); } if ($component !== 'membership') { CRM_Core_Error::displaySessionError($result); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/transact', "_qf_Main_display=true&qfKey={$form->_params['qfKey']}")); } $membershipResult[1] = $result; } elseif ($result || $form->_amount == 0.0 && !$form->_params['is_pay_later']) { if ($result) { $form->_params = array_merge($form->_params, $result); } $form->_params['receive_date'] = $now; $form->set('params', $form->_params); $form->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $result)); $form->assign('receive_date', CRM_Utils_Date::mysqlToIso($form->_params['receive_date'])); // result has all the stuff we need // lets archive it to a financial transaction if ($contributionType->is_deductible) { $form->assign('is_deductible', TRUE); $form->set('is_deductible', TRUE); } if (isset($paymentParams['contribution_source'])) { $form->_params['source'] = $paymentParams['contribution_source']; } // check if pending was set to true by payment processor $pending = FALSE; if (!empty($form->_params['contribution_status_pending'])) { $pending = TRUE; } if (!(!empty($paymentParams['is_recur']) && $form->_contributeMode == 'direct')) { $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($form, $form->_params, $result, $contactID, $contributionType, TRUE, $pending, TRUE); } $form->postProcessPremium($premiumParams, $contribution); $membershipResult[1] = $contribution; } if ($component == 'membership') { return $membershipResult; } //Do not send an email if Recurring contribution is done via Direct Mode //We will send email once the IPN is received. if (!empty($paymentParams['is_recur']) && $form->_contributeMode == 'direct') { return TRUE; } // get the price set values for receipt. if ($form->_priceSetId && $form->_lineItem) { $form->_values['lineItem'] = $form->_lineItem; $form->_values['priceSetID'] = $form->_priceSetId; } // finally send an email receipt if ($contribution) { $form->_values['contribution_id'] = $contribution->id; CRM_Contribute_BAO_ContributionPage::sendMail($contactID, $form->_values, $contribution->is_test, FALSE, $fieldTypes); } }
/** * Add the financial types. * * @param array $params * Reference array contains the values submitted by the form. * * @return CRM_Financial_DAO_FinancialAccount */ public static function add(&$params) { if (empty($params['id'])) { $params['is_active'] = CRM_Utils_Array::value('is_active', $params, FALSE); $params['is_deductible'] = CRM_Utils_Array::value('is_deductible', $params, FALSE); $params['is_tax'] = CRM_Utils_Array::value('is_tax', $params, FALSE); $params['is_header_account'] = CRM_Utils_Array::value('is_header_account', $params, FALSE); $params['is_default'] = CRM_Utils_Array::value('is_default', $params, FALSE); } if (!empty($params['id']) && !empty($params['financial_account_type_id']) && CRM_Financial_BAO_FinancialAccount::validateFinancialAccount($params['id'], $params['financial_account_type_id'])) { throw new CRM_Core_Exception(ts('You cannot change the account type since this financial account refers to a financial item having an account type of Revenue/Liability.')); } if (!empty($params['is_default'])) { $query = 'UPDATE civicrm_financial_account SET is_default = 0 WHERE financial_account_type_id = %1'; $queryParams = array(1 => array($params['financial_account_type_id'], 'Integer')); CRM_Core_DAO::executeQuery($query, $queryParams); } // action is taken depending upon the mode $financialAccount = new CRM_Financial_DAO_FinancialAccount(); if (!empty($params['id'])) { $financialAccount->id = $params['id']; $financialAccount->find(TRUE); } $financialAccount->copyValues($params); //CRM-16189 $accountType = CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name IN ('Liability', 'Asset') "); if (empty($params['id']) && !CRM_Utils_Array::value($financialAccount->financial_account_type_id, $accountType)) { $financialAccount->opening_balance = $financialAccount->current_period_opening_balance = '0.00'; } $financialAccount->save(); return $financialAccount; }
/** * Process payment after confirmation. * * @param CRM_Core_Form $form * Form object. * @param array $paymentParams * Array with payment related key. * value pairs * @param int $contactID * Contact id. * @param int $contributionTypeId * Financial type id. * @param int|string $component component id * @param bool $isTest * @param bool $isRecur * * @throws CRM_Core_Exception * @throws Exception * @return array * associated array * */ public static function processConfirm(&$form, &$paymentParams, $contactID, $contributionTypeId, $component = 'contribution', $isTest, $isRecur) { CRM_Core_Payment_Form::mapParams($form->_bltID, $form->_params, $paymentParams, TRUE); $lineItems = $form->_lineItem; $isPaymentTransaction = self::isPaymentTransaction($form); $financialType = new CRM_Financial_DAO_FinancialType(); $financialType->id = $contributionTypeId; $financialType->find(TRUE); if ($financialType->is_deductible) { $form->assign('is_deductible', TRUE); $form->set('is_deductible', TRUE); } // add some financial type details to the params list // if folks need to use it //CRM-15297 - contributionType is obsolete - pass financial type as well so people can deprecate it $paymentParams['financialType_name'] = $paymentParams['contributionType_name'] = $form->_params['contributionType_name'] = $financialType->name; //CRM-11456 $paymentParams['financialType_accounting_code'] = $paymentParams['contributionType_accounting_code'] = $form->_params['contributionType_accounting_code'] = CRM_Financial_BAO_FinancialAccount::getAccountingCode($contributionTypeId); $paymentParams['contributionPageID'] = $form->_params['contributionPageID'] = $form->_values['id']; $paymentParams['contactID'] = $form->_params['contactID'] = $contactID; //fix for CRM-16317 $form->_params['receive_date'] = date('YmdHis'); $form->assign('receive_date', CRM_Utils_Date::mysqlToIso($form->_params['receive_date'])); if ($isPaymentTransaction) { $contributionParams = array('id' => CRM_Utils_Array::value('contribution_id', $paymentParams), 'contact_id' => $contactID, 'line_item' => $lineItems, 'is_test' => $isTest, 'campaign_id' => CRM_Utils_Array::value('campaign_id', $paymentParams, CRM_Utils_Array::value('campaign_id', $form->_values)), 'contribution_page_id' => $form->_id, 'source' => CRM_Utils_Array::value('source', $paymentParams, CRM_Utils_Array::value('description', $paymentParams))); $isMonetary = !empty($form->_values['is_monetary']); if ($isMonetary) { if (empty($paymentParams['is_pay_later'])) { // @todo look up payment_instrument_id on payment processor table. $contributionParams['payment_instrument_id'] = 1; } } $contribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($form, $paymentParams, NULL, $contributionParams, $financialType, TRUE, $form->_bltID, $isRecur); $paymentParams['contributionTypeID'] = $contributionTypeId; $paymentParams['item_name'] = $form->_params['description']; $paymentParams['qfKey'] = $form->controller->_key; if ($component == 'membership') { return array('contribution' => $contribution); } $paymentParams['contributionID'] = $contribution->id; //CRM-15297 deprecate contributionTypeID $paymentParams['financialTypeID'] = $paymentParams['contributionTypeID'] = $contribution->financial_type_id; $paymentParams['contributionPageID'] = $contribution->contribution_page_id; if (isset($paymentParams['contribution_source'])) { $paymentParams['source'] = $paymentParams['contribution_source']; } if ($form->_values['is_recur'] && $contribution->contribution_recur_id) { $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id; } if (isset($paymentParams['contribution_source'])) { $form->_params['source'] = $paymentParams['contribution_source']; } // get the price set values for receipt. if ($form->_priceSetId && $form->_lineItem) { $form->_values['lineItem'] = $form->_lineItem; $form->_values['priceSetID'] = $form->_priceSetId; } $form->_values['contribution_id'] = $contribution->id; $form->_values['contribution_page_id'] = $contribution->contribution_page_id; if (!empty($form->_paymentProcessor)) { try { $payment = Civi\Payment\System::singleton()->getByProcessor($form->_paymentProcessor); if ($form->_contributeMode == 'notify') { // We want to get rid of this & make it generic - eg. by making payment processing the last thing // and always calling it first. $form->postProcessHook(); } $result = $payment->doPayment($paymentParams); $form->_params = array_merge($form->_params, $result); $form->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $result)); if (!empty($result['trxn_id'])) { $contribution->trxn_id = $result['trxn_id']; } if (!empty($result['payment_status_id'])) { $contribution->payment_status_id = $result['payment_status_id']; } $result['contribution'] = $contribution; if ($result['payment_status_id'] == CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'status_id', 'Pending') && $payment->isSendReceiptForPending()) { CRM_Contribute_BAO_ContributionPage::sendMail($contactID, $form->_values, $contribution->is_test); } return $result; } catch (\Civi\Payment\Exception\PaymentProcessorException $e) { // Clean up DB as appropriate. if (!empty($paymentParams['contributionID'])) { CRM_Contribute_BAO_Contribution::failPayment($paymentParams['contributionID'], $paymentParams['contactID'], $e->getMessage()); } if (!empty($paymentParams['contributionRecurID'])) { CRM_Contribute_BAO_ContributionRecur::deleteRecurContribution($paymentParams['contributionRecurID']); } $result['is_payment_failure'] = TRUE; $result['error'] = $e; return $result; } } } // Only pay later or unpaid should reach this point, although pay later likely does not & is handled via the // manual processor, so it's unclear what this set is for and whether the following send ever fires. $form->set('params', $form->_params); if ($form->_params['amount'] == 0) { // This is kind of a back-up for pay-later $0 transactions. // In other flows they pick up the manual processor & get dealt with above (I // think that might be better...). return array('payment_status_id' => 1, 'contribution' => $contribution, 'payment_processor_id' => 0); } elseif (empty($form->_values['amount'])) { // If the amount is not in _values[], set it $form->_values['amount'] = $form->_params['amount']; } CRM_Contribute_BAO_ContributionPage::sendMail($contactID, $form->_values, $contribution->is_test); }
/** * Build the form object. */ public function buildQuickForm() { parent::buildQuickForm(); $this->setPageTitle(ts('Financial Type Account')); if ($this->_action & CRM_Core_Action::DELETE) { return; } if (isset($this->_id)) { $params = array('id' => $this->_id); CRM_Financial_BAO_FinancialTypeAccount::retrieve($params, $defaults); $this->setDefaults($defaults); $financialAccountTitle = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', $defaults['financial_account_id'], 'name'); } $this->applyFilter('__ALL__', 'trim'); if ($this->_action == CRM_Core_Action::UPDATE) { $this->assign('aid', $this->_id); // hidden field to catch the group id in profile $this->add('hidden', 'financial_type_id', $this->_aid); // hidden field to catch the field id in profile $this->add('hidden', 'account_type_id', $this->_id); } $params['orderColumn'] = 'label'; $AccountTypeRelationship = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship', $params); if (!empty($AccountTypeRelationship)) { $element = $this->add('select', 'account_relationship', ts('Financial Account Relationship'), array('select' => ts('- Select Financial Account Relationship -')) + $AccountTypeRelationship, TRUE); } if ($this->_isARFlag) { $element->freeze(); } if ($this->_action == CRM_Core_Action::ADD) { if (!empty($this->_submitValues['account_relationship']) || !empty($this->_submitValues['financial_account_id'])) { $financialAccountType = CRM_Financial_BAO_FinancialAccount::getfinancialAccountRelations(); $financialAccountType = CRM_Utils_Array::value($this->_submitValues['account_relationship'], $financialAccountType); $result = CRM_Contribute_PseudoConstant::financialAccount(NULL, $financialAccountType); $financialAccountSelect = array('' => ts('- select -')) + $result; } else { $financialAccountSelect = array('select' => ts('- select -')) + CRM_Contribute_PseudoConstant::financialAccount(); } } if ($this->_action == CRM_Core_Action::UPDATE) { $financialAccountType = CRM_Financial_BAO_FinancialAccount::getfinancialAccountRelations(); $financialAccountType = $financialAccountType[$this->_defaultValues['account_relationship']]; $result = CRM_Contribute_PseudoConstant::financialAccount(NULL, $financialAccountType); $financialAccountSelect = array('' => ts('- select -')) + $result; } $this->add('select', 'financial_account_id', ts('Financial Account'), $financialAccountSelect, TRUE); $this->addButtons(array(array('type' => 'next', 'name' => ts('Save'), 'isDefault' => TRUE), array('type' => 'next', 'name' => ts('Save and New'), 'subName' => 'new'), array('type' => 'cancel', 'name' => ts('Cancel')))); $this->addFormRule(array('CRM_Financial_Form_FinancialTypeAccount', 'formRule'), $this); }
/** * Process the form submission. */ public function postProcess() { if ($this->_action & CRM_Core_Action::DELETE) { CRM_Financial_BAO_FinancialAccount::del($this->_id); CRM_Core_Session::setStatus(ts('Selected Financial Account has been deleted.')); } else { // store the submitted values in an array $params = $this->exportValues(); if ($this->_action & CRM_Core_Action::UPDATE) { $params['id'] = $this->_id; } $financialAccount = CRM_Financial_BAO_FinancialAccount::add($params); CRM_Core_Session::setStatus(ts('The Financial Account \'%1\' has been saved.', array(1 => $financialAccount->name)), ts('Saved'), 'success'); } }
/** * Test getting financial account for a given financial Type with a particular relationship. */ public function testGetFinancialAccountByFinancialTypeAndRelationshipCustomAddedRefunded() { $financialAccount = $this->callAPISuccess('FinancialAccount', 'create', array('name' => 'Refund Account', 'is_active' => TRUE)); $this->callAPISuccess('EntityFinancialAccount', 'create', array('entity_id' => 2, 'entity_table' => 'civicrm_financial_type', 'account_relationship' => 'Credit/Contra Revenue Account is', 'financial_account_id' => 'Refund Account')); $this->assertEquals($financialAccount['id'], CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship(2, 'Credit/Contra Revenue Account is')); }
/** * check method del() */ function testCreateEntityTrxn() { $fParams = array('name' => 'Donations' . substr(sha1(rand()), 0, 7), 'is_deductible' => 0, 'is_active' => 1); $amount = 200; $ids = array(); $financialAccount = CRM_Financial_BAO_FinancialAccount::add($fParams, $ids); $financialTrxn = new CRM_Financial_DAO_FinancialTrxn(); $financialTrxn->to_financial_account_id = $financialAccount->id; $financialTrxn->total_amount = $amount; $financialTrxn->save(); $params = array('entity_table' => 'civicrm_contribution', 'entity_id' => 1, 'financial_trxn_id' => $financialTrxn->id, 'amount' => $amount); $entityTrxn = CRM_Financial_BAO_FinancialItem::createEntityTrxn($params); $entityResult = $this->assertDBNotNull('CRM_Financial_DAO_EntityFinancialTrxn', $financialTrxn->id, 'amount', 'financial_trxn_id', 'Database check on added entity financial trxn record.'); $this->assertEquals($entityResult, $amount, 'Verify Amount for Financial Item'); return $entityTrxn; }
/** * Global validation rules for the form. * * @param array $values * posted values of the form * @param $files * @param $self * * @return array * list of errors to be posted back to the form */ public static function formRule($values, $files, $self) { $errors = array(); if (CRM_Utils_Array::value('deferred_revenue_enabled', $values)) { $errorMessage = CRM_Financial_BAO_FinancialAccount::validateTogglingDeferredRevenue(); if ($errorMessage) { // Since the error msg is too long and // takes the whole space to display inline // therefore setting blank text to highlight the field // setting actual error msg to _qf_default to show in pop-up screen $errors['deferred_revenue_enabled'] = ' '; $errors['_qf_default'] = $errorMessage; } } return $errors; }
/** * Browse all Financial Type Account data * * @return void * @access public * @static */ function browse() { // get all Financial Type Account data sorted by weight $financialType = array(); $params = array(); $dao = new CRM_Financial_DAO_EntityFinancialAccount(); $params['entity_id'] = $this->_aid; $params['entity_table'] = 'civicrm_financial_type'; if ($this->_aid) { $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $this->_title = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType', $this->_aid, 'name'); CRM_Utils_System::setTitle($this->_title . ' - ' . ts('Assigned Financial Accounts')); $financialAccountType = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialAccount', 'financial_account_type_id'); $accountRelationship = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship'); $dao->copyValues($params); $dao->find(); while ($dao->fetch()) { $financialType[$dao->id] = array(); CRM_Core_DAO::storeValues($dao, $financialType[$dao->id]); $params = array('id' => $dao->financial_account_id); $defaults = array(); $financialAccount = CRM_Financial_BAO_FinancialAccount::retrieve($params, $defaults); if (!empty($financialAccount)) { $financialType[$dao->id]['financial_account'] = $financialAccount->name; $financialType[$dao->id]['accounting_code'] = $financialAccount->accounting_code; $financialType[$dao->id]['account_type_code'] = $financialAccount->account_type_code; $financialType[$dao->id]['is_active'] = $financialAccount->is_active; if (!empty($financialAccount->contact_id)) { $financialType[$dao->id]['owned_by'] = CRM_Contact_BAO_Contact::displayName($financialAccount->contact_id); } if (!empty($financialAccount->financial_account_type_id)) { $optionGroupName = 'financial_account_type'; $financialType[$dao->id]['financial_account_type'] = CRM_Utils_Array::value($financialAccount->financial_account_type_id, $financialAccountType); } if (!empty($dao->account_relationship)) { $optionGroupName = 'account_relationship'; $financialType[$dao->id]['account_relationship'] = CRM_Utils_Array::value($dao->account_relationship, $accountRelationship); } } // form all action links $action = array_sum(array_keys($this->links())); $links = self::links(); //CRM-12492 if ($dao->account_relationship == $relationTypeId) { unset($links[CRM_Core_Action::DELETE]); } $financialType[$dao->id]['action'] = CRM_Core_Action::formLink($links, $action, array('id' => $dao->id, 'aid' => $dao->entity_id), ts('more'), FALSE, 'financialTypeAccount.manage.action', 'FinancialTypeAccount', $dao->id); } $this->assign('rows', $financialType); $this->assign('aid', $this->_aid); $this->assign('financialTypeTitle', $this->_title); } else { CRM_Core_Error::fatal(); return null; } }
/** * Global form rule. * * @param array $fields * The input form values. * @param array $files * The uploaded files if any. * @param $self * * @return bool|array * true if no errors, else array of errors */ public static function formRule($fields, $files, $self) { $errors = array(); // Check for Credit Card Contribution. if ($self->_mode) { if (empty($fields['payment_processor_id'])) { $errors['payment_processor_id'] = ts('Payment Processor is a required field.'); } else { // validate payment instrument (e.g. credit card number) CRM_Core_Payment_Form::validatePaymentInstrument($fields['payment_processor_id'], $fields, $errors, NULL); } } // Do the amount validations. if (empty($fields['total_amount']) && empty($self->_lineItems)) { if ($priceSetId = CRM_Utils_Array::value('price_set_id', $fields)) { CRM_Price_BAO_PriceField::priceSetValidation($priceSetId, $fields, $errors); } } $softErrors = CRM_Contribute_Form_SoftCredit::formRule($fields, $errors, $self); if (!empty($fields['total_amount']) && (!empty($fields['net_amount']) || !empty($fields['fee_amount']))) { $sum = CRM_Utils_Rule::cleanMoney($fields['net_amount']) + CRM_Utils_Rule::cleanMoney($fields['fee_amount']); // For taxable contribution we need to deduct taxable amount from // (net amount + fee amount) before comparing it with total amount if (!empty($self->_values['tax_amount'])) { $componentDetails = CRM_Contribute_BAO_Contribution::getComponentDetails($self->_id); if (!(CRM_Utils_Array::value('membership', $componentDetails) || CRM_Utils_Array::value('participant', $componentDetails))) { $sum = CRM_Utils_Money::format($sum - $self->_values['tax_amount'], NULL, '%a'); } } if (CRM_Utils_Rule::cleanMoney($fields['total_amount']) != $sum) { $errors['total_amount'] = ts('The sum of fee amount and net amount must be equal to total amount'); } } //CRM-16285 - Function to handle validation errors on form, for recurring contribution field. CRM_Contribute_BAO_ContributionRecur::validateRecurContribution($fields, $files, $self, $errors); // Form rule for status http://wiki.civicrm.org/confluence/display/CRM/CiviAccounts+4.3+Data+Flow if ($self->_action & CRM_Core_Action::UPDATE && $self->_id && $self->_values['contribution_status_id'] != $fields['contribution_status_id']) { CRM_Contribute_BAO_Contribution::checkStatusValidation($self->_values, $fields, $errors); } // CRM-16015, add form-rule to restrict change of financial type if using price field of different financial type if ($self->_action & CRM_Core_Action::UPDATE && $self->_id && $self->_values['financial_type_id'] != $fields['financial_type_id']) { CRM_Contribute_BAO_Contribution::checkFinancialTypeChange(NULL, $self->_id, $errors); } //FIXME FOR NEW DATA FLOW http://wiki.civicrm.org/confluence/display/CRM/CiviAccounts+4.3+Data+Flow if (!empty($fields['fee_amount']) && !empty($fields['financial_type_id']) && ($financialType = CRM_Contribute_BAO_Contribution::validateFinancialType($fields['financial_type_id']))) { $errors['financial_type_id'] = ts("Financial Account of account relationship of 'Expense Account is' is not configured for Financial Type : ") . $financialType; } // $trxn_id must be unique CRM-13919 if (!empty($fields['trxn_id'])) { $queryParams = array(1 => array($fields['trxn_id'], 'String')); $query = 'select count(*) from civicrm_contribution where trxn_id = %1'; if ($self->_id) { $queryParams[2] = array((int) $self->_id, 'Integer'); $query .= ' and id !=%2'; } $tCnt = CRM_Core_DAO::singleValueQuery($query, $queryParams); if ($tCnt) { $errors['trxn_id'] = ts('Transaction ID\'s must be unique. Transaction \'%1\' already exists in your database.', array(1 => $fields['trxn_id'])); } } if (!empty($fields['revenue_recognition_date']) && count(array_filter($fields['revenue_recognition_date'])) == 1) { $errors['revenue_recognition_date'] = ts('Month and Year are required field for Revenue Recognition.'); } // CRM-16189 try { CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($fields, $self->_id, $self->_priceSet['fields']); } catch (CRM_Core_Exception $e) { $errors['financial_type_id'] = ' '; $errors['_qf_default'] = $e->getMessage(); } $errors = array_merge($errors, $softErrors); return $errors; }
/** * Global validation rules for the form. * * @param array $values * Posted values of the form. * * @return array * list of errors to be posted back to the form */ public static function formRule($values) { $errors = array(); if (!empty($values['is_discount'])) { $occurDiscount = array_count_values($values['discount_name']); $countemptyrows = 0; $countemptyvalue = 0; for ($i = 1; $i <= self::NUM_DISCOUNT; $i++) { $start_date = $end_date = NULL; if (!empty($values['discount_name'][$i])) { if (!empty($values['discount_start_date'][$i])) { $start_date = $values['discount_start_date'][$i] ? CRM_Utils_Date::processDate($values['discount_start_date'][$i]) : 0; } if (!empty($values['discount_end_date'][$i])) { $end_date = $values['discount_end_date'][$i] ? CRM_Utils_Date::processDate($values['discount_end_date'][$i]) : 0; } if ($start_date && $end_date && strcmp($end_date, $start_date) < 0) { $errors["discount_end_date[{$i}]"] = ts('The discount end date cannot be prior to the start date.'); } if (!$start_date && !$end_date) { $errors["discount_start_date[{$i}]"] = $errors["discount_end_date[{$i}]"] = ts('Please specify either start date or end date.'); } if ($i > 1) { $end_date_1 = $values['discount_end_date'][$i - 1] ? CRM_Utils_Date::processDate($values['discount_end_date'][$i - 1]) : 0; if ($start_date && $end_date_1 && strcmp($end_date_1, $start_date) >= 0) { $errors["discount_start_date[{$i}]"] = ts('Select non-overlapping discount start date.'); } elseif (!$start_date && !$end_date_1) { $j = $i - 1; $errors["discount_start_date[{$i}]"] = $errors["discount_end_date[{$j}]"] = ts('Select either of the dates.'); } } foreach ($occurDiscount as $key => $value) { if ($value > 1 && $key != '') { if ($key == $values['discount_name'][$i]) { $errors['discount_name[' . $i . ']'] = ts('%1 is already used for Discount Name.', array(1 => $key)); } } } //validation for discount labels and values for ($index = self::NUM_OPTION; $index > 0; $index--) { $label = TRUE; if (empty($values['discounted_label'][$index]) && !empty($values['discounted_value'][$index][$i])) { $label = FALSE; if (!$label) { $errors["discounted_label[{$index}]"] = ts('Label cannot be empty.'); } } if (!empty($values['discounted_label'][$index])) { $duplicateIndex = CRM_Utils_Array::key($values['discounted_label'][$index], $values['discounted_label']); if (!($duplicateIndex === FALSE) && !($duplicateIndex == $index)) { $errors["discounted_label[{$index}]"] = ts('Duplicate label value'); } } if (empty($values['discounted_label'][$index]) && empty($values['discounted_value'][$index][$i])) { $countemptyrows++; } if (empty($values['discounted_value'][$index][$i])) { $countemptyvalue++; } } if (!empty($values['_qf_Fee_next']) && ($countemptyrows == 11 || $countemptyvalue == 11)) { $errors["discounted_label[1]"] = $errors["discounted_value[1][{$i}]"] = ts('At least one fee should be entered for your Discount Set. If you do not see the table to enter discount fees, click the "Add Discount Set to Fee Table" button.'); } } } } if ($values['is_monetary']) { //check if financial type is selected if (!$values['financial_type_id']) { $errors['financial_type_id'] = ts("Please select financial type."); } //check for the event fee label (mandatory) if (!$values['fee_label']) { $errors['fee_label'] = ts('Please enter the fee label for the paid event.'); } if (empty($values['price_set_id'])) { //check fee label and amount $check = 0; $optionKeys = array(); foreach ($values['label'] as $key => $val) { if (trim($val) && trim($values['value'][$key])) { $optionKeys[$key] = $key; $check++; } } $default = CRM_Utils_Array::value('default', $values); if ($default && !in_array($default, $optionKeys)) { $errors['default'] = ts('Please select an appropriate option as default.'); } if (!$check) { if (!$values['label'][1]) { $errors['label[1]'] = ts('Please enter a label for at least one fee level.'); } if (!$values['value'][1]) { $errors['value[1]'] = ts('Please enter an amount for at least one fee level.'); } } } if (isset($values['is_pay_later'])) { if (empty($values['pay_later_text'])) { $errors['pay_later_text'] = ts('Please enter the Pay Later prompt to be displayed on the Registration form.'); } if (empty($values['pay_later_receipt'])) { $errors['pay_later_receipt'] = ts('Please enter the Pay Later instructions to be displayed to your users.'); } } } // CRM-16189 try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($values['financial_type_id']); } catch (CRM_Core_Exception $e) { $errors['financial_type_id'] = $e->getMessage(); } return empty($errors) ? TRUE : $errors; }
/** * Validation. * * @param array $params * (ref.) an assoc array of name/value pairs. * * @return bool|array * mixed true or array of errors */ public static function formRule($params) { $errors = array(); if (!$params['name']) { $errors['name'] = ts('Please enter a membership type name.'); } if ($params['minimum_fee'] > 0 && !$params['financial_type_id']) { $errors['financial_type_id'] = ts('Please enter the financial Type.'); } if (empty($params['duration_interval']) and $params['duration_unit'] != 'lifetime') { $errors['duration_interval'] = ts('Please enter a duration interval.'); } if (in_array(CRM_Utils_Array::value('auto_renew', $params), array(1, 2))) { if ($params['duration_interval'] > 1 && $params['duration_unit'] == 'year' || $params['duration_interval'] > 12 && $params['duration_unit'] == 'month') { $errors['duration_unit'] = ts('Automatic renewals are not supported by the currently available payment processors when the membership duration is greater than 1 year / 12 months.'); } } if ($params['period_type'] == 'fixed' && $params['duration_unit'] == 'day') { $errors['period_type'] = ts('Period type should be Rolling when duration unit is Day'); } if ($params['period_type'] == 'fixed' && $params['duration_unit'] == 'year') { $periods = array('fixed_period_start_day', 'fixed_period_rollover_day'); foreach ($periods as $period) { $month = $params[$period]['M']; $date = $params[$period]['d']; if (!$month || !$date) { switch ($period) { case 'fixed_period_start_day': $errors[$period] = ts('Please enter a valid fixed period start day'); break; case 'fixed_period_rollover_day': $errors[$period] = ts('Please enter a valid fixed period rollover day'); break; } } } } if ($params['fixed_period_start_day'] && !empty($params['fixed_period_start_day'])) { $params['fixed_period_start_day']['Y'] = date('Y'); if (!CRM_Utils_Rule::qfDate($params['fixed_period_start_day'])) { $errors['fixed_period_start_day'] = ts('Please enter valid Fixed Period Start Day'); } } if ($params['fixed_period_rollover_day'] && !empty($params['fixed_period_rollover_day'])) { $params['fixed_period_rollover_day']['Y'] = date('Y'); if (!CRM_Utils_Rule::qfDate($params['fixed_period_rollover_day'])) { $errors['fixed_period_rollover_day'] = ts('Please enter valid Fixed Period Rollover Day'); } } // CRM-16189 try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($params['financial_type_id']); } catch (CRM_Core_Exception $e) { $errors['financial_type_id'] = $e->getMessage(); } return empty($errors) ? TRUE : $errors; }
/** * Function to build status message while * enabling/ disabling various objects */ static function getStatusMsg() { $recordID = CRM_Utils_Type::escape($_POST['recordID'], 'Integer'); $recordBAO = CRM_Utils_Type::escape($_POST['recordBAO'], 'String'); $op = CRM_Utils_Type::escape($_POST['op'], 'String'); $show = NULL; if ($op == 'disable-enable') { $status = ts('Are you sure you want to enable this record?'); } else { switch ($recordBAO) { case 'CRM_Core_BAO_UFGroup': require_once str_replace('_', DIRECTORY_SEPARATOR, $recordBAO) . '.php'; $method = 'getUFJoinRecord'; $result = array($recordBAO, $method); $ufJoin = call_user_func_array($result, array($recordID, TRUE)); if (!empty($ufJoin)) { $status = ts('This profile is currently used for %1.', array(1 => implode(', ', $ufJoin))) . ' <br/><br/>' . ts('If you disable the profile - it will be removed from these forms and/or modules. Do you want to continue?'); } else { $status = ts('Are you sure you want to disable this profile?'); } break; case 'CRM_Price_BAO_PriceSet': require_once str_replace('_', DIRECTORY_SEPARATOR, $recordBAO) . '.php'; $usedBy = CRM_Price_BAO_PriceSet::getUsedBy($recordID); $priceSet = CRM_Price_BAO_PriceSet::getTitle($recordID); if (!CRM_Utils_System::isNull($usedBy)) { $template = CRM_Core_Smarty::singleton(); $template->assign('usedBy', $usedBy); $comps = array('Event' => 'civicrm_event', 'Contribution' => 'civicrm_contribution_page', 'EventTemplate' => 'civicrm_event_template'); $contexts = array(); foreach ($comps as $name => $table) { if (array_key_exists($table, $usedBy)) { $contexts[] = $name; } } $template->assign('contexts', $contexts); $show = 'noButton'; $table = $template->fetch('CRM/Price/Page/table.tpl'); $status = ts('Unable to disable the \'%1\' price set - it is currently in use by one or more active events, contribution pages or contributions.', array(1 => $priceSet)) . "<br/> {$table}"; } else { $status = ts('Are you sure you want to disable \'%1\' Price Set?', array(1 => $priceSet)); } break; case 'CRM_Event_BAO_Event': $status = ts('Are you sure you want to disable this Event?'); break; case 'CRM_Core_BAO_UFField': $status = ts('Are you sure you want to disable this CiviCRM Profile field?'); break; case 'CRM_Contribute_BAO_ManagePremiums': $status = ts('Are you sure you want to disable this premium? This action will remove the premium from any contribution pages that currently offer it. However it will not delete the premium record - so you can re-enable it and add it back to your contribution page(s) at a later time.'); break; case 'CRM_Contact_BAO_RelationshipType': $status = ts('Are you sure you want to disable this relationship type?') . '<br/><br/>' . ts('Users will no longer be able to select this value when adding or editing relationships between contacts.'); break; case 'CRM_Financial_BAO_FinancialType': $status = ts('Are you sure you want to disable this financial type?'); break; case 'CRM_Financial_BAO_FinancialAccount': if (!CRM_Financial_BAO_FinancialAccount::getARAccounts($recordID)) { $show = 'noButton'; $status = ts('The selected financial account cannot be disabled because at least one Accounts Receivable type account is required (to ensure that accounting transactions are in balance).'); } else { $status = ts('Are you sure you want to disable this financial account?'); } break; case 'CRM_Financial_BAO_PaymentProcessor': $status = ts('Are you sure you want to disable this payment processor?') . ' <br/><br/>' . ts('Users will no longer be able to select this value when adding or editing transaction pages.'); break; case 'CRM_Financial_BAO_PaymentProcessorType': $status = ts('Are you sure you want to disable this payment processor type?'); break; case 'CRM_Core_BAO_LocationType': $status = ts('Are you sure you want to disable this location type?') . ' <br/><br/>' . ts('Users will no longer be able to select this value when adding or editing contact locations.'); break; case 'CRM_Event_BAO_ParticipantStatusType': $status = ts('Are you sure you want to disable this Participant Status?') . '<br/><br/> ' . ts('Users will no longer be able to select this value when adding or editing Participant Status.'); break; case 'CRM_Mailing_BAO_Component': $status = ts('Are you sure you want to disable this component?'); break; case 'CRM_Core_BAO_CustomField': $status = ts('Are you sure you want to disable this custom data field?'); break; case 'CRM_Core_BAO_CustomGroup': $status = ts('Are you sure you want to disable this custom data group? Any profile fields that are linked to custom fields of this group will be disabled.'); break; case 'CRM_Core_BAO_MessageTemplate': $status = ts('Are you sure you want to disable this message tempate?'); break; case 'CRM_ACL_BAO_ACL': $status = ts('Are you sure you want to disable this ACL?'); break; case 'CRM_ACL_BAO_EntityRole': $status = ts('Are you sure you want to disable this ACL Role Assignment?'); break; case 'CRM_Member_BAO_MembershipType': $status = ts('Are you sure you want to disable this membership type?'); break; case 'CRM_Member_BAO_MembershipStatus': $status = ts('Are you sure you want to disable this membership status rule?'); break; case 'CRM_Price_BAO_PriceField': $status = ts('Are you sure you want to disable this price field?'); break; case 'CRM_Contact_BAO_Group': $status = ts('Are you sure you want to disable this Group?'); break; case 'CRM_Core_BAO_OptionGroup': $status = ts('Are you sure you want to disable this Option?'); break; case 'CRM_Contact_BAO_ContactType': $status = ts('Are you sure you want to disable this Contact Type?'); break; case 'CRM_Core_BAO_OptionValue': require_once str_replace('_', DIRECTORY_SEPARATOR, $recordBAO) . '.php'; $label = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', $recordID, 'label'); $status = ts('Are you sure you want to disable the \'%1\' option ?', array(1 => $label)); $status .= '<br /><br />' . ts('WARNING - Disabling an option which has been assigned to existing records will result in that option being cleared when the record is edited.'); break; case 'CRM_Contribute_BAO_ContributionRecur': $recurDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($recordID); $status = ts('Are you sure you want to mark this recurring contribution as cancelled?'); $status .= '<br /><br /><strong>' . ts('WARNING - This action sets the CiviCRM recurring contribution status to Cancelled, but does NOT send a cancellation request to the payment processor. You will need to ensure that this recurring payment (subscription) is cancelled by the payment processor.') . '</strong>'; if ($recurDetails->membership_id) { $status .= '<br /><br /><strong>' . ts('This recurring contribution is linked to an auto-renew membership. If you cancel it, the associated membership will no longer renew automatically. However, the current membership status will not be affected.') . '</strong>'; } break; case 'CRM_Batch_BAO_Batch': if ($op == 'close') { $status = ts('Are you sure you want to close this batch?'); } elseif ($op == 'open') { $status = ts('Are you sure you want to reopen this batch?'); } elseif ($op == 'delete') { $status = ts('Are you sure you want to delete this batch?'); } elseif ($op == 'remove') { $status = ts('Are you sure you want to remove this financial transaction?'); } elseif ($op == 'export') { $status = ts('Are you sure you want to close and export this batch?'); } else { $status = ts('Are you sure you want to assign this financial transaction to the batch?'); } break; default: $status = ts('Are you sure you want to disable this record?'); break; } } $statusMessage['status'] = $status; $statusMessage['show'] = $show; echo json_encode($statusMessage); CRM_Utils_System::civiExit(); }
/** * Test testGetAllDeferredFinancialAccount. */ public function testGetAllDeferredFinancialAccount() { $financialAccount = CRM_Financial_BAO_FinancialAccount::getAllDeferredFinancialAccount(); // The two deferred financial accounts which are created by default. $expected = array("Deferred Revenue - Event Fee", "Deferred Revenue - Member Dues"); $this->assertEquals(array_count_values($expected), array_count_values($financialAccount), "The two arrays are not the same"); $this->_createDeferredFinancialAccount(); $financialAccount = CRM_Financial_BAO_FinancialAccount::getAllDeferredFinancialAccount(); $expected[] = "TestFinancialAccount_1"; $this->assertEquals(array_count_values($expected), array_count_values($financialAccount), "The two arrays are not the same"); }
/** * Process payment after confirmation. * * @param CRM_Core_Form $form * Form object. * @param array $paymentParams * Array with payment related key. * value pairs * @param int $contactID * Contact id. * @param int $contributionTypeId * Financial type id. * @param int|string $component component id * @param $isTest * * @throws CRM_Core_Exception * @throws Exception * @return array * associated array * */ public static function processConfirm(&$form, &$paymentParams, $contactID, $contributionTypeId, $component = 'contribution', $isTest) { CRM_Core_Payment_Form::mapParams($form->_bltID, $form->_params, $paymentParams, TRUE); $lineItems = $form->_lineItem; $isPaymentTransaction = self::isPaymentTransaction($form); $financialType = new CRM_Financial_DAO_FinancialType(); $financialType->id = $contributionTypeId; $financialType->find(TRUE); if ($financialType->is_deductible) { $form->assign('is_deductible', TRUE); $form->set('is_deductible', TRUE); } // add some financial type details to the params list // if folks need to use it //CRM-15297 - contributionType is obsolete - pass financial type as well so people can deprecate it $paymentParams['financialType_name'] = $paymentParams['contributionType_name'] = $form->_params['contributionType_name'] = $financialType->name; //CRM-11456 $paymentParams['financialType_accounting_code'] = $paymentParams['contributionType_accounting_code'] = $form->_params['contributionType_accounting_code'] = CRM_Financial_BAO_FinancialAccount::getAccountingCode($contributionTypeId); $paymentParams['contributionPageID'] = $form->_params['contributionPageID'] = $form->_values['id']; $paymentParams['contactID'] = $form->_params['contactID'] = $contactID; //fix for CRM-16317 $form->_params['receive_date'] = date('YmdHis'); $form->assign('receive_date', CRM_Utils_Date::mysqlToIso($form->_params['receive_date'])); if ($isPaymentTransaction) { // Fix for CRM-14354. If the membership is recurring, don't create a // civicrm_contribution_recur record for the additional contribution // (i.e., the amount NOT associated with the membership). Temporarily // cache the is_recur values so we can process the additional gift as a // one-off payment. if (!empty($form->_values['is_recur'])) { if ($form->_membershipBlock['is_separate_payment'] && !empty($form->_params['auto_renew'])) { $cachedFormValue = CRM_Utils_Array::value('is_recur', $form->_values); $cachedParamValue = CRM_Utils_Array::value('is_recur', $paymentParams); unset($form->_values['is_recur']); unset($paymentParams['is_recur']); } } $contributionParams = array('contact_id' => $contactID, 'line_item' => $lineItems, 'is_test' => $isTest, 'campaign_id' => CRM_Utils_Array::value('campaign_id', $paymentParams, CRM_Utils_Array::value('campaign_id', $form->_values)), 'contribution_page_id' => $form->_id, 'source' => CRM_Utils_Array::value('source', $paymentParams, CRM_Utils_Array::value('description', $paymentParams))); $isMonetary = !empty($form->_values['is_monetary']); if ($isMonetary) { if (empty($paymentParams['is_pay_later'])) { // @todo look up payment_instrument_id on payment processor table. $contributionParams['payment_instrument_id'] = 1; } } $contribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($form, $paymentParams, NULL, $contributionParams, $financialType, TRUE, TRUE, $form->_bltID); $paymentParams['contributionTypeID'] = $contributionTypeId; $paymentParams['item_name'] = $form->_params['description']; if ($contribution && $form->_values['is_recur'] && $contribution->contribution_recur_id) { $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id; } $paymentParams['qfKey'] = $form->controller->_key; if ($component == 'membership') { return array('contribution' => $contribution); } // restore cached values (part of fix for CRM-14354) if (!empty($cachedFormValue)) { $form->_values['is_recur'] = $cachedFormValue; $paymentParams['is_recur'] = $cachedParamValue; } $paymentParams['contributionID'] = $contribution->id; //CRM-15297 deprecate contributionTypeID $paymentParams['financialTypeID'] = $paymentParams['contributionTypeID'] = $contribution->financial_type_id; $paymentParams['contributionPageID'] = $contribution->contribution_page_id; if (isset($paymentParams['contribution_source'])) { $paymentParams['source'] = $paymentParams['contribution_source']; } if ($form->_values['is_recur'] && $contribution->contribution_recur_id) { $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id; } if ($form->_contributeMode && $form->_amount > 0.0) { try { $payment = Civi\Payment\System::singleton()->getByProcessor($form->_paymentProcessor); if ($form->_contributeMode == 'notify') { // We want to get rid of this & make it generic - eg. by making payment processing the last thing // and always calling it first. $form->postProcessHook(); } $result = $payment->doPayment($paymentParams); $form->_params = array_merge($form->_params, $result); $form->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $result)); if (!empty($result['trxn_id'])) { $contribution->trxn_id = $result['trxn_id']; } if (!empty($result['payment_status_id'])) { $contribution->payment_status_id = $result['payment_status_id']; } $result['contribution'] = $contribution; return $result; } catch (\Civi\Payment\Exception\PaymentProcessorException $e) { // Clean up DB as appropriate. if (!empty($paymentParams['contributionID'])) { CRM_Contribute_BAO_Contribution::failPayment($paymentParams['contributionID'], $paymentParams['contactID'], $e->getMessage()); } if (!empty($paymentParams['contributionRecurID'])) { CRM_Contribute_BAO_ContributionRecur::deleteRecurContribution($paymentParams['contributionRecurID']); } $result['is_payment_failure'] = TRUE; $result['error'] = $e; return $result; } } } // Only pay later or unpaid should reach this point. The theory is that paylater should get a receipt now & // processor // transaction receipts should be outcome driven. $form->set('params', $form->_params); if (isset($paymentParams['contribution_source'])) { $form->_params['source'] = $paymentParams['contribution_source']; } // get the price set values for receipt. if ($form->_priceSetId && $form->_lineItem) { $form->_values['lineItem'] = $form->_lineItem; $form->_values['priceSetID'] = $form->_priceSetId; } $form->_values['contribution_id'] = $contribution->id; $form->_values['contribution_page_id'] = $contribution->contribution_page_id; CRM_Contribute_BAO_ContributionPage::sendMail($contactID, $form->_values, $contribution->is_test); }
/** * Add the event. * * @param array $params * Reference array contains the values submitted by the form. * * @return CRM_Event_DAO_Event */ public static function add(&$params) { CRM_Utils_System::flushCache(); $financialTypeId = NULL; if (!empty($params['id'])) { CRM_Utils_Hook::pre('edit', 'Event', $params['id'], $params); if (empty($params['skipFinancialType'])) { $financialTypeId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $params['id'], 'financial_type_id'); } } else { CRM_Utils_Hook::pre('create', 'Event', NULL, $params); } // CRM-16189 if (!empty($params['financial_type_id'])) { CRM_Financial_BAO_FinancialAccount::validateFinancialType($params['financial_type_id']); } $event = new CRM_Event_DAO_Event(); $event->copyValues($params); $result = $event->save(); if (!empty($params['id'])) { CRM_Utils_Hook::post('edit', 'Event', $event->id, $event); } else { CRM_Utils_Hook::post('create', 'Event', $event->id, $event); } if ($financialTypeId && !empty($params['financial_type_id']) && $financialTypeId != $params['financial_type_id']) { CRM_Price_BAO_PriceFieldValue::updateFinancialType($params['id'], 'civicrm_event', $params['financial_type_id']); } return $result; }
/** * Process the form submission. * * @return void */ public function postProcess() { if ($this->_action & CRM_Core_Action::DELETE) { CRM_Financial_BAO_FinancialAccount::del($this->_id); CRM_Core_Session::setStatus(ts('Selected Financial Account has been deleted.')); } else { $ids = array(); // store the submitted values in an array $params = $this->exportValues(); if ($this->_action & CRM_Core_Action::UPDATE) { $ids['contributionType'] = $this->_id; } $contributionType = CRM_Financial_BAO_FinancialAccount::add($params, $ids); CRM_Core_Session::setStatus(ts('The Financial Account \'%1\' has been saved.', array(1 => $contributionType->name))); } }
/** * check method getAccountingCode() */ function testGetAccountingCode() { $params = array('name' => 'Donations', 'is_active' => 1, 'is_reserved' => 0); $ids = array(); $financialType = CRM_Financial_BAO_FinancialType::add($params, $ids); $financialAccountid = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', 'Donations', 'id', 'name'); CRM_Core_DAO::setFieldValue('CRM_Financial_DAO_FinancialAccount', $financialAccountid, 'accounting_code', '4800'); $accountingCode = CRM_Financial_BAO_FinancialAccount::getAccountingCode($financialType->id); $this->assertEquals($accountingCode, 4800, 'Verify accounting code.'); }
/** * Global validation rules for the form. * * @param array $fields * Posted values of the form. * * @param $files * @param CRM_Core_Form $form * * @return array * if errors then list of errors to be posted back to the form, * true otherwise */ public static function formRule($fields, $files, $form) { $errors = array(); if (!empty($fields['count']) && !empty($fields['max_value']) && $fields['count'] > $fields['max_value']) { $errors['count'] = ts('Participant count can not be greater than max participants.'); } // CRM-16189 try { CRM_Financial_BAO_FinancialAccount::validateFinancialType($fields['financial_type_id'], $form->_fid, 'PriceField'); } catch (CRM_Core_Exception $e) { $errors['financial_type_id'] = $e->getMessage(); } return empty($errors) ? TRUE : $errors; }
/** * Process payment after confirmation. * * @param CRM_Core_Form $form * Form object. * @param array $paymentParams * Array with payment related key. * value pairs * @param array $premiumParams * Array with premium related key. * value pairs * @param int $contactID * Contact id. * @param int $contributionTypeId * Financial type id. * @param int|string $component component id * @param array $fieldTypes * Presumably relates to custom field types - used when building data for sendMail. * @param $isTest * @param $isPayLater * * @throws CRM_Core_Exception * @throws Exception * @return array * associated array * */ public static function processConfirm(&$form, &$paymentParams, &$premiumParams, $contactID, $contributionTypeId, $component = 'contribution', $fieldTypes = NULL, $isTest, $isPayLater) { CRM_Core_Payment_Form::mapParams($form->_bltID, $form->_params, $paymentParams, TRUE); $lineItems = $form->_lineItem; $isPaymentTransaction = self::isPaymentTransaction($form); $contributionType = new CRM_Financial_DAO_FinancialType(); $contributionType->id = $contributionTypeId; if (!$contributionType->find(TRUE)) { //@todo - surely this check was part of the 4.3 upgrade & can go now? CRM_Core_Error::fatal('Could not find a system table'); } // add some financial type details to the params list // if folks need to use it //CRM-15297 - contributionType is obsolete - pass financial type as well so people can deprecate it $paymentParams['financialType_name'] = $paymentParams['contributionType_name'] = $form->_params['contributionType_name'] = $contributionType->name; //CRM-11456 $paymentParams['financialType_accounting_code'] = $paymentParams['contributionType_accounting_code'] = $form->_params['contributionType_accounting_code'] = CRM_Financial_BAO_FinancialAccount::getAccountingCode($contributionTypeId); $paymentParams['contributionPageID'] = $form->_params['contributionPageID'] = $form->_values['id']; $payment = NULL; $paymentObjError = ts('The system did not record payment details for this payment and so could not process the transaction. Please report this error to the site administrator.'); if ($isPaymentTransaction) { $payment = CRM_Core_Payment::singleton($form->_mode, $form->_paymentProcessor, $form); } //fix for CRM-2062 //fix for CRM-16317 $now = $form->_params['receive_date'] = date('YmdHis'); $form->assign('receive_date', CRM_Utils_Date::mysqlToIso($form->_params['receive_date'])); $result = NULL; if ($form->_contributeMode == 'notify' || $isPayLater) { // this is not going to come back, i.e. we fill in the other details // when we get a callback from the payment processor // also add the contact ID and contribution ID to the params list $paymentParams['contactID'] = $form->_params['contactID'] = $contactID; $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($form, $paymentParams, NULL, $contactID, $contributionType, TRUE, TRUE, $isTest, $lineItems); if ($contribution) { $form->_params['contributionID'] = $contribution->id; } $form->_params['contributionTypeID'] = $contributionTypeId; $form->_params['item_name'] = $form->_params['description']; if ($contribution && $form->_values['is_recur'] && $contribution->contribution_recur_id) { $form->_params['contributionRecurID'] = $contribution->contribution_recur_id; } $form->set('params', $form->_params); $form->postProcessPremium($premiumParams, $contribution); if ($isPaymentTransaction) { // add qfKey so we can send to paypal $form->_params['qfKey'] = $form->controller->_key; if ($component == 'membership') { $membershipResult = array(1 => $contribution); return $membershipResult; } else { if (!$isPayLater) { if (is_object($payment)) { // call postProcess hook before leaving $form->postProcessHook(); // this does not return $result = $payment->doTransferCheckout($form->_params, 'contribute'); } else { CRM_Core_Error::fatal($paymentObjError); } } else { // follow similar flow as IPN // send the receipt mail $form->set('params', $form->_params); if ($contributionType->is_deductible) { $form->assign('is_deductible', TRUE); $form->set('is_deductible', TRUE); } if (isset($paymentParams['contribution_source'])) { $form->_params['source'] = $paymentParams['contribution_source']; } // get the price set values for receipt. if ($form->_priceSetId && $form->_lineItem) { $form->_values['lineItem'] = $form->_lineItem; $form->_values['priceSetID'] = $form->_priceSetId; } $form->_values['contribution_id'] = $contribution->id; $form->_values['contribution_page_id'] = $contribution->contribution_page_id; CRM_Contribute_BAO_ContributionPage::sendMail($contactID, $form->_values, $contribution->is_test); return; } } } } elseif ($form->_contributeMode == 'express') { if ($form->_values['is_monetary'] && $form->_amount > 0.0) { // determine if express + recurring and direct accordingly if (!empty($paymentParams['is_recur']) && $paymentParams['is_recur'] == 1) { if (is_object($payment)) { $result = $payment->createRecurringPayments($paymentParams); } else { CRM_Core_Error::fatal($paymentObjError); } } else { if (is_object($payment)) { $result = $payment->doExpressCheckout($paymentParams); } else { CRM_Core_Error::fatal($paymentObjError); } } } } elseif ($isPaymentTransaction) { if (!empty($paymentParams['is_recur']) && $form->_contributeMode == 'direct') { // For recurring contribution, create Contribution Record first. // Contribution ID, Recurring ID and Contact ID needed // When we get a callback from the payment processor $paymentParams['contactID'] = $contactID; // Fix for CRM-14354. If the membership is recurring, don't create a // civicrm_contribution_recur record for the additional contribution // (i.e., the amount NOT associated with the membership). Temporarily // cache the is_recur values so we can process the additional gift as a // one-off payment. $pending = FALSE; if (!empty($form->_values['is_recur'])) { if ($form->_membershipBlock['is_separate_payment'] && !empty($form->_params['auto_renew'])) { $cachedFormValue = CRM_Utils_Array::value('is_recur', $form->_values); $cachedParamValue = CRM_Utils_Array::value('is_recur', $paymentParams); unset($form->_values['is_recur']); unset($paymentParams['is_recur']); } else { $pending = TRUE; } } $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($form, $paymentParams, NULL, $contactID, $contributionType, $pending, TRUE, $isTest, $lineItems); // restore cached values (part of fix for CRM-14354) if (!empty($cachedFormValue)) { $form->_values['is_recur'] = $cachedFormValue; $paymentParams['is_recur'] = $cachedParamValue; } $paymentParams['contributionID'] = $contribution->id; //CRM-15297 deprecate contributionTypeID $paymentParams['financialTypeID'] = $paymentParams['contributionTypeID'] = $contribution->financial_type_id; $paymentParams['contributionPageID'] = $contribution->contribution_page_id; if ($form->_values['is_recur'] && $contribution->contribution_recur_id) { $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id; } } if (is_object($payment)) { $result = $payment->doDirectPayment($paymentParams); } else { CRM_Core_Error::fatal($paymentObjError); } } if ($component == 'membership') { $membershipResult = array(); } if (is_a($result, 'CRM_Core_Error')) { //make sure to cleanup db for recurring case. //@todo this clean up has always been controversial as many orgs prefer to see failed transactions. // most recent discussion has been that they should be retained and this could be altered if (!empty($paymentParams['contributionID'])) { CRM_Contribute_BAO_Contribution::deleteContribution($paymentParams['contributionID']); } if (!empty($paymentParams['contributionRecurID'])) { CRM_Contribute_BAO_ContributionRecur::deleteRecurContribution($paymentParams['contributionRecurID']); } if ($component !== 'membership') { CRM_Core_Error::displaySessionError($result); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/transact', "_qf_Main_display=true&qfKey={$form->_params['qfKey']}")); } $membershipResult[1] = $result; } elseif ($result || $form->_amount == 0.0 && !$form->_params['is_pay_later']) { if ($result) { $form->_params = array_merge($form->_params, $result); } $form->set('params', $form->_params); $form->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $result)); // result has all the stuff we need // lets archive it to a financial transaction //@todo - this is done in 2 places - can't we just do it once straight after retrieving contribution type - // when would this be a bad thing? if ($contributionType->is_deductible) { $form->assign('is_deductible', TRUE); $form->set('is_deductible', TRUE); } if (isset($paymentParams['contribution_source'])) { $form->_params['source'] = $paymentParams['contribution_source']; } // check if pending was set to true by payment processor $pending = FALSE; if (!empty($form->_params['contribution_status_pending'])) { $pending = TRUE; } if (!(!empty($paymentParams['is_recur']) && $form->_contributeMode == 'direct')) { $contribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($form, $form->_params, $result, $contactID, $contributionType, $pending, TRUE, $isTest, $lineItems); } $form->postProcessPremium($premiumParams, $contribution); if (is_array($result)) { if (!empty($result['trxn_id'])) { $contribution->trxn_id = $result['trxn_id']; } if (!empty($result['payment_status_id'])) { $contribution->payment_status_id = $result['payment_status_id']; } } $membershipResult[1] = $contribution; } if ($component == 'membership') { return $membershipResult; } //Do not send an email if Recurring contribution is done via Direct Mode //We will send email once the IPN is received. if (!empty($paymentParams['is_recur']) && $form->_contributeMode == 'direct') { return TRUE; } // get the price set values for receipt. if ($form->_priceSetId && $form->_lineItem) { $form->_values['lineItem'] = $form->_lineItem; $form->_values['priceSetID'] = $form->_priceSetId; } // finally send an email receipt if ($contribution) { $form->_values['contribution_id'] = $contribution->id; CRM_Contribute_BAO_ContributionPage::sendMail($contactID, $form->_values, $contribution->is_test, FALSE, $fieldTypes); } }