<?php
// $Id: ec_receipt.php,v 1.1.2.6 2008/03/24 02:40:12 sime Exp $

/**
 * @file
 * These are hooks which are called using ec_receipt_invoke() or 
 * ec_receipt_alloc_invoke()
 */

/**
 * @ingroup hooks
 * @{
 */

/**
 * @defgroup "e-Commerce Receipts" "e-Commerce Receipts"
 * @{
 * The Drupal e-Commerce Receipts system
 *
 * Welcome to the Drupal developers documentation for Drupal e-Commerce 
 * Receipts package.
 */

/**
 * Register payments gateways to the e-Commerce Receipts system
 *
 * @return
 *  Return an array or receipt info blocks to the system.
 */
function hook_receipt_info() {
  // Because you can create a module what provides several
  // payment gateways, we ask for a array containing
  // info about each of them.
  return array(
    'cod' => array(
      // Description
      'name'                 => t('Gateway example'),
      'description'          => t('Clients pay when they receive their products.'),

      // (Optional). The payment icon
      'icon' => array(
        'src' => drupal_get_path('module', 'example') .'/example.gif',
        'attributes' => array(
          'title' => t('Example Logo'),
          'class' => 'example-logo',
        ),
      ),

      // List only the currencies supported by your
      // payment gateway
      'currencies_supported' => array('AUD', 'USD'),

      // Remember to set the 'module' attribute
      // differently to each payment gateway
      'module'               => array('example'),

      // (Optional). All money operations that this method allow.
      // For payment gateways, use "allow_payments".
      'allow_payments'       => TRUE,
      'allow_admin_payments' => TRUE,
      'allow_refunds'        => TRUE,
      'allow_payto'          => TRUE,
      'allow_recurring'      => TRUE,

      // (Optional). Extra third party requirements. You should include all
      // restrictions and notices.
      'gateway_requirements' => NULL,
    ),
  );
}

/**
 * Load additional receipt information from the database.
 *
 * @param $receipt
 *  Receipt record which this hook is meant to load the additional 
 *  information.
 * 
 * @return
 *  Return an array of additional information to be included into the 
 *  receipt before it is returned to the system.
 */
function hook_receipt_load($receipt) {
}

/**
 * Save additional information about the receipt to the database.
 *
 * @param $receipt
 *  The receipt object which is going to be saved.
 */
function hook_receipt_save($receipt) {
}

/**
 * Build a form for collecting the payment information.
 *
 * This will generally be used on the checkout review page which will 
 * collect the information that is required to charge the customer.
 *
 * @param $type
 *  The allocation type which corresponds to the $object which can be past 
 *  to the e-Commerce Receipt allocation interface.
 *
 * @param $object
 *  This is a data type which can pass the information to the allocation 
 *  interface to reteive data from the object.
 *
 * @return
 *  Return the form which can be displayed.
 */
function hook_receipt_payment_form($type, $object) {
}

/**
 * Using the information past from the payment form the system will process 
 * the payment and update the receipt.
 *
 * @param $receipt
 *  A blank receipt is past to the system for the payment to be connected 
 *  to. The identifier for the payment is against the receipt and not the 
 *  transactions. At this stage the transaction may or may not have been 
 *  created, and if there is a crash the receipt can be tracked to the 
 *  customer.
 *
 * @param $type
 *  The allocation type which corresponds to the $object which can be past 
 *  to the e-Commerce Receipt allocation interface.
 *
 * @param $object
 *  This is a data type which can pass the information to the allocation 
 *  interface to reteive data from the object.
 *
 * @return
 *  Pass back the $receipt->erid after ec_receipt_save($receipt);
 */
function hook_receipt_process_payment($receipt, $atype, $object) {

  // Some receipt types, like C.O.D. may just set some values and return.
  // This example looks at a payment gateway.

  // Do some general preparation of xml, or whatever the gateway requires.
  // $ret == ...

  $ret = drupal_http_request(variable_get('my_gateway_url', $gateway_url), $headers, 'POST', $request_xml);
  $response = simplexml_load_string($ret->data);

  switch ($response->txnStatus) {
    case 'True':
      $receipt->status = RECEIPT_STATUS_COMPLETED;
      $receipt->approval_code = $response->authCode;
      break;

    case 'False':
      $receipt->status = RECEIPT_STATUS_FAILED;
      $receipt->response_text = $response->trxnError;
      form_set_error('', $receipt->response_text);
      break;
  }
  ec_receipt_save($receipt);

  return $receipt->erid;
}

/**
 * @param $receipt
 *  A blank receipt is past to the system for the payment to be connected 
 *  to. The identifier for the payment is against the receipt and not the 
 *  transactions. 
 *
 * @param $type
 *  The allocation type which corresponds to the $object which can be past 
 *  to the e-Commerce Receipt allocation interface.
 *
 * @param $object
 *  This is a data type which can pass the information to the allocation 
 *  interface to reteive data from the object.
 *
 * @return
 *  Return the url which is past to drupal_goto() to be devirted to the 
 *  hosted payment gateway system.
 */
function hook_receipt_payment_url($receipt, $atype, $object) {
}

