/**
  * The function gets called when a new order takes place.
  *
  * @param xml   $dataRoot    response send by google in xml format
  * @param array $privateData contains the name value pair of <merchant-private-data>
  *
  * @return void
  *
  */
 function newOrderNotify($dataRoot, $privateData, $component)
 {
     $ids = $input = $params = array();
     $input['component'] = strtolower($component);
     $ids['contact'] = self::retrieve('contactID', 'Integer', $privateData, TRUE);
     $ids['contribution'] = self::retrieve('contributionID', 'Integer', $privateData, TRUE);
     $ids['contributionRecur'] = $ids['contributionPage'] = NULL;
     if ($input['component'] == "event") {
         $ids['event'] = self::retrieve('eventID', 'Integer', $privateData, TRUE);
         $ids['participant'] = self::retrieve('participantID', 'Integer', $privateData, TRUE);
         $ids['membership'] = NULL;
     } else {
         $ids['membership'] = self::retrieve('membershipID', 'Integer', $privateData, FALSE);
         $ids['related_contact'] = self::retrieve('relatedContactID', 'Integer', $privateData, FALSE);
         $ids['onbehalf_dupe_alert'] = self::retrieve('onBehalfDupeAlert', 'Integer', $privateData, FALSE);
         $ids['contributionRecur'] = self::retrieve('contributionRecurID', 'Integer', $privateData, FALSE);
     }
     $paymentProcessorID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_PaymentProcessorType', 'Google_Checkout', 'id', 'payment_processor_type');
     if (!$this->validateData($input, $ids, $objects, TRUE, $paymentProcessorID)) {
         return FALSE;
     }
     $input['invoice'] = $privateData['invoiceID'];
     $input['newInvoice'] = $dataRoot['google-order-number']['VALUE'];
     if ($ids['contributionRecur']) {
         if ($objects['contributionRecur']->invoice_id == $dataRoot['serial-number']) {
             CRM_Core_Error::debug_log_message("The new order notification already handled: {$dataRoot['serial-number']}.");
             return;
         } else {
             $transaction = new CRM_Core_Transaction();
             CRM_Core_Error::debug_log_message("New order for an installment received.");
             $recur =& $objects['contributionRecur'];
             // fix dates that already exist
             $dates = array('create', 'start', 'end', 'cancel', 'modified');
             foreach ($dates as $date) {
                 $name = "{$date}_date";
                 if ($recur->{$name}) {
                     $recur->{$name} = CRM_Utils_Date::isoToMysql($recur->{$name});
                 }
             }
             $recur->invoice_id = $dataRoot['serial-number'];
             $recur->processor_id = $input['newInvoice'];
             $recur->save();
             if ($objects['contribution']->contribution_status_id == 1) {
                 // create a contribution and then get it processed
                 $contribution = new CRM_Contribute_DAO_Contribution();
                 $contribution->contact_id = $ids['contact'];
                 $contribution->contribution_type_id = $objects['contributionType']->id;
                 $contribution->contribution_page_id = $objects['contribution']->contribution_page_id;
                 $contribution->contribution_recur_id = $ids['contributionRecur'];
                 $contribution->receive_date = date('YmdHis');
                 $contribution->currency = $objects['contribution']->currency;
                 $contribution->payment_instrument_id = $objects['contribution']->payment_instrument_id;
                 $contribution->amount_level = $objects['contribution']->amount_level;
                 $contribution->address_id = $objects['contribution']->address_id;
                 $contribution->invoice_id = $input['invoice'];
                 $contribution->total_amount = $dataRoot['order-total']['VALUE'];
                 $contribution->contribution_status_id = 2;
                 $objects['contribution'] = $contribution;
             }
             $transaction->commit();
         }
     }
     // make sure the invoice is valid and matches what we have in the contribution record
     $contribution =& $objects['contribution'];
     if ($contribution->invoice_id != $input['invoice']) {
         CRM_Core_Error::debug_log_message("Invoice values dont match between database and IPN request");
         return;
     }
     // lets replace invoice-id with google-order-number because thats what is common and unique
     // in subsequent calls or notifications sent by google.
     $contribution->invoice_id = $input['newInvoice'];
     $input['amount'] = $dataRoot['order-total']['VALUE'];
     if ($contribution->total_amount != $input['amount']) {
         CRM_Core_Error::debug_log_message("Amount values dont match between database and IPN request");
         return;
     }
     if (!$this->getInput($input, $ids, $dataRoot)) {
         return FALSE;
     }
     $transaction = new CRM_Core_Transaction();
     // check if contribution is already completed, if so we ignore this ipn
     if ($contribution->contribution_status_id == 1) {
         CRM_Core_Error::debug_log_message("returning since contribution has already been handled");
         return;
     } else {
         /* Since trxn_id hasn't got any use here,
          * lets make use of it by passing the eventID/membershipTypeID to next level.
          * And change trxn_id to google-order-number before finishing db update */
         if (CRM_Utils_Array::value('event', $ids)) {
             $contribution->trxn_id = $ids['event'] . CRM_Core_DAO::VALUE_SEPARATOR . $ids['participant'];
         } elseif (CRM_Utils_Array::value('membership', $ids)) {
             $contribution->trxn_id = $ids['membership'][0] . CRM_Core_DAO::VALUE_SEPARATOR . $ids['related_contact'] . CRM_Core_DAO::VALUE_SEPARATOR . $ids['onbehalf_dupe_alert'];
         }
     }
     // CRM_Core_Error::debug_var( 'c', $contribution );
     $contribution->save();
     $transaction->commit();
     return TRUE;
 }
