<?php

/**
 * Payment block content callback function
 */
function _fernweh_alter_payment_block_content($order_id, $lead_id) {

  $output = "";
  if (!empty($order_id) && is_numeric($order_id) && !empty($lead_id) && is_numeric($lead_id)) {
    $view_list = "";


    $header = array('Date', 'MOP', 'Remarks', 'Type', 'Amount');
    $data = array();


    // Load service cost of product
    //$product = commerce_product_load($lead_id);
    //$total_amount = ($product->field_lead_service_flight_cost)? $product->field_lead_service_flight_cost["und"][0]["value"]:0;
    $order = commerce_order_load($order_id);

    $total_amount = ($order->field_order_service_cost) ? $order->field_order_service_cost["und"][0]["value"] : 0;
    //var_dump($order);exit();
    $net_paid_amount = 0;
    $results = fernweh_get_payments($order_id);
    if ($results) {
      foreach ($results as $row) {
        $payment = node_load($row->entity_id);
        // If status is equal to 0, payment is deleted then filter out
        if ($payment->status != 0) {
          $date = !empty($payment->field_payment_date) ? $payment->field_payment_date[LANGUAGE_NONE][0]['value'] : "";
          $mode = !empty($payment->field_payment_mode) ? $payment->field_payment_mode[LANGUAGE_NONE][0]['value'] : "";

          $payment_type = !empty($payment->field_payment_type) ? $payment->field_payment_type[LANGUAGE_NONE][0]['value'] : "";

          $detail = !empty($payment->field_payment_detail) ? $payment->field_payment_detail[LANGUAGE_NONE][0]['value'] : "";
          $paid = !empty($payment->field_payment_amount_paid) ? $payment->field_payment_amount_paid[LANGUAGE_NONE][0]['value'] : "";
          if (!empty($payment->field_payment_type[LANGUAGE_NONE][0]['value']) && $payment->field_payment_type[LANGUAGE_NONE][0]['value'] == 1) { // 1- Amount paid against order
            $net_paid_amount += is_numeric($paid) ? $paid : 0;
            $payment_type = "Payment";
          }
          elseif (!empty($payment->field_payment_type[LANGUAGE_NONE][0]['value']) && $payment->field_payment_type[LANGUAGE_NONE][0]['value'] == 2) { // 2- Amount refund against order
            $net_paid_amount -= is_numeric($paid) ? $paid : 0;
            $payment_type = "Refund";
          }
          $date = date('d-M-Y', strtotime($date));
          $basepath = base_path();
          // Generate edit and delete action links for popup
          //$delete_button = '<a href="' . $basepath . 'popup/nojs/payment/' . $row->entity_id . '/delete" title="Delete Payment" class="ctools-use-modal ctools-modal-fernweh-delete-style fn-delete">Delete Payment</a>';
          //$edit_button = '<a href="' . $basepath . 'popup/nojs/payment/' . $row->entity_id . '/edit/order/' . $order_id . '" title="Edit Payment" class="ctools-use-modal ctools-modal-fernweh-confirm-style fn-edit">Edit Payment</a>';
          $action = ""; //$edit_button . ' | ' . $delete_button;
          if (function_exists('inr_money_format')) {
            $paid = inr_money_format($paid);
          }
          $data[] = array($date, $mode, $detail, $payment_type, $paid);
        }
      }

      // data is empty its means no payment record available then don't render empty table
      if (!empty($data)) {
        $view_list = theme('table', array('header' => $header, 'rows' => $data));
      }
      else {
        //$view_list = '<div class="row payment-list-info"><div class="alert alert-info" role="alert">No payment transaction available</div></div>';
        $view_list = '<div class="row payment-list-info"><div class="alert alert-info" role="alert">' . t('Payment transaction available on account page.') . '</div></div>';
      }
    }
    $total_due_amount = ($total_amount - $net_paid_amount);
    if (function_exists('inr_money_format')) {
      $total_amount = inr_money_format($total_amount);
      $total_due_amount = inr_money_format($total_due_amount);
    }


    // view - Generate HTML mark
    $output .= '<div class="section-wrapper">';
    $output .= '<div class="left-section-wrapper">'
        . '<h3 class="section-title">Payment Details</h3>'
        . '<div class="amt-wrapper">'
        . '<div class="amt-box"><span class="box-title">Total Amount</span><span class="box-value red-text"> ' . $total_amount . ' </span></div>'
        . '<div class="amt-box"><span class="box-title">Amount Due</span><span class="box-value green-text"> ' . $total_due_amount . ' </span></div>'
        . '</div>'
        . '</div>';
    $output .= '<div class="right-section-wrapper">';
    $button = ""; //ctools_modal_text_button(t('Make Payment'), 'popup/nojs/payment/add/order/' . $order_id, t('Make Payment'), 'add-plus ctools-modal-fernweh-confirm-style add-plus');
    $output .= '<div class="section-row"><h3 class="float-left">Payment</h3> ' . $button . ' </div>';
    $output .= '<div class="view-list-wrapper">' . $view_list . '</div>';
    $output .= '</div>';
    $output .= '</div>';
  }

  // Return HTML view
  return $output;
}

/**
 * Implements hook_form_form_id_alter()
 * @param type $form
 * @param type $form_state
 * @param type $form_id
 */
