You are here

uc_pma.module in Ubercart Payment Method Adjustments 7

Same filename and directory in other branches
  1. 6 uc_pma.module

This module hooks into a few different parts of Ubercart to allow store administrators to associate a fee or discount with payment methods.

Module compiled by Ryan from a schnazzy patch by cYu. Ported on Drupal 7.x by Tomas Barej

File

uc_pma.module
View source
<?php

/**
 * @file
 * This module hooks into a few different parts of Ubercart to allow store
 * administrators to associate a fee or discount with payment methods.
 *
 * Module compiled by Ryan from a schnazzy patch by cYu.
 * Ported on Drupal 7.x by Tomas Barej
 */

/**
 * Implements hook_theme().
 */
function uc_pma_theme() {
  return array(
    'uc_pma_payment_method_table' => array(
      'render element' => 'form',
      'file' => 'uc_pma.module',
    ),
  );
}

/**
 * Implements hook_form_alter().
 */
function uc_pma_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'uc_payment_methods_form') {
    $methods_info = '<div>' . t('The adjustment field can be used to associate a fee or discount with a payment method.  Specify a value that is a flat amount or a percentage of the subtotal to be added or subtracted when a payment method is chosen at checkout. Examples: 3%, 1.00, -5.5%, -2') . '</div><br />';
    if (isset($form['methods_info'])) {
      $form['methods_info']['#value'] .= $methods_info;
    }
    else {
      $form['methods_info']['#value'] = $methods_info;
    }
    $form['pmtable']['#theme'] = 'uc_pma_payment_method_table';
    foreach (element_children($form['pmtable']) as $method_id) {
      $form['pmtable'][$method_id]['uc_payment_method_' . $method_id . '_adjustment'] = array(
        '#type' => 'textfield',
        '#summary callback' => 'summarize_null',
        '#default_value' => variable_get('uc_payment_method_' . $method_id . '_adjustment', ''),
        '#size' => '9',
      );
    }
    $form['uc_pma'] = array(
      '#type' => 'fieldset',
      '#title' => t('Payment Method Adjustments'),
    );
    $form['uc_pma']['uc_pma_adjustments_apply_to'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Apply UC_PMA adjustments to:'),
      '#default_value' => variable_get('uc_pma_adjustments_apply_to', array(
        'products',
      )),
      '#description' => t('UC_PMA adjustments always apply to products, but not by default to line items like shipping.'),
      '#options' => array(
        'shipping' => t('Shipping'),
      ),
    );
  }
  elseif ($form_id == 'uc_cart_checkout_form') {
    foreach ($form['panes']['payment']['payment_method']['#options'] as $key => $value) {
      $adjustment = variable_get('uc_payment_method_' . $key . '_adjustment', '');
      if (!empty($adjustment)) {
        $form['panes']['payment']['payment_method']['#options'][$key] .= '<div class="description" style="padding-left: 2.5em;">' . payment_method_adjustment_description($key) . '</div>';
      }
    }

    //replace default payment pane ajax behaviour with own
    $form['panes']['payment']['payment_method']['#ajax'] = array(
      'callback' => 'uc_pma_payment_method_ajax',
      'progress' => array(
        'type' => 'throbber',
      ),
    );
  }
}

/**
 * AJAX callback for payment method details on the checkout form and adding a line item of payment method adjustment.
 */
function uc_pma_payment_method_ajax($form, $form_state) {
  if (isset($form['panes']['payment']['details'])) {
    $commands[] = ajax_command_replace('#payment-details', drupal_render($form['panes']['payment']['details']));
  }
  if (isset($form['panes']['payment']['line_items'])) {
    $commands[] = ajax_command_replace('#line-items-div', drupal_render($form['panes']['payment']['line_items']));
    $commands[] = ajax_command_prepend('#line-items-div', theme('status_messages'));
  }
  return array(
    '#type' => 'ajax',
    '#commands' => $commands,
  );
}

/*******************************************************************************
 * Hook Functions (Ubercart)
 ******************************************************************************/

/**
 * Implements hook_uc_line_item().
 */
function uc_pma_uc_line_item() {
  $items[] = array(
    'id' => 'payment',
    'title' => t('Payment method'),
    'weight' => 6,
    'stored' => FALSE,
    'calculated' => TRUE,
    'add_list' => TRUE,
    'callback' => 'uc_pma_adjustment_callback',
  );
  return $items;
}

/**
 * Payment ajustment line item callback
 */
function uc_pma_adjustment_callback($op, &$order) {
  switch ($op) {
    case 'load':
      $adjustment_order = $order;
      $lines = array();
      if (empty($adjustment_order->payment_method)) {

        //if payment_method isn't set we pick the default one
        $methods = _uc_payment_method_list();
        $default = NULL;
        if (count($methods) > 0) {
          foreach ($methods as $id => $method) {
            if ($method['checkout'] && !isset($method['express'])) {
              if (is_null($default)) {
                $default = $id;
              }
            }
          }
          $adjustment_order->payment_method = $default;
        }
      }
      $adjustment = _payment_method_adjustment($adjustment_order);
      if (isset($adjustment['description']) && isset($adjustment['value'])) {
        $lines[] = array(
          'id' => 'payment_method',
          'title' => $adjustment['description'],
          'amount' => $adjustment['value'],
        );
      }
      return $lines;
  }
}