Пример #2
0
 /**
  * Updates contacts affected by the option value passed.
  *
  * @param int $optionValueId
  *   The option value id.
  * @param int $action
  *   The action describing whether prefix/suffix was UPDATED or DELETED.
  *
  * @return bool
  */
 public static function updateRecords(&$optionValueId, $action)
 {
     //finding group name
     $optionValue = new CRM_Core_DAO_OptionValue();
     $optionValue->id = $optionValueId;
     $optionValue->find(TRUE);
     $optionGroup = new CRM_Core_DAO_OptionGroup();
     $optionGroup->id = $optionValue->option_group_id;
     $optionGroup->find(TRUE);
     // group name
     $gName = $optionGroup->name;
     // value
     $value = $optionValue->value;
     // get the proper group name & affected field name
     // todo: this may no longer be needed for individuals - check inputs
     $individuals = array('gender' => 'gender_id', 'individual_prefix' => 'prefix_id', 'individual_suffix' => 'suffix_id', 'communication_style' => 'communication_style_id');
     $contributions = array('payment_instrument' => 'payment_instrument_id');
     $activities = array('activity_type' => 'activity_type_id');
     $participant = array('participant_role' => 'role_id');
     $eventType = array('event_type' => 'event_type_id');
     $aclRole = array('acl_role' => 'acl_role_id');
     $all = array_merge($individuals, $contributions, $activities, $participant, $eventType, $aclRole);
     $fieldName = '';
     foreach ($all as $name => $id) {
         if ($gName == $name) {
             $fieldName = $id;
         }
     }
     if ($fieldName == '') {
         return TRUE;
     }
     if (array_key_exists($gName, $individuals)) {
         $contactDAO = new CRM_Contact_DAO_Contact();
         $contactDAO->{$fieldName} = $value;
         $contactDAO->find();
         while ($contactDAO->fetch()) {
             if ($action == CRM_Core_Action::DELETE) {
                 $contact = new CRM_Contact_DAO_Contact();
                 $contact->id = $contactDAO->id;
                 $contact->find(TRUE);
                 // make sure dates doesn't get reset
                 $contact->birth_date = CRM_Utils_Date::isoToMysql($contact->birth_date);
                 $contact->deceased_date = CRM_Utils_Date::isoToMysql($contact->deceased_date);
                 $contact->{$fieldName} = 'NULL';
                 $contact->save();
             }
         }
         return TRUE;
     }
     if (array_key_exists($gName, $contributions)) {
         $contribution = new CRM_Contribute_DAO_Contribution();
         $contribution->{$fieldName} = $value;
         $contribution->find();
         while ($contribution->fetch()) {
             if ($action == CRM_Core_Action::DELETE) {
                 $contribution->{$fieldName} = 'NULL';
                 $contribution->save();
             }
         }
         return TRUE;
     }
     if (array_key_exists($gName, $activities)) {
         $activity = new CRM_Activity_DAO_Activity();
         $activity->{$fieldName} = $value;
         $activity->find();
         while ($activity->fetch()) {
             $activity->delete();
         }
         return TRUE;
     }
     //delete participant role, type and event type option value
     if (array_key_exists($gName, $participant)) {
         $participantValue = new CRM_Event_DAO_Participant();
         $participantValue->{$fieldName} = $value;
         if ($participantValue->find(TRUE)) {
             return FALSE;
         }
         return TRUE;
     }
     //delete event type option value
     if (array_key_exists($gName, $eventType)) {
         $event = new CRM_Event_DAO_Event();
         $event->{$fieldName} = $value;
         if ($event->find(TRUE)) {
             return FALSE;
         }
         return TRUE;
     }
     //delete acl_role option value
     if (array_key_exists($gName, $aclRole)) {
         $entityRole = new CRM_ACL_DAO_EntityRole();
         $entityRole->{$fieldName} = $value;
         $aclDAO = new CRM_ACL_DAO_ACL();
         $aclDAO->entity_id = $value;
         if ($entityRole->find(TRUE) || $aclDAO->find(TRUE)) {
             return FALSE;
         }
         return TRUE;
     }
 }
 function _process_csv($csv_array, $csv_name, $mail_date)
 {
     $this->_addToSummary("Processing {$csv_name}");
     foreach ($csv_array as $row) {
         $this->_addToSummary(null);
         // insert blank line.
         // check if this is a blank line
         if (count($row) <= 1) {
             continue;
         }
         $subscriptionId = $row[0];
         $subscriptionStatus = $row[1];
         $paymentNum = $row[2];
         $totalRecurrences = $row[3];
         $transactionId = $row[4];
         $amount = $row[5];
         $currency = $row[6];
         $custFirstName = $row[8];
         $custLastName = $row[9];
         $contributionStatus = $row[10];
         $recur = new CRM_Contribute_DAO_ContributionRecur();
         $first_contribution = new CRM_Contribute_DAO_Contribution();
         // If this is the first payment, load recurring contribution and update
         if ($paymentNum == 1) {
             // Load contribution using SubscriptionID as trxn_id
             $first_contribution->trxn_id = $subscriptionId;
             if (!$first_contribution->find(true)) {
                 $this->_addToSummary("THE RECURRING TRANSACTION FOR SUBSCRIPTION {$subscriptionId} COULD NOT BE FOUND. A TRANSACTION HAS OCCURED THAT WAS NOT EXPECTED.  PLEASE REVIEW {$csv_name}.");
                 continue;
             }
             // Load recurring contribution from contribution
             $recur->id = $first_contribution->contribution_recur_id;
             if (!$recur->find(true)) {
                 $this->_addToSummary("INITIAL RECURRING CONTRIBUTION NOT FOUND FOR {$subscriptionId}. PLEASE REVIEW {$csv_name}");
                 continue;
             }
             $recur->start_date = $mail_date;
             $recur->processor_id = $subscriptionId;
             $recur->trxn_id = $subscriptionId;
             $recur->contribution_status_id = _CRM_PROCESS_AUTHORIZE_REPORT_STATUS_CURRENT;
             // update transaction id for contribution
             $first_contribution->trxn_id = $transactionId;
             $first_contribution->receive_date = $mail_date;
             $first_contribution->contribution_status_id = $this->_get_contribution_status($contributionStatus);
             // load contribution page
             $contribution_page = new CRM_Contribute_DAO_ContributionPage();
             $contribution_page->id = $first_contribution->contribution_page_id;
             if (!$contribution_page->find(true)) {
                 $this->_addToSummary("COULD NOT FIND CONTRIBUTION PAGE FOR {$subscriptionId}. PLEASE REVIEW {$csv_name}");
                 continue;
             }
             // is there an email receipt
             if ($contribution_page->is_email_receipt) {
                 $first_contribution->receipt_date = date('YmdHis');
             }
         } else {
             $recur->processor_id = $subscriptionId;
             if (!$recur->find(true)) {
                 $this->_addToSummary("THE RECURRING TRANSACTION FOR SUBSCRIPTION {$subscriptionId} COULD NOT BE FOUND. A TRANSACTION HAS OCCURED THAT WAS NOT EXPECTED.  PLEASE REVIEW {$csv_name}.");
                 continue;
             }
             $recur->modified_date = $mail_date;
             // load first contribution
             $first_contribution->contribution_recur_id = $recur->id;
             $first_contribution->orderBy('receive_date');
             $first_contribution->limit(1);
             if (!$first_contribution->find(true)) {
                 $this->_addToSummary("CONTRIBUTION RECORD FOR SUBSCRIPTION {$subscriptonId} COULD NOT BE FOUND.  PLEASE REVIEW {$csv_name}");
                 continue;
             }
             // load contribution page
             $contribution_page = new CRM_Contribute_DAO_ContributionPage();
             $contribution_page->id = $first_contribution->contribution_page_id;
             if (!$contribution_page->find(true)) {
                 $this->_addToSummary("COULD NOT FIND CONTRIBUTION PAGE FOR {$subscriptionId}. PLEASE REVIEW {$csv_name}");
                 continue;
             }
         }
         // is this valid for failed transactions also?
         if ($amount != $recur->amount) {
             $this->_addToSummary("AN UNEXPECTED AMOUNT WAS RECEIVED FOR SUBSCRIPTION {$subscriptionId}. SKIPPING THIS TRANSACTION. PLEASE REVIEW {$csv_name}");
             continue;
         }
         // Verify contact exists
         if (!$recur->contact_id) {
             // assuming if contact_id is set, contact exists
             $this->_addToSummary("NO USER IS ASSOCIATED WITH THE CONTRIBUTION FOR SUBSCRIPTION {$subscrptionId}, EXPECTED '{$custFirstName} {$custLastName}'. PLEASE REVIEW {$csv_name}");
             continue;
         }
         // Verify number of recurrences
         if ($recur->installments != $totalRecurrences) {
             $this->_addToSummary("SUBSCRIPTION {$subscriptionId} EXPECTS {$recur->installments}, OFFERED {$totalRecurrences}. PLEASE REVIEW {$csv_name}");
             continue;
         }
         // Check if this contribution is complete
         if (!empty($recur->end_date) && $recur->end_date != '0000-00-00 00:00:00') {
             $this->_addToSummary("SUBSCRIPTION {$subscriptionId} IS MARKED AS COMPLETE. PLEASE REVIEW {$csv_name}");
             continue;
         }
         if (!empty($recur->cancel_date) && $recur->cancel_date != '0000-00-00 00:00:00') {
             $this->_addToSummary("SUBSCRIPTION {$subscriptionId} IS MARKED AS CANCELLED. PLEASE REVIEW {$csv_name}");
             continue;
         }
         if ($paymentNum == $totalRecurrences) {
             $recur->end_date = $mail_date;
             $recur->contribution_status_id = _CRM_PROCESS_AUTHORIZE_REPORT_STATUS_COMPLETE;
         }
         if ($contributionStatus != CRM_Core_Payment_AuthorizeNet::AUTH_APPROVED) {
             $recur->failure_count++;
         }
         CRM_Core_DAO::transaction('BEGIN');
         if (!$recur->save()) {
             $this->_addToSummary("THE RECURRING CONTRIBUTION COULD NOT BE UPDATED. PLEASE REVIEW {$csv_name} FOR subscription_id={$subscription_id}");
             CRM_Core_DAO::transaction('ROLLBACK');
             continue;
         }
         $this->_addToSummary("The recurring transaction has been updated.");
         if ($paymentNum == 1) {
             // update first contribution
             if (!$first_contribution->save()) {
                 $this->_addToSummary("THE CONTRIBUTION COULD NOT BE UPDATED. PLEASE REVIEW {$csv_name} FOR subscription_id={$subscription_id}");
                 CRM_Core_DAO::transaction('ROLLBACK');
                 continue;
             }
             // copy $first_contribution to $contribution for use later
             $contribution = $first_contribution;
         } else {
             // create a contribution and then get it processed
             $contribution = new CRM_Contribute_DAO_Contribution();
             // make sure that the transaction doesn't already exist
             $contribution->trxn_id = $transactionId;
             if ($contribution->find()) {
                 $this->_addToSummary("THE TRANSACTION {$transaction_id} ALREADY EXISTS IN CIVICRM. PLEASE REVIEW {$csv_name} FOR subscription_id={$subscription_id}");
                 CRM_Core_DAO::transaction('ROLLBACK');
                 continue;
             }
             $contribution->contribution_recur_id = $recur->id;
             $contribution->receive_date = $mail_date;
             $contribution->total_amount = $amount;
             $contribution->net_amount = $amount;
             $contribution->trxn_id = $transactionId;
             $contribution->currency = $currency;
             $contribution->contribution_status_id = $this->_get_contribution_status($contributionStatus);
             $contribution->contact_id = $first_contribution->contact_id;
             $contribution->contribution_type_id = $first_contribution->contribution_type_id;
             $contribution->contribution_page_id = $first_contribution->contribution_page_id;
             $contribution->payment_instrument_id = $first_contribution->payment_instrument_id;
             $contribution->is_test = $first_contribution->is_test;
             $contribution->invoice_id = md5(uniqid(rand(), true));
             if ($contribution_page->is_email_receipt) {
                 $contribution->receipt_date = date('YmdHis');
             }
             if (!$contribution->save()) {
                 $this->_addToSummary("THE CONTRIBUTION COULD NOT BE SAVED. PLEASE REVIEW {$csv_name} FOR subscription_id={$subscription_id}");
                 CRM_Core_DAO::transaction('ROLLBACK');
                 continue;
             }
         }
         $this->_addToSummary('Contribution saved');
         // create the transaction record
         $trxnParams = array('entity_table' => 'civicrm_contribution', 'entity_id' => $contribution->id, 'trxn_date' => $mail_date, 'trxn_type' => 'Debit', 'total_amount' => $amount, 'fee_amount' => $contribution->fee_amount, 'net_amount' => $contribution->net_amount, 'currency' => $contribution->currency, 'payment_processor' => 'AuthNet_AIM', 'trxn_id' => $contribution->trxn_id);
         require_once 'CRM/Contribute/BAO/FinancialTrxn.php';
         $trxn =& CRM_Contribute_BAO_FinancialTrxn::create($trxnParams);
         if (is_a($trxn, 'CRM_Core_Error')) {
             $this->_addToSummary("A TRANSACTION RECORD COULD NOT BE CREATED. PLEASE REVIEW {$csv_name} FOR subscription_id={$subscription_id}");
             CRM_Core_DAO::transaction('ROLLBACK');
             continue;
         } else {
             $this->_addToSummary("Transaction record created.");
         }
         // get the title of the contribution page
         $title = $contribution_page->title;
         // format the money
         require_once 'CRM/Utils/Money.php';
         $formattedAmount = CRM_Utils_Money::format($amount, $contribution->currency);
         CRM_Core_DAO::transaction('COMMIT');
         // get the contribution type
         require_once 'CRM/Contribute/BAO/ContributionType.php';
         $contribution_type_name = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionType', $contribution->contribution_type_id, 'name');
         // create an activity history record
         $ahParams = array('entity_table' => 'civicrm_contact', 'entity_id' => $recur->contact_id, 'activity_type' => $contribution_type_name, 'module' => 'CiviContribute', 'callback' => 'CRM_Contribute_Page_Contribution::details', 'activity_id' => $contribution->id, 'activity_summary' => "{$formattedAmount} - {$title} (online)", 'activity_date' => $mail_date);
         require_once 'api/History.php';
         if (is_a(crm_create_activity_history($ahParams), 'CRM_Core_Error')) {
             $this->_addToSummary("AN ACTIVITY HISTORY RECORD COULD NOT BE CREATED.");
         } else {
             $this->_addToSummary("Activity History record created.");
         }
         $this->_addToSummary("Transaction {$transactionId} has been processed.");
         $first_contribution->free();
         $contribution_page->free();
         $contribution->free();
         $recur->free();
         $trxn->free();
     }
     $this->_addToSummary("Done processing {$csv_name}");
     $this->_addToSummary('');
 }