function fernweh_alter_form_payment_node_form_alter(&$form, &$form_state, $form_id) {

  $form['title']['#default_value'] = 'Payment for order';
  hide($form['title']);
  hide($form['field_payment_entity_reference']); // Payment against order entity ref
  hide($form['field_payment_account_entity_ref']);  // Payment against account entity ref
  $form['field_payment_amount_paid'][LANGUAGE_NONE][0]['value']['#attributes']['class'][] = 'cost-inr';
  // If order and order's lead don't associated with any account
  $order_id = NULL;
  if (arg(4) == "order" || arg(5) == "order") {
    $order_id = 0;
    if (arg(3) == "add" && is_numeric(arg(5))) { // Order page payment add
      $order_id = arg(5);
    }
    elseif (is_numeric(arg(3)) && arg(4) == "edit" && is_numeric(arg(6))) { // Order page payment edit
      $order_id = arg(6);
      // On payment edit don't allow edit payment type and payment mode
      $form['field_payment_mode']['#disabled'] = TRUE;
      $form['field_payment_type']['#disabled'] = TRUE;
    }
  }
  elseif (isset($_POST['field_payment_order_id']) && is_numeric($_POST['field_payment_order_id'])) { // Order payment field is set
    $order_id = $_POST['field_payment_order_id'];
  }
  else {
    $order_id = NULL;
  }
  // If we have order id
  $account = FALSE;
  $account_id = NULL;
  if (!empty($order_id) && is_numeric($order_id)) { // Get account associated with order
    hide($form['field_payment_status']);
    hide($form['field_payment_type']);
    hide($form['field_payment_mode']);

    $account_id = fernweh_get_account_id($order_id);
    $form['field_payment_order_id'] = array(// Create order id field to retain order id
      '#type' => 'hidden',
      '#title' => t(''),
      '#value' => $order_id
    );
    if (is_numeric($account_id)) {
      // Account
      // Pass extra data to form
      $form['field_payment_account_id'] = array(// Create account id field to retain account id
        '#type' => 'hidden',
        '#title' => t(''),
        '#value' => $account_id
      );
      $account = TRUE;
    }
  }

  //If order doesn't have account OR (If direct deposit to account, remove payment mode type account - Add & edit)
  if (!$account && ((arg(3) == "add" && arg(4) == "card") || ( is_numeric(arg(3)) && arg(4) == "edit" && arg(5) == "card" ))) {
    unset($form['field_payment_mode'][LANGUAGE_NONE]['#options']['Account']);
  }

  if (!empty($order_id)) {
    // On Payment mode change ajax event
    $form['field_payment_mode'][LANGUAGE_NONE]['#ajax'] = array(
      'event' => 'change',
      'callback' => '_fernweh_payment_ajax_callback',
      'wrapper' => 'payment_form_wrapper',
      'method' => 'replace',
      'parameter' => array('orderid' => $order_id, 'accountid' => $account_id)
    );
  }
  else {
    // Call from account
    // If account page payment hide payment type select list
    hide($form['field_payment_type']);
  }

  // Wrap Form
  $form['#prefix'] = '<div id="payment_form_wrapper">';
  $form['#suffix'] = '</div>';

  if (arg(0) == "node" && arg(1) == "add" && arg(2) == "payment") {
    drupal_set_title(t('Make Payment'));
  }
  $form['group_access'][LANGUAGE_NONE]['#default_value'] = 1;
  $form['group_access']['#attributes']['class'][] = 'element-hidden';
  hide($form['actions']['delete']);
  $form['actions']['cancel'] = array(
    '#markup' => l(t('Cancel'), '#', array('attributes' => array('class' => 'fn-btn-cancel modal-cancel-btn ctools-close-modal'))),
    '#weight' => -11,
      //'#submit' => array('fernweh_payment_submit'),
  );

  // If service amount is zero
  if (!empty($order_id)) {
    $order = commerce_order_load($order_id);
    $service_cost = $order->field_order_service_cost[LANGUAGE_NONE][0]["value"];
    $form['#validate'][] = "fernweh_payment_form_validate";

    $net_paid_amount = 0;
    $results = fernweh_get_payments($order_id);
    if ($results) {
      foreach ($results as $row) {
        $payment = node_load($row->entity_id);
        // If status is equal to 0, payment is deleted then filter out
        if ($payment->status != 0) {
          $paid = !empty($payment->field_payment_amount_paid) ? $payment->field_payment_amount_paid[LANGUAGE_NONE][0]['value'] : "";
          if (isset($payment->field_payment_type[LANGUAGE_NONE][0]['value']) && $payment->field_payment_type[LANGUAGE_NONE][0]['value'] == 1) {
            $net_paid_amount += is_numeric($paid) ? $paid : 0;
          }
          elseif (isset($payment->field_payment_type[LANGUAGE_NONE][0]['value']) && $payment->field_payment_type[LANGUAGE_NONE][0]['value'] == 2) {
            $net_paid_amount -= is_numeric($paid) ? $paid : 0;
          }
        }
      }
    }

    $balance_amount = $service_cost - $net_paid_amount;

    if (empty($balance_amount) && arg(4) != "edit") {
      hide($form['field_payment_detail']);
      hide($form['field_payment_date']);
      hide($form['field_payment_mode']);
      hide($form['field_payment_amount_paid']);
      hide($form['field_payment_detail']);
      hide($form['field_payment_type']);
      hide($form['field_payment_status']);
      unset($form['actions']['submit']);
      unset($form['actions']['cancel']);
      $form['message_alert'] = array(
        '#markup' => '<div class="alert alert-warning"><p><strong>Sorry!</strong> You can not pay more than order due amount.</p>
                </div>'
      );
    }
  }

// -------------- Account Payment form alter -------------------
  hide($form['field_payment_card_reference']);

// Account has all order pending or payment not completed
  if (arg(4) == "account" || arg(5) == "account") {

    $account_id = Null;
    if ((arg(3) == "add") && is_numeric(arg(5))) {
      $account_id = arg(5);

      $form ['choose_payment_type'] = array(
        '#type' => 'radios',
        '#title' => t('Payment To'),
        '#default_value' => 0,
        '#options' => array(t('Account'), t('Order')),
      );
    }
    elseif (is_numeric(arg(3)) && arg(4) == "edit") {
      $account_id = arg(3);
    }
    hide($form['field_payment_status']);
    $account_node = node_load($account_id);
    $outstanding_bal = $account_node->field_account_available_amount["und"][0]["value"];
    $outstanding_bal_value = 0;
    if ($outstanding_bal > 0) {
      $outstanding_bal_value = $outstanding_bal;
    }
    $form['account_outstanding_bal'] = array(// Create order id field to retain order id
      '#type' => 'hidden',
      '#title' => t(''),
      '#value' => abs($outstanding_bal_value),
      '#attributes' => array('data-amount' => array(inr_money_format(abs($outstanding_bal_value))))
    );


    //$orders = fernweh_get_orders_of_account($account_id);
    $orders = fernweh_get_all_orders_by_account($account_id);
    $data = array();
    foreach ($orders as $order) {
      $service_cost_amount = ($order->field_order_service_cost) ? $order->field_order_service_cost["und"][0]["value"] : 0;
      $paid_amount = fernweh_get_order_paid_amount($order->order_id);
      if ($paid_amount < $service_cost_amount) {
        $data[] = array(
          'order_id' => $order->order_id,
          'global_id' => $order->field_global_id[LANGUAGE_NONE][0]['value'],
          'amount' => inr_money_format($service_cost_amount),
          'due_amount' => inr_money_format($service_cost_amount - $paid_amount)
        );
      }
    }
    $header = array(
      'global_id' => "Order ID",
//      'name' => "Name",
      'amount' => "Service Cost",
      'due_amount' => "Due"
    );
    $options = array();
    if (empty($data)) {
      unset($form['choose_payment_type']['#options'][1]);
    }
    foreach ($data as $ord) {
      $options[$ord['order_id']] = array(
        'global_id' => l($ord['global_id'], 'order/' . $ord['order_id'] . '/details'),
//        'name' => $ord['name'],
        'amount' => $ord['amount'],
        'due_amount' => $ord['due_amount']
      );
    }
    if ((arg(3) == "add") && is_numeric(arg(5))) {
      $form['orders'] = array(
        '#type' => 'tableselect',
        '#header' => $header,
        '#options' => $options,
        '#empty' => t('No orders found.'),
        '#weight' => 11,
        '#attributes' => array('class' => array("order-table-list"))
      );
    }
    $form['actions']['submit']['#submit'][] = 'fernweh_payment_form_submit';
  }

  if (arg(4) == "card" || arg(5) == "card") {
    $form['actions']['submit']['#submit'][] = 'fernweh_payment_form_submit';
    unset($form['field_payment_status'][LANGUAGE_NONE]['#options']['_none']);
    // if edit
    if (arg(4) == "edit") {
      if ($form['field_payment_status'][LANGUAGE_NONE]['#default_value'][0] == "complete") {
        $form['field_payment_status']['#attributes']['style'] = 'pointer-events:none;';
      }
    }
  }
}

