/**
  * @param int $pledgeID
  * @param $actualAmount
  * @param $pledgeScheduledAmount
  * @param int $paymentContributionId
  * @param int $pPaymentId
  * @param int $paymentStatusID
  */
 public static function adjustPledgePayment($pledgeID, $actualAmount, $pledgeScheduledAmount, $paymentContributionId = NULL, $pPaymentId = NULL, $paymentStatusID = NULL)
 {
     $allStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
     if ($paymentStatusID == array_search('Cancelled', $allStatus) || $paymentStatusID == array_search('Refunded', $allStatus)) {
         $query = "\nSELECT civicrm_pledge_payment.id id\nFROM  civicrm_pledge_payment\nWHERE civicrm_pledge_payment.contribution_id = {$paymentContributionId}\n";
         $paymentsAffected = CRM_Core_DAO::executeQuery($query);
         $paymentIDs = array();
         while ($paymentsAffected->fetch()) {
             $paymentIDs[] = $paymentsAffected->id;
         }
         // Reset the affected values by the amount paid more than the scheduled amount
         foreach ($paymentIDs as $key => $value) {
             $payment = new CRM_Pledge_DAO_PledgePayment();
             $payment->id = $value;
             if ($payment->find(TRUE)) {
                 $payment->contribution_id = 'null';
                 $payment->status_id = array_search('Pending', $allStatus);
                 $payment->scheduled_date = NULL;
                 $payment->reminder_date = NULL;
                 $payment->scheduled_amount = $pledgeScheduledAmount;
                 $payment->actual_amount = 'null';
                 $payment->save();
             }
         }
         // Cancel the initial paid amount
         CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', reset($paymentIDs), 'status_id', $paymentStatusID, 'id');
         CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', reset($paymentIDs), 'actual_amount', $actualAmount, 'id');
         // Add new payment after the last payment for the pledge
         $allPayments = self::getPledgePayments($pledgeID);
         $lastPayment = array_pop($allPayments);
         $pledgeFrequencyUnit = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_Pledge', $pledgeID, 'frequency_unit', 'id');
         $pledgeFrequencyInterval = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_Pledge', $pledgeID, 'frequency_interval', 'id');
         $pledgeScheduledDate = $lastPayment['scheduled_date'];
         $scheduled_date = CRM_Utils_Date::processDate($pledgeScheduledDate);
         $date['year'] = (int) substr($scheduled_date, 0, 4);
         $date['month'] = (int) substr($scheduled_date, 4, 2);
         $date['day'] = (int) substr($scheduled_date, 6, 2);
         $newDate = date('YmdHis', mktime(0, 0, 0, $date['month'], $date['day'], $date['year']));
         $ScheduledDate = CRM_Utils_Date::format(CRM_Utils_Date::intervalAdd($pledgeFrequencyUnit, $pledgeFrequencyInterval, $newDate));
         $pledgeParams = array('status_id' => array_search('Pending', $allStatus), 'pledge_id' => $pledgeID, 'scheduled_amount' => $pledgeScheduledAmount, 'scheduled_date' => $ScheduledDate);
         $payment = self::add($pledgeParams);
     } else {
         $oldestPayment = self::getOldestPledgePayment($pledgeID);
         if (!$paymentContributionId) {
             // means we are editing payment scheduled payment, so get the second pending to update.
             $oldestPayment = self::getOldestPledgePayment($pledgeID, 2);
             if ($oldestPayment['count'] != 1 && $oldestPayment['id'] == $pPaymentId) {
                 $oldestPayment = self::getOldestPledgePayment($pledgeID);
             }
         }
         if ($oldestPayment) {
             // not the last scheduled payment and the actual amount is less than the expected , add it to oldest pending.
             if ($actualAmount != $pledgeScheduledAmount && ($actualAmount < $pledgeScheduledAmount || $actualAmount - $pledgeScheduledAmount < $oldestPayment['amount'])) {
                 $oldScheduledAmount = $oldestPayment['amount'];
                 $newScheduledAmount = $oldScheduledAmount + ($pledgeScheduledAmount - $actualAmount);
                 // store new amount in oldest pending payment record.
                 CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', $oldestPayment['id'], 'scheduled_amount', $newScheduledAmount);
                 if (CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_PledgePayment', $oldestPayment['id'], 'contribution_id', 'id')) {
                     CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', $oldestPayment['id'], 'contribution_id', $paymentContributionId);
                 }
             } elseif ($actualAmount > $pledgeScheduledAmount && $actualAmount - $pledgeScheduledAmount >= $oldestPayment['amount']) {
                 // here the actual amount is greater than expected and also greater than the next installment amount, so update the next installment as complete and again add it to next subsequent pending payment
                 // set the actual amount of the next pending to '0', set contribution Id to current contribution Id and status as completed
                 $paymentId = array($oldestPayment['id']);
                 self::updatePledgePayments($pledgeID, array_search('Completed', $allStatus), $paymentId, 0, $paymentContributionId);
                 CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', $oldestPayment['id'], 'scheduled_amount', 0, 'id');
                 $oldestPayment = self::getOldestPledgePayment($pledgeID);
                 if (!$paymentContributionId) {
                     // means we are editing payment scheduled payment.
                     $oldestPaymentAmount = self::getOldestPledgePayment($pledgeID, 2);
                 }
                 $newActualAmount = $actualAmount - $pledgeScheduledAmount;
                 $newPledgeScheduledAmount = $oldestPayment['amount'];
                 if (!$paymentContributionId) {
                     $newActualAmount = $actualAmount - $pledgeScheduledAmount;
                     $newPledgeScheduledAmount = $oldestPaymentAmount['amount'];
                     // means we are editing payment scheduled payment, so update scheduled amount.
                     CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_PledgePayment', $oldestPaymentAmount['id'], 'scheduled_amount', $newActualAmount);
                 }
                 if ($newActualAmount > 0) {
                     self::adjustPledgePayment($pledgeID, $newActualAmount, $newPledgeScheduledAmount, $paymentContributionId);
                 }
             }
         }
     }
 }
 /**
  * On delete contribution record update associated pledge payment and pledge.
  *
  * @param int $contributionID  contribution id
  *
  * @access public
  * @static
  */
 static function resetPledgePayment($contributionID)
 {
     //get all status
     $allStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
     $transaction = new CRM_Core_Transaction();
     $payment = new CRM_Pledge_DAO_PledgePayment();
     $payment->contribution_id = $contributionID;
     if ($payment->find(TRUE)) {
         $payment->contribution_id = 'null';
         $payment->status_id = array_search('Pending', $allStatus);
         $payment->scheduled_date = NULL;
         $payment->reminder_date = NULL;
         $payment->save();
         //update pledge status.
         $pledgeID = $payment->pledge_id;
         $pledgeStatusID = self::calculatePledgeStatus($pledgeID);
         CRM_Core_DAO::setFieldValue('CRM_Pledge_DAO_Pledge', $pledgeID, 'status_id', $pledgeStatusID);
         $payment->free();
     }
     $transaction->commit();
     return TRUE;
 }