Пример #1
0
 /**
  * Takes an associative array and creates a contribution object.
  *
  * the function extract all the params it needs to initialize the create a
  * contribution object. the params array could contain additional unused name/value
  * pairs
  *
  * @param array $params
  *   (reference ) an assoc array of name/value pairs.
  *
  * @return CRM_Contribute_BAO_Contribution
  * @todo move hook calls / extended logic to create - requires changing calls to call create not add
  */
 public static function add(&$params)
 {
     if (!empty($params['id'])) {
         CRM_Utils_Hook::pre('edit', 'ContributionRecur', $params['id'], $params);
     } else {
         CRM_Utils_Hook::pre('create', 'ContributionRecur', NULL, $params);
     }
     // make sure we're not creating a new recurring contribution with the same transaction ID
     // or invoice ID as an existing recurring contribution
     $duplicates = array();
     if (self::checkDuplicate($params, $duplicates)) {
         $error = CRM_Core_Error::singleton();
         $d = implode(', ', $duplicates);
         $error->push(CRM_Core_Error::DUPLICATE_CONTRIBUTION, 'Fatal', array($d), "Found matching recurring contribution(s): {$d}");
         return $error;
     }
     $recurring = new CRM_Contribute_BAO_ContributionRecur();
     $recurring->copyValues($params);
     $recurring->id = CRM_Utils_Array::value('id', $params);
     // set currency for CRM-1496
     if (empty($params['id']) && !isset($recurring->currency)) {
         $config = CRM_Core_Config::singleton();
         $recurring->currency = $config->defaultCurrency;
     }
     $result = $recurring->save();
     if (!empty($params['id'])) {
         CRM_Utils_Hook::post('edit', 'ContributionRecur', $recurring->id, $recurring);
     } else {
         CRM_Utils_Hook::post('create', 'ContributionRecur', $recurring->id, $recurring);
     }
     if (!empty($params['custom']) && is_array($params['custom'])) {
         CRM_Core_BAO_CustomValueTable::store($params['custom'], 'civicrm_contribution_recur', $recurring->id);
     }
     return $result;
 }
Пример #2
0
 /**
  * Test that an object can be retrieved & saved (per CRM-14986).
  *
  * This has been causing a DB error so we are checking for absence of error
  */
 public function testFindSave()
 {
     $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', $this->_params);
     $dao = new CRM_Contribute_BAO_ContributionRecur();
     $dao->id = $contributionRecur['id'];
     $dao->find(TRUE);
     $dao->is_email_receipt = 0;
     $dao->save();
 }
 /**
  * takes an associative array and creates a contribution object
  *
  * the function extract all the params it needs to initialize the create a
  * contribution object. the params array could contain additional unused name/value
  * pairs
  *
  * @param array  $params (reference ) an assoc array of name/value pairs
  * @param array $ids    the array that holds all the db ids
  *
  * @return object CRM_Contribute_BAO_Contribution object
  * @access public
  * @static
  */
 static function add(&$params, &$ids)
 {
     $duplicates = array();
     if (self::checkDuplicate($params, $duplicates)) {
         $error =& CRM_Core_Error::singleton();
         $d = implode(', ', $duplicates);
         $error->push(CRM_Core_Error::DUPLICATE_CONTRIBUTION, 'Fatal', array($d), "Found matching contribution(s): {$d}");
         return $error;
     }
     $recurring = new CRM_Contribute_BAO_ContributionRecur();
     $recurring->copyValues($params);
     $recurring->id = CRM_Utils_Array::value('contribution', $ids);
     // set currency for CRM-1496
     if (!isset($recurring->currency)) {
         $config =& CRM_Core_Config::singleton();
         $recurring->currency = $config->defaultCurrency;
     }
     return $recurring->save();
 }