/**
 *  // ======================== Payment form submit from account page ================== /
 */
function fernweh_payment_form_submit(&$form, &$form_state) {

  if ((arg(3) == "add") && is_numeric(arg(5))) {
    $payment_for = arg(4);

    if ($payment_for == "account") {
      $account_id = arg(5);
      $orders = $form_state['values']['orders'];
      $form_amount = $form_state['values']['field_payment_amount_paid'][LANGUAGE_NONE][0]["value"];
      $orders = array_filter($orders, function($item) {
        return !empty($item);
      });
      if (count($orders) > 0) {
        foreach ($orders as $order_id) {
          $order = commerce_order_load($order_id);
          $service_cost = isset($order->field_order_service_cost["und"][0]["value"]) ? $order->field_order_service_cost["und"][0]["value"] : 0;
          $paid_amount = fernweh_get_order_paid_amount($order_id); //($order->field_order_paid_amount) ? $order->field_order_paid_amount["und"][0]["value"] : 0;
          $pendding_amount = $service_cost - $paid_amount;
          if ($pendding_amount > 0 && $service_cost > 0 && $form_amount > 0) {
            // Create payment against order full
            $amount_paid_to_order = 0;
            if ($form_amount > $pendding_amount) {
              $amount_paid_to_order = $pendding_amount;
              $form_amount = $form_amount - $pendding_amount;
            }
            elseif ($form_amount <= $pendding_amount) {
              $amount_paid_to_order = $form_amount;
              $form_amount = 0;
            }
            $node = new stdClass();
            $node->type = 'payment';
            node_object_prepare($node);
            $node->title = 'Payment from Order ID ' . $order_id;
            $node->status = 1;
            $node->promote = 0;
            $node->comment = 0;
            $node->language = LANGUAGE_NONE;
            $node->field_payment_date[LANGUAGE_NONE][0] = array(
              'value' => date('Y-m-d H:i:s', strtotime('now')),
              'timezone' => 'UTC',
              'timezone_db' => 'UTC',
            );
            $node->field_payment_type[$node->language][0]['value'] = 1;
            $node->field_payment_mode[$node->language][0]['value'] = $form_state['values']['field_payment_mode'][LANGUAGE_NONE][0]["value"];
            $node->field_payment_amount_paid[$node->language][0]['value'] = $amount_paid_to_order;
            $node->field_payment_entity_reference[$node->language][0]['target_id'] = $order_id;
            $node->field_payment_account_entity_ref[$node->language][0]['target_id'] = $account_id;
            $node->field_payment_status[$node->language][0]['value'] = "complete";
            $node = node_submit($node);
            node_save($node);

            $order->field_order_paid_amount[LANGUAGE_NONE][0]["value"] = $paid_amount + (float) $amount_paid_to_order;
            if (function_exists(_change_order_status)) {
              $order = _change_order_status($order);
            }

            commerce_order_save($order);

            $account_id = arg(5); // Account page, add balance
            if (is_numeric($account_id)) {
              // Add credit amount from outstanding balance
              $account = node_load($account_id);
              //$account_outstanding_balance = $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'];
              //$payment_mode = $form_state['values']['field_payment_mode'][LANGUAGE_NONE][0]["value"];
              //if($payment_mode == "Account" ){
              //  $net_outstanding_balance = $account_outstanding_balance + (float)$amount_paid_to_order;
              //}else{
              //  $net_outstanding_balance = $account_outstanding_balance - (float)$amount_paid_to_order;
              //}
              //$account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'] =  $net_outstanding_balance;
              // Update outstanding
              $account->field_account_available_amount[LANGUAGE_NONE][0]['value'] = $account->field_account_available_amount[LANGUAGE_NONE][0]['value'] - (float) $amount_paid_to_order;
              // JOSEPH
              db_update('node')->fields(array('changed' => time()))->condition('nid', $account->nid, '=')->execute();
              // JOSEPH
              field_attach_update('node', $account);
            }
          }
          else {
            break;
          }
        }
        // No transaction for amount from account
        $form_amount = 0;
      }

      if ($form_amount > 0) {
        // No order to pay "Account"
        $entity_id = $form_state["nid"];
        if (!empty($entity_id)) {
          $node = node_load($entity_id);
          $node->status = 1;
          $node->promote = 0;
          $node->comment = 0;
          $node->language = LANGUAGE_NONE;
          $node->field_payment_date[LANGUAGE_NONE][0] = array(
            'value' => date('Y-m-d H:i:s', strtotime('now')),
            'timezone' => 'UTC',
            'timezone_db' => 'UTC',
          );
          $node->field_payment_type[$node->language][0]['value'] = 1;
          $node->field_payment_mode[$node->language][0]['value'] = $form_state['values']['field_payment_mode'][LANGUAGE_NONE][0]["value"];
          $node->field_payment_amount_paid[$node->language][0]['value'] = $form_amount;
          //$node->field_payment_entity_reference[$node->language][0]['target_id'] = $order_id;
          $node->field_payment_account_entity_ref[$node->language][0]['target_id'] = $account_id;
          $node->field_payment_status[$node->language][0]['value'] = "complete";
          node_save($node);

          $account_id = arg(5); // Account page, add balance
          if (is_numeric($account_id)) {
            // Add credit amount from outstanding balance
            $account = node_load($account_id);
            $credit_amount = $form_amount;
            if (!empty($credit_amount) && is_numeric($credit_amount)) {
              // If amount is making from account page
              $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'] = $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'] - $credit_amount;
              $account->field_account_available_amount[LANGUAGE_NONE][0]['value'] = $account->field_account_available_amount[LANGUAGE_NONE][0]['value'] + $credit_amount;
              // JOSEPH
              db_update('node')->fields(array('changed' => time()))->condition('nid', $account->nid, '=')->execute();
// JOSEPH              
// update node with new values
              field_attach_update('node', $account);
            }
            // Update Available Amount
          }
        }
      }
    }
    else {
      if ($payment_for == "card") {
        $entity_id = $form_state["nid"];
        $card_id = arg(5);
        if (!empty($entity_id)) {
          $form_amount = $form_state['values']['field_payment_amount_paid'][LANGUAGE_NONE][0]["value"];
          $node = node_load($entity_id);
          $node->title = 'Payment from Card ID ' . $card_id;
          $node->status = 1;
          $node->promote = 0;
          $node->comment = 0;
          $node->language = LANGUAGE_NONE;
          $node->field_payment_date[LANGUAGE_NONE][0] = array(
            'value' => date('Y-m-d H:i:s', strtotime('now')),
            'timezone' => 'UTC',
            'timezone_db' => 'UTC',
          );
          $node->field_payment_type[$node->language][0]['value'] = 1;
          $node->field_payment_mode[$node->language][0]['value'] = $form_state['values']['field_payment_mode'][LANGUAGE_NONE][0]["value"];
          $node->field_payment_amount_paid[$node->language][0]['value'] = $form_amount;
          $node->field_payment_status[$node->language][0]['value'] = $form_state['values']['field_payment_status'][LANGUAGE_NONE][0]["value"];
          $node->field_payment_card_reference[$node->language][0]['tid'] = $card_id;
          node_save($node);

          $card_payment_status = $form_state['values']['field_payment_status'][LANGUAGE_NONE][0]["value"];
          if ($card_payment_status == "complete") {
            // Update Card Outstanding balance
            $card_id = !empty($card_id) ? $card_id : NULL;
            if (!empty($card_id)) {
              $card = taxonomy_term_load($card_id);
              $credit_amount = $form_amount;
              if (!empty($credit_amount) && is_numeric($credit_amount)) {
                // If amount is making from account page
                $card->field_card_outstanding_balance[LANGUAGE_NONE][0]['value'] = $card->field_card_outstanding_balance[LANGUAGE_NONE][0]['value'] - $credit_amount;
                // update node with new values
                field_attach_update('taxonomy_term', $card);
              }
            }
          }
        }
      }
    }
  }
}