/**
 * Implements hook_order().
 */
function uc_pma_order($op, &$arg1) {
  switch ($op) {
    case 'save':
      $adjustment = _payment_method_adjustment($arg1);
      db_query("DELETE FROM {uc_order_line_items} WHERE order_id = %d AND type = 'payment_method'", $arg1->order_id);
      $min_adjust = 0.01;
      if ($adjustment['value'] && ($adjustment['value'] >= $min_adjust || $adjustment['value'] <= -$min_adjust)) {
        uc_order_line_item_add($arg1->order_id, 'payment_method', $adjustment['description'], $adjustment['value'], 1);
      }
      break;
  }
}

// Retheme the payment method settings table to include the adjustment field.
function theme_uc_pma_payment_method_table($variables) {
  $form = $variables['form'];
  drupal_add_tabledrag('uc-payment-methods', 'order', 'sibling', 'uc-payment-method-weight');
  $header = array(
    t('Payment method'),
    t('List position'),
    t('Adjustment'),
    t('Operations'),
  );
  $rows = array();
  foreach (element_children($form) as $method) {
    $row = array(
      drupal_render($form[$method]['uc_payment_method_' . $method . '_checkout']),
      drupal_render($form[$method]['uc_payment_method_' . $method . '_weight']),
      drupal_render($form[$method]['uc_payment_method_' . $method . '_adjustment']),
      drupal_render($form[$method]['settings']),
    );
    $rows[] = array(
      'data' => $row,
      'class' => array(
        'draggable',
      ),
    );
  }
  return theme('table', array(
    'header' => $header,
    'rows' => $rows,
    'attributes' => array(
      'id' => 'uc-payment-methods',
    ),
  ));
}
function payment_method_adjustment_description($method_id) {
  $name = _uc_payment_method_data($method_id, 'name');
  $adjustment = variable_get('uc_payment_method_' . $method_id . '_adjustment', '');
  if (empty($name) || empty($adjustment)) {
    return;
  }
  $adjustment = preg_replace('/[^-0-9' . variable_get('uc_currency_dec', '.') . ']+%/', '', $adjustment);
  if (!strstr($adjustment, '%')) {
    $adjustment = uc_currency_format(str_replace(variable_get('uc_currency_dec', '.'), ".", $adjustment));
  }
  if (strstr($adjustment, '-')) {
    $description = t('Receive a !adjustment discount when paying by !method.', array(
      '!adjustment' => str_replace('-', '', $adjustment),
      '!method' => $name,
    ));
  }
  else {
    $description = t('There is a !adjustment fee when paying by !method.', array(
      '!adjustment' => $adjustment,
      '!method' => $name,
    ));
  }
  return $description;
}
function _payment_method_adjustment($order) {
  if (empty($order->payment_method)) {
    return 0;
  }

  // In case the variable is set to '', check if $adjustment is empty and substitute 0.
  $pm_adjustment = variable_get('uc_payment_method_' . $order->payment_method . '_adjustment', '0');
  $adjustment_data = array(
    'name' => _uc_payment_method_data($order->payment_method, 'name'),
    'adjustment' => empty($pm_adjustment) ? '0' : $pm_adjustment,
  );
  $subtotal = 0;
  foreach ($order->products as $item) {
    $item_total = $item->qty ? $item->qty * $item->price : $item->price;
    $subtotal += $item_total;
  }
  $adjust_types = variable_get('uc_pma_adjustments_apply_to', array());
  if (!empty($adjust_types)) {
    foreach ($order->line_items as $line_item) {
      if (in_array($line_item['type'], $adjust_types)) {
        $subtotal += $line_item['amount'];
      }
    }
  }
  $discount = FALSE;
  $percent = FALSE;
  $adjustment = array();
  $adjustment = preg_replace('/[^-0-9' . variable_get('uc_currency_dec', '.') . ']+%/', '', $adjustment_data['adjustment']);
  $ret['value'] = $adjustment;
  $ret['description'] = t('@name fee', array(
    '@name' => $adjustment_data['name'],
  ));
  if (strstr($adjustment, '-')) {
    $discount = TRUE;
  }
  if (strstr($adjustment, '%')) {
    $percent = TRUE;
    $adjustment = str_replace('%', '', $adjustment);
    $adjustment /= 100;
  }
  if ($percent) {
    $ret['value'] = $adjustment * $subtotal;
  }
  if ($discount) {
    $ret['description'] = t('@name discount', array(
      '@name' => $adjustment_data['name'],
    ));
  }
  $ret['description'] = ucfirst($ret['description']);

  //force first letter of line item to be uppercase
  $ret['value'] = number_format(str_replace(variable_get('uc_currency_dec', '.'), ".", $ret['value']), 2);
  return $ret;
}

Functions

Namesort descending Description
payment_method_adjustment_description
theme_uc_pma_payment_method_table
uc_pma_adjustment_callback Payment ajustment line item callback
uc_pma_form_alter Implements hook_form_alter().
uc_pma_order Implements hook_order().
uc_pma_payment_method_ajax AJAX callback for payment method details on the checkout form and adding a line item of payment method adjustment.
uc_pma_theme Implements hook_theme().
uc_pma_uc_line_item Implements hook_uc_line_item().
_payment_method_adjustment