Пример #4
0
 static function processAPIContribution($params)
 {
     if (empty($params) || array_key_exists('error', $params)) {
         return false;
     }
     // add contact using dedupe rule
     require_once 'CRM/Dedupe/Finder.php';
     $dedupeParams = CRM_Dedupe_Finder::formatParams($params, 'Individual');
     $dedupeParams['check_permission'] = false;
     $dupeIds = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Individual');
     // if we find more than one contact, use the first one
     if (CRM_Utils_Array::value(0, $dupeIds)) {
         $params['contact_id'] = $dupeIds[0];
     }
     require_once 'CRM/Contact/BAO/Contact.php';
     $contact = CRM_Contact_BAO_Contact::create($params);
     if (!$contact->id) {
         return false;
     }
     // only pass transaction params to contribution::create, if available
     if (array_key_exists('transaction', $params)) {
         $params = $params['transaction'];
         $params['contact_id'] = $contact->id;
     }
     // handle contribution custom data
     $customFields = CRM_Core_BAO_CustomField::getFields('Contribution', false, false, CRM_Utils_Array::value('contribution_type_id', $params));
     $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params, $customFields, CRM_Utils_Array::value('id', $params, null), 'Contribution');
     // create contribution
     // if this is a recurring contribution then process it first
     if ($params['trxn_type'] == 'subscrpayment') {
         // see if a recurring record already exists
         require_once 'CRM/Contribute/BAO/ContributionRecur.php';
         $recurring = new CRM_Contribute_BAO_ContributionRecur();
         $recurring->processor_id = $params['processor_id'];
         if (!$recurring->find(true)) {
             $recurring = new CRM_Contribute_BAO_ContributionRecur();
             $recurring->invoice_id = $params['invoice_id'];
             $recurring->find(true);
         }
         // This is the same thing the CiviCRM IPN handler does to handle
         // subsequent recurring payments to avoid duplicate contribution
         // errors due to invoice ID. See:
         // ./CRM/Core/Payment/PayPalIPN.php:200
         if ($recurring->id) {
             $params['invoice_id'] = md5(uniqid(rand(), true));
         }
         $recurring->copyValues($params);
         $recurring->save();
         if (is_a($recurring, 'CRM_Core_Error')) {
             return false;
         } else {
             $params['contribution_recur_id'] = $recurring->id;
         }
     }
     require_once 'CRM/Contribute/BAO/Contribution.php';
     $contribution =& CRM_Contribute_BAO_Contribution::create($params, CRM_Core_DAO::$_nullArray);
     if (!$contribution->id) {
         return false;
     }
     return true;
 }