/**
 * // ===== PAYMENT DELETE FROM SUBMIT ACTION ============/
 * On payment against account delete adjust account outstanding balance
 */
function _fernweh_alter_payment_delete_form_submit_extend($payment) {

  if (is_object($payment)) {
    $amount_paid = isset($payment->field_payment_amount_paid[LANGUAGE_NONE][0]['value']) ? $payment->field_payment_amount_paid[LANGUAGE_NONE][0]['value'] : NULL;
    $payment_type = isset($payment->field_payment_type[LANGUAGE_NONE][0]['value']) ? $payment->field_payment_type[LANGUAGE_NONE][0]['value'] : NULL;
    if (is_numeric($amount_paid)) {
      $account_id = !empty($payment->field_payment_account_entity_ref[LANGUAGE_NONE][0]['target_id']) ? $payment->field_payment_account_entity_ref[LANGUAGE_NONE][0]['target_id'] : NULL;
      $card_id = isset($payment->field_payment_card_reference[LANGUAGE_NONE][0]['tid']) ? $payment->field_payment_card_reference[LANGUAGE_NONE][0]['tid'] : NULL;

      if (empty($card_id) && !empty($account_id)) { // If payment related to account then only modify outstanding balance
        $account = node_load($account_id);
        $net_outstanding_balance = $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'];
        $net_available_balance = $account->field_account_available_amount[LANGUAGE_NONE][0]['value'];
        // Check if payment is associated with order
        if (!empty($payment->field_payment_entity_reference[LANGUAGE_NONE][0]['target_id'])) {
          // payment associated with order
          if ($payment_type == 1) { // payment type is payment
            //$net_outstanding_balance += $amount_paid;
            $net_available_balance += $amount_paid;
            $order_id = $payment->field_payment_entity_reference[LANGUAGE_NONE][0]['target_id'];
            $order = commerce_order_load($order_id);
            $order->field_order_paid_amount["und"][0]["value"] = $order->field_order_paid_amount["und"][0]["value"] - $amount_paid;
            commerce_order_save($order);
          }
//          elseif ($payment_type == 2) { // Payment type is refund
//            $net_outstanding_balance += $amount_paid;
//          }
        }
        else {
          // payment don't have any association with order, it only belongs to account
          if ($payment_type == 1) { // payment type is payment
            $net_outstanding_balance += $amount_paid;
            $net_available_balance -= $amount_paid;
          }
        }
        $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'] = $net_outstanding_balance;
        $account->field_account_available_amount[LANGUAGE_NONE][0]['value'] = $net_available_balance;
        // JOSEPH
        db_update('node')->fields(array('changed' => time()))->condition('nid', $account->nid, '=')->execute();
        // JOSEPH
        // Update account balance with new values
        field_attach_update('node', $account);
      }
      else {
        // Card payment delete
        $card = taxonomy_term_load($card_id);
        $credit_amount = $amount_paid;
        if (!empty($credit_amount) && is_numeric($credit_amount)) {
          // If amount is making from account page
          $card->field_card_outstanding_balance[LANGUAGE_NONE][0]['value'] = $card->field_card_outstanding_balance[LANGUAGE_NONE][0]['value'] + $credit_amount;
          // update node with new values
          field_attach_update('taxonomy_term', $card);
        }
      }
    }
  }
}

