예제 #1
0
 /**
  * This will process a report text file as taken from PayPal.  This will create any applicable PaypalBatch entries
  * and correlate with existing CreditCardPayment records.  This will *only* process "Delayed Capture" transactions,
  * since that's all we actually care about.  This will create "as unlinked" any CreditCardPayment records that had
  * to be created because it didn't exist (which means that this is a bad thing -- we should not have any of those).
  * 
  * If there are any issues with importing, this will throw an error
  * 
  * @param string $strReportText the text of the report itself from paypal
  * @param integer $intEntriesModified return value of the number of entries that were modified
  * @param integer $intEntriesAdded return value of the number of entries that were created (hopefully shouuld be zero)
  * @throws QCallerException
  */
 public static function ProcessReport($strReportText, &$intEntriesModified, &$intEntriesAdded)
 {
     $intEntriesModified = 0;
     $intEntriesAdded = 0;
     // Cleanup Linebreaks
     $strReportText = str_replace("\r", "\n", $strReportText);
     while (strpos($strReportText, "\n\n") !== false) {
         $strReportText = str_replace("\n\n", "\n", $strReportText);
     }
     $strReportText = trim($strReportText);
     // Pull out the First Line (column headers) from the rest of the report
     $intPosition = strpos($strReportText, "\n");
     $strFirstLine = substr($strReportText, 0, $intPosition);
     $strReportText = substr($strReportText, $intPosition + 1);
     // Calculate the tokens
     $strTokenArray = array();
     $intColumnIndex = 0;
     foreach (explode("\t", $strFirstLine) as $strToken) {
         if (array_key_exists($strToken, $strTokenArray)) {
             throw new QCallerException('Report has a duplicate column: ' . $strToken);
         }
         $strTokenArray[$strToken] = $intColumnIndex;
         $intColumnIndex++;
     }
     // Ensure that the required fields exist
     foreach (self::$RequiredFields as $strRequiredToken) {
         if (!array_key_exists($strRequiredToken, $strTokenArray)) {
             throw new QCallerException('Report is missing required column: ' . $strRequiredToken);
         }
     }
     // Go through each line of the report
     foreach (explode("\n", $strReportText) as $strLine) {
         // Break out all cells, and then create a specific Values array that contain only the cells we care about, indexed by name
         $strCellArray = explode("\t", $strLine);
         $strValuesArray = array();
         foreach (self::$RequiredFields as $strRequiredToken) {
             $strValuesArray[$strRequiredToken] = $strCellArray[$strTokenArray[$strRequiredToken]];
         }
         // Only process "Delayed Capture"
         if ($strValuesArray['Type'] == 'Delayed Capture') {
             if (strlen(trim($strValuesArray[self::PayPalOriginalTransactionId])) == 0) {
                 throw new QCallerException('Transaction ' . $strValuesArray[self::PayPalTransactionId] . ' does not have an Original Transaction Id');
             }
             // Can we find the linked CCPayment Record?
             $objCreditCardPayment = CreditCardPayment::LoadByTransactionCode($strValuesArray[self::PayPalOriginalTransactionId]);
             if (!$objCreditCardPayment) {
                 // No -- let's create this as an UNLINKED one
                 $intEntriesAdded++;
                 $objCreditCardPayment = new CreditCardPayment();
                 $objCreditCardPayment->TransactionCode = $strValuesArray[self::PayPalOriginalTransactionId];
                 $objCreditCardPayment->CreditCardStatusTypeId = CreditCardStatusType::Captured;
                 $objCreditCardPayment->CreditCardLastFour = substr($strValuesArray[self::PayPalAccountNumber], strlen($strValuesArray[self::PayPalAccountNumber]) - 4);
                 foreach (CreditCardType::$NameArray as $intId => $strName) {
                     if (strtolower($strName) == strtolower($strValuesArray[self::PayPalTenderType])) {
                         $objCreditCardPayment->CreditCardTypeId = $intId;
                     }
                 }
                 if (!$objCreditCardPayment->CreditCardTypeId) {
                     throw new QCallerException('Unlinked transaction contains an unknown credit card type: ' . $strValuesArray[self::PayPalTenderType]);
                 }
                 $objCreditCardPayment->UnlinkedFlag = true;
                 // Setup Fields
                 $objCreditCardPayment->AuthorizationCode = $strValuesArray[self::PayPalAuthCode];
                 $objCreditCardPayment->AmountCharged = $strValuesArray[self::PayPalAmount];
             }
             // Link in the Pay Pal Batch Info (if applicable)
             //					if (SERVER_INSTANCE == 'dev') $strValuesArray[self::PayPalBatchId] = 789;
             if ($intBatchNumber = trim($strValuesArray[self::PayPalBatchId])) {
                 $objPayPalBatch = PaypalBatch::LoadByNumber($intBatchNumber);
                 if (!$objPayPalBatch) {
                     $objPayPalBatch = new PaypalBatch();
                     $objPayPalBatch->Number = $intBatchNumber;
                     $objPayPalBatch->DateReceived = new QDateTime($strValuesArray[self::PayPalSettledDate]);
                     $objPayPalBatch->ReconciledFlag = false;
                     $objPayPalBatch->Save();
                 }
                 if ($objCreditCardPayment->PaypalBatchId != $objPayPalBatch->Id) {
                     $objCreditCardPayment->PaypalBatch = $objPayPalBatch;
                     if ($objCreditCardPayment->Id) {
                         $intEntriesModified++;
                     }
                 }
             } else {
                 if (!is_null($objCreditCardPayment->PaypalBatchId)) {
                     $objCreditCardPayment->PaypalBatch = null;
                     if ($objCreditCardPayment->Id) {
                         $intEntriesModified++;
                     }
                 }
             }
             // TODO: How do we account fo a "reconciled" PayPal batch that unexpectatly received another transaction not previously accounted for?
             // Check Fields to ensure match
             if ($objCreditCardPayment->AuthorizationCode != $strValuesArray[self::PayPalAuthCode]) {
                 throw new QCallerException(sprintf('Mismatch AuthCode for Transaction %s: %s vs. %s', $strValuesArray[self::PayPalOriginalTransactionId], $strValuesArray[self::PayPalAuthCode], $objCreditCardPayment->AuthorizationCode));
             }
             if ($objCreditCardPayment->AmountCharged != str_replace(',', '', $strValuesArray[self::PayPalAmount])) {
                 throw new QCallerException(sprintf('Mismatch Amount for Transaction %s: %s vs. %s', $strValuesArray[self::PayPalOriginalTransactionId], $strValuesArray[self::PayPalAmount], $objCreditCardPayment->AmountCharged));
             }
             // Update Fields
             $objCreditCardPayment->DateCaptured = new QDateTime($strValuesArray[self::PayPalTime]);
             $objCreditCardPayment->Save();
         }
     }
 }