/**
 * Register allocation types to the receipt system. An allocation is literally
 * an allocation of some money on a receipt (say from a payment gateway) against
 * a transaction.
 *
 * Most transactions are generated by the store.module, hence the main implementer
 * of allocations is store. Another example of a module that implements allocations
 * is ec_receipt itself, which provides refunds (ie. an allocation amount debited from
 * a transactio and credited to the customer).
 *
 * Note: the above is sime's first attempt to describe it.
 *
 * @return
 *  Return an array of info.
 */
function hook_allocation_info() {
  // As per store.module
  return array(
    'transaction' => array(
      'name' => t('e-Commerce transactions'),
      'description' => t('Allocation interface for e-Commerce transactions.'),
      'module' => 'store',
    ),
  );
}

/**
 * Return the payment data of an allocation object.
 * Eg. store returns the data previously assigned in 'set_payment_data'
 */
function hook_alloc_get_payment_data($txn) {
  return $txn->payment_data[$txn->payment_method];
}

/**
 * I have no idea how an allocation provide returns a payment form
 * since its not a receipt type - sime
 */
function hook_alloc_get_payment_form($txn) {
  return $txn->payment_form;
}

/**
 * Return the payment method of an allocation object.
 * Eg. store returns the method assigned in 'set_payment_data'
 */
function hook_alloc_get_payment_type($txn) {
  return $txn->payment_method;
}

/**
 * Return the total amount for an allocation object.
 * Eg. store returns the total for a transaction.
 */
function hook_alloc_get_total($txn) {
  return store_transaction_calc_gross($txn);
}

/**
 * Load an allocation object.
 * Eg. store returns the total for a transaction.
 */
function hook_alloc_load($txnid) {
  return store_transaction_load($txnid);
}

/**
 * Allows an allocation object provider to assign payment data to its native object.
 * Eg. store assigns payment data to its transaction.
 */
function hook_alloc_set_payment_data(&$txn, $payment_data) {
  $txn->payment_data[$txn->payment_method] = $payment_data;
}

/**
 * The allocation object provider returns an appropriate address.
 * Eg. store returns an address from the transaction object.
 */
function hook_alloc_get_address($txn, $atype = 'billing') {
  if (!empty($txn->address[$atype])) {
    return (array)$txn->address[$atype];
  }
}

/**
 * The allocation object provider returns the customer.
 * Eg. store returns the customer from the transaction object.
 */
function hook_alloc_get_customer($txn) {
  return $txn->customer;
}

/**
 * The allocation object provider customer names from an allocation object.
 * Eg. store returns the customers from the transaction object.
 */
function hook_alloc_get_customer_names(&$txn, $atype = 'billing') {
  if ($address = $txn->address[$atype]) {
    $names = array();
    if (!empty($address->firstname) or !empty($address->lastname)) {
      $names['fname'] = $address->firstname;
      $names['lname'] = $address->lastname;
    }
    elseif (!empty($address['firstname']) or !empty($address['lastname'])) {
      $names['fname'] = $address['firstname'];
      $names['lname'] = $address['lastname'];
    }
    else {
      $names = ec_common_split_name($address->fullname);
    }
    return !empty($names) ? $names : NULL;
  }
}

/**
 * The allocation object provider returns currency.
 * Eg. store returns the currency of the transaction object.
 */
function hook_alloc_get_currency($txn) {
  return $txn->currency;
}

/**
 * The allocation object provider returns the invoice number of the allocation object.
 * Eg. store returns the invoice number from the transaction object.
 */
function hook_alloc_get_invoice_no($txn) {
  return $txn->txnid;
}

/**
 * The allocation object provider returns the items of the allocation object.
 * Eg. store returns the product items from the transaction object.
 */
function hook_alloc_get_items($txn) {
  if (!empty($txn->items) && is_array($txn->items)) {
    store_alloc_build_items($txn, 'init');
    $items = array_map('store_alloc_build_items', $txn->items);
    return $items;
  }
}

/**
 * tba (example is from store.module)
 */
function hook_alloc_allocation($txn, $balance) {
  $is_shippable = FALSE;

  if (!empty($txn->items)) {
    foreach ($txn->items as $item) {
      if (product_is_shippable($item->vid)) {
        $is_shippable = TRUE;
        break;
      }
    }
  }

  if ($balance == 0) {
    $txn->allocation = EC_ALLOC_COMPLETED;
    if (!$is_shippable) {
      $txn->workflow = EC_WORKFLOW_COMPLETED;
    }
  }
  else {
    $txn->allocation = EC_ALLOC_PART;
  }

  store_transaction_save($txn);
}

/**
 * tba (example is from store.module)
 */
function hook_alloc_build_items($item, $op = 'process') {
  static $txn;
  if ($op == 'init') {
    $txn = $item;
    return;
  }

  return array(
    'id' => $item->nid,
    'name' => $item->title,
    'qty' => $item->qty,
    'amount' => store_adjust_misc($txn, $item),
  );
}


/**
 * @} End of "defgroup e-Commerce Receipts"
 */

/**
 * @} End of "ingroup hooks".
 */