/*
 * Implements hook_node_presave()
 */

// TODO - Need to alter the presave method
function fernweh_alter_node_presave($node) {

  if (arg(4) == "card" && arg(3) == "add") {
    return true;
  }
  /**
   * $entity_id - Either account id or order id
   */
  // Add new payment
  // if ($node->type === 'payment' && arg(3) == "add") { // Add new payment
  // $entity_id = null;
  //if (arg(5) && is_numeric(arg(5))) {
  // $entity_id = arg(5);
//      switch (arg(4)) {
//        case 'order': // Order page
//          // determine account id from order id
//          $account_id = fernweh_get_account_id($entity_id);
//          $node->title = 'Payment for order id ' . arg(5);
//          // If payment mode is account at order payment, populate both entity references
//          if ($node->field_payment_mode[LANGUAGE_NONE][0]['value'] == "Account") {
//            if (is_numeric($account_id)) {
//              // Deduct debit amount from outstanding balance
//              $account = node_load($account_id);
//              $debit_amount = $node->field_payment_amount_paid[LANGUAGE_NONE][0]['value'];
//              if (!empty($debit_amount) && is_numeric($debit_amount)) {
//                //print_r($account->field_account_outstanding_bal);
//                $new_outstanding_bal = $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'];
//                if ($node->field_payment_type[LANGUAGE_NONE][0]['value'] == 1) { // 1 - Paid to order from account
//                  $new_outstanding_bal -= $debit_amount;
//                }
//                elseif ($node->field_payment_type[LANGUAGE_NONE][0]['value'] == 2) { //  3 - Refund account to balance
//                  $new_outstanding_bal += $debit_amount;
//                }
//                $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'] = $new_outstanding_bal;
//                // update node with new values
//                field_attach_update('node', $account);
//              }
//              $node->field_payment_account_entity_ref[LANGUAGE_NONE][0]['target_id'] = $account_id;
//            }
//          }
//          $node->field_payment_entity_reference[LANGUAGE_NONE][0]['target_id'] = $entity_id;
//          break;
//        case 'account':
//          $account_id = arg(5); // Account page, add balance
//            $credit_amount = $node->field_payment_amount_paid[LANGUAGE_NONE][0]['value'];
//            if (is_numeric($account_id) && $credit_amount >0 ) {
//              // Add credit amount from outstanding balance
//              $account = node_load($account_id);
//            if (!empty($credit_amount) && is_numeric($credit_amount)) {
//              // If amount is making from account page
//              $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'] = $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'] - $credit_amount;
//              // update node with new values
//              field_attach_update('node', $account);
//            }
//          }
//          $node->field_payment_type[LANGUAGE_NONE][0]['value'] = 1; // 1 - Payment direct to account
//          $node->title = 'Payment for account id ' . arg(5);
//          $node->field_payment_account_entity_ref[LANGUAGE_NONE][0]['target_id'] = $entity_id;
//          break;
//      }
  //   }
  // }
  if ($node->type === 'payment' && is_numeric(arg(3)) && arg(4) == "edit") { // Edit Payment
    $entity_id = null;
    if (arg(6) && is_numeric(arg(6))) {
      switch (arg(5)) {
        case 'order': // Order page
          $entity_id = arg(6);
          //
          // If payment mode is account at order payment, populate both entity references
          // if ($node->field_payment_mode[LANGUAGE_NONE][0]['value'] == "Account") {
          // determine account id from order id
          $account_id = fernweh_get_account_id($entity_id);
          if (is_numeric($account_id)) {
            _fernweh_modify_outstanding_balance($account_id, $node, 'order');
          }
          // }
          break;
        case 'account': // Account page
          $account_id = arg(6); // Account page, edit balance
          if (is_numeric($account_id)) {
            _fernweh_modify_outstanding_balance($account_id, $node, 'account');
          }
          break;
      }
    }
  }

  // Edit special caseArray

  if (arg(4) == "edit" && arg(5) == "card" && is_numeric(arg(6))) {

    // Payment status change
    $new_payment_status = ($node->field_payment_status) ? $node->field_payment_status[LANGUAGE_NONE][0]['value'] : NULL;
    $original_payment_status = ($node->original->field_payment_status) ? $node->original->field_payment_status[LANGUAGE_NONE][0]['value'] : NULL;


    // Payment edit from card
    $card_id = arg(6);
    $card_id = !empty($card_id) ? $card_id : NULL;
    if (!empty($card_id)) {
      $new_amount_paid = ($node->field_payment_amount_paid) ? $node->field_payment_amount_paid[LANGUAGE_NONE][0]['value'] : NULL;
      $original_amount_paid = ($node->original->field_payment_amount_paid) ? $node->original->field_payment_amount_paid[LANGUAGE_NONE][0]['value'] : NULL;
      // Determine current submit amount less or greater than previous amount
      $change_amount = 0;
      if ($new_payment_status == $original_payment_status && $new_payment_status == "complete") {
        // Status is already complete
        if (is_numeric($original_amount_paid) && is_numeric($original_amount_paid)) {
          $change_amount = $original_amount_paid - $new_amount_paid;
        }
      }
      elseif ($new_payment_status != $original_payment_status && $new_payment_status == "complete") {
        // Status changed to complete
        $change_amount = $change_amount - $new_amount_paid;
      }

      $card = taxonomy_term_load($card_id);
      if (is_object($card)) {
        if (!empty($change_amount) && is_numeric($change_amount)) {
          // If amount is making from account page
          $card->field_card_outstanding_balance[LANGUAGE_NONE][0]['value'] = $card->field_card_outstanding_balance[LANGUAGE_NONE][0]['value'] + $change_amount;
          // update node with new values
          field_attach_update('taxonomy_term', $card);
        }
      }
    }
  }
}