Пример #5
0
 /**
  * This is the counterpart to the doDirectPayment method. This method creates
  * partial mandates, where the subsequent payment processess produces a payment.
  *
  * This function here should be called after the payment process was completed.
  * It will process all the PARTIAL mandates and connect them with created contributions.
  */
 public static function processPartialMandates()
 {
     // load all the PARTIAL mandates
     $partial_mandates = civicrm_api3('SepaMandate', 'get', array('version' => 3, 'status' => 'PARTIAL', 'option.limit' => 9999));
     foreach ($partial_mandates['values'] as $mandate_id => $mandate) {
         if ($mandate['type'] == 'OOFF') {
             // in the OOFF case, we need to find the contribution, and connect it
             $contribution = civicrm_api('Contribution', 'getsingle', array('version' => 3, 'trxn_id' => $mandate['reference']));
             if (empty($contribution['is_error'])) {
                 // check collection date
                 $ooff_notice = (int) CRM_Sepa_Logic_Settings::getSetting("batching.OOFF.notice", $mandate['creditor_id']);
                 $first_collection_date = strtotime("+{$ooff_notice} days");
                 $collection_date = strtotime($contribution['receive_date']);
                 if ($collection_date < $first_collection_date) {
                     // adjust collection date to the earliest possible one
                     $collection_date = $first_collection_date;
                 }
                 // FOUND! Update the contribution...
                 $contribution_bao = new CRM_Contribute_BAO_Contribution();
                 $contribution_bao->get('id', $contribution['id']);
                 $contribution_bao->is_pay_later = 0;
                 $contribution_bao->receive_date = date('YmdHis', $collection_date);
                 $contribution_bao->contribution_status_id = (int) CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name');
                 $contribution_bao->payment_instrument_id = (int) CRM_Core_OptionGroup::getValue('payment_instrument', 'OOFF', 'name');
                 $contribution_bao->save();
                 // ...and connect it to the mandate
                 $mandate_update = array();
                 $mandate_update['id'] = $mandate['id'];
                 $mandate_update['entity_id'] = $contribution['id'];
                 $mandate_update['type'] = $mandate['type'];
                 if (empty($mandate['contact_id'])) {
                     // this happens when the payment gets created AFTER the doDirectPayment method
                     $mandate_update['contact_id'] = $contribution_bao->contact_id;
                 }
                 // initialize according to the creditor settings
                 CRM_Sepa_BAO_SEPACreditor::initialiseMandateData($mandate['creditor_id'], $mandate_update);
                 // finally, write the changes to the mandate
                 civicrm_api3('SepaMandate', 'create', $mandate_update);
             } else {
                 // if NOT FOUND or error, delete the partial mandate
                 civicrm_api3('SepaMandate', 'delete', array('id' => $mandate_id));
             }
         } elseif ($mandate['type'] == 'RCUR') {
             // in the RCUR case, we also need to find the contribution, and connect it
             // load the contribution AND the associated recurring contribution
             $contribution = civicrm_api('Contribution', 'getsingle', array('version' => 3, 'trxn_id' => $mandate['reference']));
             $rcontribution = civicrm_api('ContributionRecur', 'getsingle', array('version' => 3, 'trxn_id' => $mandate['reference']));
             if (empty($contribution['is_error']) && empty($rcontribution['is_error'])) {
                 // we need to set the receive date to the correct collection date, otherwise it will be created again (w/o)
                 $rcur_notice = (int) CRM_Sepa_Logic_Settings::getSetting("batching.RCUR.notice", $mandate['creditor_id']);
                 $now = strtotime(date('Y-m-d', strtotime("now +{$rcur_notice} days")));
                 // round to full day
                 $collection_date = CRM_Sepa_Logic_Batching::getNextExecutionDate($rcontribution, $now);
                 // fix contribution
                 $contribution_bao = new CRM_Contribute_BAO_Contribution();
                 $contribution_bao->get('id', $contribution['id']);
                 $contribution_bao->is_pay_later = 0;
                 $contribution_bao->contribution_status_id = (int) CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name');
                 $contribution_bao->payment_instrument_id = (int) CRM_Core_OptionGroup::getValue('payment_instrument', 'FRST', 'name');
                 $contribution_bao->receive_date = date('YmdHis', strtotime($collection_date));
                 $contribution_bao->save();
                 // fix recurring contribution
                 $rcontribution_bao = new CRM_Contribute_BAO_ContributionRecur();
                 $rcontribution_bao->get('id', $rcontribution['id']);
                 $rcontribution_bao->start_date = date('YmdHis', strtotime($rcontribution_bao->start_date));
                 $rcontribution_bao->create_date = date('YmdHis', strtotime($rcontribution_bao->create_date));
                 $rcontribution_bao->modified_date = date('YmdHis', strtotime($rcontribution_bao->modified_date));
                 $rcontribution_bao->contribution_status_id = (int) CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name');
                 $rcontribution_bao->payment_instrument_id = (int) CRM_Core_OptionGroup::getValue('payment_instrument', 'FRST', 'name');
                 $rcontribution_bao->save();
                 // ...and connect it to the mandate
                 $mandate_update = array();
                 $mandate_update['id'] = $mandate['id'];
                 $mandate_update['entity_id'] = $rcontribution['id'];
                 $mandate_update['type'] = $mandate['type'];
                 if (empty($mandate['contact_id'])) {
                     $mandate_update['contact_id'] = $contribution['contact_id'];
                     $mandate['contact_id'] = $contribution['contact_id'];
                 }
                 //NO: $mandate_update['first_contribution_id'] = $contribution['id'];
                 // initialize according to the creditor settings
                 CRM_Sepa_BAO_SEPACreditor::initialiseMandateData($mandate['creditor_id'], $mandate_update);
                 // finally, write the changes to the mandate
                 civicrm_api3('SepaMandate', 'create', $mandate_update);
                 // ...and trigger notification
                 // FIXME: WORKAROUND, see https://github.com/Project60/org.project60.sepa/issues/296)
                 CRM_Contribute_BAO_ContributionPage::recurringNotify(CRM_Core_Payment::RECURRING_PAYMENT_START, $mandate['contact_id'], $contribution_bao->contribution_page_id, $rcontribution_bao);
             } else {
                 // something went wrong, delete partial
                 error_log("org.project60.sepa: deleting partial mandate " . $mandate['reference']);
                 civicrm_api3('SepaMandate', 'delete', array('id' => $mandate_id));
             }
         }
     }
 }