/**
 * Fernweh custom function to modify outstanding balance at payment edit
 *
 */
function _fernweh_modify_outstanding_balance($account_id, $node, $payment_against) {

  if (is_numeric($account_id)) {
    // Amount from outstanding balance
    $account = node_load($account_id);
    if ($account) {
      $new_amount_paid = ($node->field_payment_amount_paid) ? $node->field_payment_amount_paid[LANGUAGE_NONE][0]['value'] : NULL;
      $original_amount_paid = ($node->original->field_payment_amount_paid) ? $node->original->field_payment_amount_paid[LANGUAGE_NONE][0]['value'] : NULL;
      // Determine current submit amount less or greater than previous amount
      if (is_numeric($original_amount_paid) && is_numeric($original_amount_paid)) {
        $service_amount_change = $original_amount_paid - $new_amount_paid;
        // -ve (new amount is greater than previous amount paid)
        // +ve (new amount is less than previous amount paid)
        // 0 (no change)
        if ($service_amount_change != 0) {
          $payment_type = ($node->field_payment_type) ? $node->field_payment_type[LANGUAGE_NONE][0]['value'] : NULL;
          // get original outstanding balance
          $net_outstanding_balance = $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'];
          $net_available_balance = $account->field_account_available_amount[LANGUAGE_NONE][0]['value'];
          // if payment type is payment and  payment against order
          if ($payment_against == 'order' /* && $payment_type == 1 */) { // 1-payment type payment
            //$net_outstanding_balance += $service_amount_change;
            if ($service_amount_change > 0) {
              $net_available_balance = $net_available_balance + abs($service_amount_change);
            }
            else {
              $net_available_balance = $net_available_balance - abs($service_amount_change);
            }
            // if payment type is payment or refund and payment against account
          }
          elseif ($payment_against == 'account' /* && ($payment_type == 1||$payment_type == 2) */) { // 2- Refund
            if ($service_amount_change > 0) {
              $net_outstanding_balance = $net_outstanding_balance + abs($service_amount_change);
              $net_available_balance = $net_available_balance - abs($service_amount_change);
            }
            else {
              $net_outstanding_balance = $net_outstanding_balance - abs($service_amount_change);
              $net_available_balance = $net_available_balance + abs($service_amount_change);
            }
          }//else set back to original value
          $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'] = $net_outstanding_balance;
          $account->field_account_available_amount[LANGUAGE_NONE][0]['value'] = $net_available_balance;
          // JOSEPH
          db_update('node')->fields(array('changed' => time()))->condition('nid', $account->nid, '=')->execute();
// JOSEPH          
// update account node with new outstanding balance value
          field_attach_update('node', $account);

          if ($payment_against == "order" && !empty($node->field_payment_entity_reference[LANGUAGE_NONE][0]['target_id'])) {
            $order_id = $node->field_payment_entity_reference[LANGUAGE_NONE][0]['target_id'];
            $order = commerce_order_load($order_id);
            $order->field_order_paid_amount["und"][0]["value"] = $order->field_order_paid_amount["und"][0]["value"] - $service_amount_change;
            if (function_exists(_change_order_status)) {
              $order = _change_order_status($order);
            }
            commerce_order_save($order);
          }
        }
      }
    }
  }
}

/**
 * Payment mode change check cost
 * @param $form
 * @param $form_state
 * @return mixed
 */
function _fernweh_payment_ajax_callback($form, $form_state) {

  if ($form['field_payment_account_id'] && is_numeric($form['field_payment_account_id']['#value'])) {

    ctools_include('ajax');
    ctools_include('modal');
    ctools_add_js('ajax-responder');

    $account_id = $form['field_payment_account_id']['#value'];
    $order_id = $form['field_payment_order_id']['#value'];
    $account = node_load($account_id);
    $order = commerce_order_load($order_id);
    $payment_type = ($form_state['values']['field_payment_type'][LANGUAGE_NONE][0]['value']) ? $form_state['values']['field_payment_type'][LANGUAGE_NONE][0]['value'] : NULL;
    if ($payment_type == 1 && $account && $form_state['values']['field_payment_mode'][LANGUAGE_NONE][0]['value'] == 'Account') {
      $outstanding_bal = $account->field_account_outstanding_bal[LANGUAGE_NONE][0]['value'];
      $service_cost = $order->field_order_service_cost[LANGUAGE_NONE][0]['value'];
      // Account must have balance greater than service cost
      if ($outstanding_bal < $service_cost) {
        hide($form['field_payment_detail']);
        hide($form['field_payment_amount_paid']);
        hide($form['field_payment_type']);
        unset($form['actions']['submit']);
        $form['message_alert'] = array(
          '#markup' => '<div class="alert alert-warning"><p><strong>Oops!</strong> Account do not have sufficient amount.</p>
                <p>Please change payment mode or make payment against account and try again</p>
                <p><strong>Outstanding Balance:</strong> <span> ' . inr_money_format($outstanding_bal) . '</span></p>
                <p><strong>Service Cost:</strong> <span> ' . inr_money_format($service_cost) . '</span></p>
                </div>'
        );
        return $form;
      }
    }


    // Prepare AJAX ctool
    $output = ctools_modal_form_wrapper('payment_node_form', $form_state);

    if (!empty($form_state['ajax_commands'])) {
      $output = $form_state['ajax_commands'];
    }

    print ajax_render($output);
    drupal_exit();
  }
}

/**
 * Payment form validation
 * @param $form
 * @param $form_state
 */
function fernweh_payment_form_validate($form, &$form_state) {

  // Validate Payment mode
  $payment_mode = $form_state['values']['field_payment_mode'][LANGUAGE_NONE][0]['value'];
  if (empty($payment_mode) || $payment_mode == "_none") {
    form_set_error('field_payment_mode', t('Payment mode should not be empty'));
  }

  // Validate Amount Paid
  $amount_paid = $form_state['values']['field_payment_amount_paid'][LANGUAGE_NONE][0]["value"];
  $amount_paid_default = $form['field_payment_amount_paid'][LANGUAGE_NONE][0]['value']['#default_value'];
  $payment_type = isset($form_state['input']['field_payment_type']) ? $form_state['input']['field_payment_type'][LANGUAGE_NONE][0]["value"] : NULL;
  if ($amount_paid > $amount_paid_default) {
    // Validate if payment against order
    if ($form_state['input']['field_payment_order_id']) {
      $order_id = $form_state['input']['field_payment_order_id'];
      $order = commerce_order_load($order_id);
      $service_cost = isset($order->field_order_service_cost[LANGUAGE_NONE][0]["value"]) ? $order->field_order_service_cost[LANGUAGE_NONE][0]["value"] : 0;
      $net_paid_amount = 0;
      $results = fernweh_get_payments($order_id);
      if ($results) {
        foreach ($results as $row) {
          $payment = node_load($row->entity_id);
          // If status is equal to 0, payment is deleted then filter out
          if ($payment->status != 0) {
            if (isset($payment->field_payment_type[LANGUAGE_NONE][0]['value']) && $payment->field_payment_type[LANGUAGE_NONE][0]['value'] == 1) {
              $paid = !empty($payment->field_payment_amount_paid) ? $payment->field_payment_amount_paid[LANGUAGE_NONE][0]['value'] : "";
              $net_paid_amount += is_numeric($paid) ? $paid : 0;
            }
          }
        }
      }

      $balance_amount = $service_cost - $net_paid_amount;
      $net_amount_change = $amount_paid - $amount_paid_default;

      if (arg(2) == "payment" && arg(4) == "edit" && arg(5) == "order") {
        $amount_paid = $net_amount_change;
      }

      if (($payment_type != 2) && !empty($amount_paid) && is_numeric($amount_paid) && $amount_paid > $balance_amount) {
        form_set_error('field_payment_amount_paid', t('Amount paid should not greater than service cost.'));
      }
    }
  }


  // Common validation
  if (empty($amount_paid)) {
    form_set_error('field_payment_amount_paid', t('Amount paid should not be empty'));
  }
  elseif (!empty($amount_paid) && !is_numeric($amount_paid)) {
    form_set_error('field_payment_amount_paid', t('Amount paid should be numeric'));
  }
}

/**
 * Get Payment records based on order id
 */
function fernweh_get_payments($order_id) {
  //Fetch all payments associated with current order id
  $results = db_select('field_data_field_payment_entity_reference', 'c')
      ->fields('c', array('entity_id'))
      ->condition('c.field_payment_entity_reference_target_id', $order_id, "=")
      ->execute();
  return $results;
}

/**
 * Get order list by account id
 */
function fernweh_get_orders_of_account($account_id) {

//  select la.entity_id, p.sku, l.order_id from field_data_field_lead_account la 
//INNER JOIN commerce_product p ON la.entity_id = p.product_id 
//INNER JOIN commerce_line_item l ON p.sku = l.line_item_label 
//INNER JOIN commerce_order o ON l.order_id = o.order_id
//where la.field_lead_account_target_id = 1402 AND o.status = 'pending'


  $result_query = db_select('field_data_field_lead_account', 'la')
      ->fields('l', array('order_id'));

  $result_query->join('commerce_product', 'p', 'la.entity_id = p.product_id');
  $result_query->join('commerce_line_item', 'l', 'p.sku = l.line_item_label');
  $result_query->join('commerce_order', 'o', 'l.order_id = o.order_id');
  $result_query->condition('la.field_lead_account_target_id', $account_id, '=');
  $result_query->condition('o.status', 'pending', '=');

  $result = $result_query->execute();

  $orders = array();
  while ($record = $result->fetchAssoc()) {
    $orders[] = commerce_order_load($record['order_id']);
  }


  //Fetch all orders associated with current account id
//  $query = new EntityFieldQuery();
//  $query->entityCondition('entity_type', 'commerce_product')
//      ->propertyCondition('type', "lead")
//      ->fieldCondition('field_lead_account', 'target_id', $account_id, '=')
//  ;
//  $result = $query->execute();
//  $orders = array();
//  foreach ($result['commerce_product'] as $row) {
//    $product_id = $row->product_id;
//    $order_id = fernweh_get_order_id($product_id);
//    if (is_numeric($order_id) && $order_id != 0) {
//      $orders[] = commerce_order_load($order_id);
//    }
//  }

  return $orders;
}

/**
 * Get order list by account id
 */
function fernweh_get_all_orders_by_account($account_id) {

  $result_query = db_select('field_data_field_lead_account', 'la')
      ->fields('l', array('order_id'));

  $result_query->join('commerce_product', 'p', 'la.entity_id = p.product_id');
  $result_query->join('commerce_line_item', 'l', 'p.sku = l.line_item_label');
  $result_query->join('commerce_order', 'o', 'l.order_id = o.order_id');
  $result_query->condition('la.field_lead_account_target_id', $account_id, '=');
  //$result_query->condition('o.status', 'pending', '=');

  $result = $result_query->execute();

  $orders = array();
  while ($record = $result->fetchAssoc()) {
    $orders[] = commerce_order_load($record['order_id']);
  }

  return $orders;
}

/**
 * Get Aready paid amount to order
 * @param $order_id
 * @return int|string
 */
function fernweh_get_order_paid_amount($order_id) {
  $net_paid_amount = 0;
  $results = fernweh_get_payments($order_id);
  if ($results) {
    foreach ($results as $row) {
      $payment = node_load($row->entity_id);
      // If status is equal to 0, payment is deleted then filter out
      if ($payment->status != 0) {
        $paid = !empty($payment->field_payment_amount_paid) ? $payment->field_payment_amount_paid[LANGUAGE_NONE][0]['value'] : "";
        if (isset($payment->field_payment_type[LANGUAGE_NONE][0]['value']) && $payment->field_payment_type[LANGUAGE_NONE][0]['value'] == 1) {
          $net_paid_amount += is_numeric($paid) ? $paid : 0;
        }
        elseif (isset($payment->field_payment_type[LANGUAGE_NONE][0]['value']) && $payment->field_payment_type[LANGUAGE_NONE][0]['value'] == 2) {
          $net_paid_amount -= is_numeric($paid) ? $paid : 0;
        }
      }
    }
  }
  return $net_paid_amount;
}
