<?php

/**
 * @file
 * Install, update and uninstall functions for the uc_order module.
 */

/**
 * Implements hook_schema().
 */
function uc_order_schema() {
  $schema = array();

  $schema['uc_orders'] = array(
    'description' => 'Stores Ubercart order information.',
    'fields' => array(
      'order_id' => array(
        'description' => 'Primary key: the order ID.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'uid' => array(
        'description' => 'The {user}.uid of the customer that placed the order.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'order_status' => array(
        'description' => 'The {uc_order_statuses}.order_status_id indicating the order status.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'order_total' => array(
        'description' => 'The total amount to be paid for the order.',
        'type' => 'numeric',
        'precision' => 16,
        'scale' => 5,
        'not null' => TRUE,
        'default' => 0.0,
      ),
      'product_count' => array(
        'description' => 'The total product quantity of the order.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'primary_email' => array(
        'description' => 'The email address of the customer.',
        'type' => 'varchar',
        'length' => 96,
        'not null' => TRUE,
        'default' => '',
      ),
      'delivery_first_name' => array(
        'description' => 'The first name of the person receiving shipment.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'delivery_last_name' => array(
        'description' => 'The last name of the person receiving shipment.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'delivery_phone' => array(
        'description' => 'The phone number at the delivery location.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'delivery_company' => array(
        'description' => 'The company at the delivery location.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'delivery_street1' => array(
        'description' => 'The street address of the delivery location.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'delivery_street2' => array(
        'description' => 'The second line of the street address.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'delivery_city' => array(
        'description' => 'The city of the delivery location.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'delivery_zone' => array(
        'description' => 'The state/zone/province id of the delivery location.',
        'type' => 'int',
        'size' => 'medium',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'delivery_postal_code' => array(
        'description' => 'The postal code of the delivery location.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'delivery_country' => array(
        'description' => 'The country ID of the delivery location.',
        'type' => 'int',
        'size' => 'medium',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'billing_first_name' => array(
        'description' => 'The first name of the person paying for the order.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'billing_last_name' => array(
        'description' => 'The last name of the person paying for the order.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'billing_phone' => array(
        'description' => 'The phone number for the billing address.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'billing_company' => array(
        'description' => 'The company of the billing address.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'billing_street1' => array(
        'description' => 'The street address where the bill will be sent.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'billing_street2' => array(
        'description' => 'The second line of the street address.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'billing_city' => array(
        'description' => 'The city where the bill will be sent.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'billing_zone' => array(
        'description' => 'The state/zone/province ID where the bill will be sent.',
        'type' => 'int',
        'size' => 'medium',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'billing_postal_code' => array(
        'description' => 'The postal code where the bill will be sent.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'billing_country' => array(
        'description' => 'The country ID where the bill will be sent.',
        'type' => 'int',
        'size' => 'medium',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'payment_method' => array(
        'description' => 'The method of payment.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'data' => array(
        'description' => 'A serialized array of extra data.',
        'type' => 'text',
        'serialize' => TRUE,
      ),
      'created' => array(
        'description' => 'The Unix timestamp indicating when the order was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'modified' => array(
        'description' => 'The Unix timestamp indicating when the order was last modified.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'host' => array(
        'description' => 'Host IP address of the person paying for the order.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'currency' => array(
        'description' => 'The ISO currency code for the order.',
        'type' => 'char',
        'length' => 3,
        'not null' => TRUE,
        'default' => '',
      ),
    ),
    'indexes' => array(
      'uid' => array('uid'),
      'order_status' => array('order_status'),
    ),
    'primary key' => array('order_id'),
  );

  $schema['uc_order_admin_comments'] = array(
    'description' => 'Comments on orders that only administrators can see.',
    'fields' => array(
      'comment_id' => array(
        'description' => 'Primary key: the comment ID.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'order_id' => array(
        'description' => 'The {uc_orders}.order_id of the order.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'uid' => array(
        'description' => 'The {user}.uid of the author of the comment.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'message' => array(
        'description' => 'The comment body.',
        'type' => 'text',
      ),
      'created' => array(
        'description' => 'The Unix timestamp indicating when the comment was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'order_id' => array('order_id'),
    ),
    'primary key' => array('comment_id'),
  );

  $schema['uc_order_comments'] = array(
    'description' => 'Comments on the order that the customer can see.',
    'fields' => array(
      'comment_id' => array(
        'description' => 'Primary key: the comment ID.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'order_id' => array(
        'description' => 'The {uc_orders}.order_id of the order.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'uid' => array(
        'description' => 'The {users}.uid of the user who made the comment.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'order_status' => array(
        'description' => 'The status the order had when the comment was made, from {uc_order_statuses}.order_status_id.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'notified' => array(
        'description' => 'A flag indicating whether the comment was emailed to the customer. 1 => Yes. 0 => No.',
        'type' => 'int',
        'size' => 'tiny',
        'not null' => TRUE,
        'default' => 0,
      ),
      'message' => array(
        'description' => 'The comment body.',
        'type' => 'text',
      ),
      'created' => array(
        'description' => 'The Unix timestamp indicating when the comment was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'order_id' => array('order_id'),
    ),
    'primary key' => array('comment_id'),
  );

  $schema['uc_order_line_items'] = array(
    'description' => 'Order line items other than products.',
    'fields' => array(
      'line_item_id' => array(
        'description' => 'Primary key: the line item ID.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'order_id' => array(
        'description' => 'The {uc_orders}.order_id.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'type' => array(
        'description' => 'The line item type.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'title' => array(
        'description' => 'The label of the line item.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'amount' => array(
        'description' => "The amount of the line item in the store's currency.",
        'type' => 'numeric',
        'precision' => 16,
        'scale' => 5,
        'not null' => TRUE,
        'default' => 0.0,
      ),
      'weight' => array(
        'description' => 'The sort criteria of line items.',
        'type' => 'int',
        'size' => 'small',
        'not null' => TRUE,
        'default' => 0,
      ),
      'data' => array(
        'description' => 'A serialized array of extra data.',
        'type' => 'text',
        'serialize' => TRUE,
      ),
    ),
    'indexes' => array(
      'order_id' => array('order_id'),
    ),
    'primary key' => array('line_item_id'),
  );

  $schema['uc_order_log'] = array(
    'description' => 'Record of changes made to an order.',
    'fields' => array(
      'order_log_id' => array(
        'description' => 'Primary key: the log entry ID.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'order_id' => array(
        'description' => 'The {uc_orders}.order_id.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'uid' => array(
        'description' => 'The {users}.uid of the user who made the changes.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'changes' => array(
        'description' => 'The description of what was changed.',
        'type' => 'text',
      ),
      'created' => array(
        'description' => 'The Unix timestamp indicating when the change was made.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'order_id' => array('order_id'),
    ),
    'primary key' => array('order_log_id'),
  );

  $schema['uc_order_products'] = array(
    'description' => 'The products that have been ordered.',
    'fields' => array(
      'order_product_id' => array(
        'description' => 'Primary key: the ordered product ID.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'order_id' => array(
        'description' => 'The {uc_orders}.order_id.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'nid' => array(
        'description' => 'The {node}.nid of the product.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'title' => array(
        'description' => 'The product title, from {node}.title.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'manufacturer' => array(
        'description' => 'The product manufacturer. (Deprecated)',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'model' => array(
        'description' => 'The product model/SKU, from {uc_products}.model.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'qty' => array(
        'description' => 'The number of the same product ordered.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'cost' => array(
        'description' => 'The cost to the store for the product.',
        'type' => 'numeric',
        'precision' => 16,
        'scale' => 5,
        'not null' => TRUE,
        'default' => 0.0,
      ),
      'price' => array(
        'description' => 'The price paid for the ordered product.',
        'type' => 'numeric',
        'precision' => 16,
        'scale' => 5,
        'not null' => TRUE,
        'default' => 0.0,
      ),
      'weight' => array(
        'description' => 'The physical weight.',
        'type' => 'float',
        'not null' => TRUE,
        'default' => 0.0,
      ),
      'data' => array(
        'description' => 'A serialized array of extra data.',
        'type' => 'text',
        'serialize' => TRUE,
      ),
    ),
    'indexes' => array(
      'order_id' => array('order_id'),
      'qty' => array('qty'),
      'nid' => array('nid'),
    ),
    'primary key' => array('order_product_id'),
  );

  $schema['uc_order_statuses'] = array(
    'description' => 'Statuses the order can have during its lifecycle.',
    'fields' => array(
      'order_status_id' => array(
        'description' => 'Primary key: the order status ID.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'title' => array(
        'description' => 'The status title.',
        'type' => 'varchar',
        'length' => 48,
        'not null' => TRUE,
        'default' => '',
      ),
      'state' => array(
        'description' => 'The base order state with which the status is associated.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'weight' => array(
        'description' => 'The sort criteria for statuses.',
        'type' => 'int',
        'size' => 'small',
        'not null' => TRUE,
        'default' => 0,
      ),
      'locked' => array(
        'description' => 'A flag indicating whether users can delete the status. 0 => Yes. 1 => No.',
        'type' => 'int',
        'size' => 'tiny',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'primary key' => array('order_status_id'),
  );

  return $schema;
}

/**
 * Implements hook_install().
 */
function uc_order_install() {
  drupal_install_schema('uc_order');

  $t = get_t();
  db_query("INSERT INTO {uc_order_statuses} (order_status_id, title, state, weight, locked) VALUES ('canceled', '%s', 'canceled', -20, 1);", $t('Canceled'));
  db_query("INSERT INTO {uc_order_statuses} (order_status_id, title, state, weight, locked) VALUES ('in_checkout', '%s', 'in_checkout', -10, 1);", $t('In checkout'));
  db_query("INSERT INTO {uc_order_statuses} (order_status_id, title, state, weight, locked) VALUES ('pending', '%s', 'post_checkout', 0, 1);", $t('Pending'));
  db_query("INSERT INTO {uc_order_statuses} (order_status_id, title, state, weight, locked) VALUES ('processing', '%s', 'post_checkout', 5, 1);", $t('Processing'));
  db_query("INSERT INTO {uc_order_statuses} (order_status_id, title, state, weight, locked) VALUES ('completed', '%s', 'completed', 20, 1);", $t('Completed'));
}

/**
 * Implements hook_uninstall().
 */
function uc_order_uninstall() {
  drupal_uninstall_schema('uc_order');

  db_query("DELETE FROM {variable} WHERE name LIKE 'uc_order_pane_%'");
  db_query("DELETE FROM {variable} WHERE name LIKE 'uc_state_%'");
  variable_del('uc_order_number_displayed');
  variable_del('uc_order_logging');
  variable_del('uc_order_capitalize_addresses');
  variable_del('uc_cust_view_order_invoices');
  variable_del('uc_cust_order_invoice_template');
}

/**
 * Implements hook_update_last_removed().
 */
function uc_order_update_last_removed() {
  return 8;
}

function uc_order_update_6000() {
  $ret = array();

  // Standardize database definitions during upgrade to Drupal 6.
  // ID fields are unsigned, regular-sized ints.
  // "Boolean" flags are unsigned tiny ints.
  // Postgres tables will have the necessary default values, and MySQL
  // doesn't need them, so the schema can just be mismatched for that.

  // Some id columns are already auto-incremented, so we can't remove the
  // primary key beforehand in MySQL. So we add it later for Postgres.

  db_drop_primary_key($ret, 'uc_orders');
  db_drop_index($ret, 'uc_orders', 'uid');
  db_change_field($ret, 'uc_orders', 'order_id', 'order_id', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('order_id')));
  db_change_field($ret, 'uc_orders', 'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), array('indexes' => array('uid' => array('uid'))));
  db_change_field($ret, 'uc_orders', 'delivery_first_name', 'delivery_first_name', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'delivery_last_name', 'delivery_last_name', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'delivery_phone', 'delivery_phone', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'delivery_company', 'delivery_company', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'delivery_street1', 'delivery_street1', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'delivery_street2', 'delivery_street2', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'delivery_city', 'delivery_city', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'delivery_zone', 'delivery_zone', array('type' => 'int', 'unsigned' => TRUE, 'size' => 'medium', 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_orders', 'delivery_postal_code', 'delivery_postal_code', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'delivery_country', 'delivery_country', array('type' => 'int', 'unsigned' => TRUE, 'size' => 'medium', 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_orders', 'billing_first_name', 'billing_first_name', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'billing_last_name', 'billing_last_name', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'billing_phone', 'billing_phone', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'billing_company', 'billing_company', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'billing_street1', 'billing_street1', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'billing_street2', 'billing_street2', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'billing_city', 'billing_city', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'billing_zone', 'billing_zone', array('type' => 'int', 'unsigned' => TRUE, 'size' => 'medium', 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_orders', 'billing_postal_code', 'billing_postal_code', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
  db_change_field($ret, 'uc_orders', 'billing_country', 'billing_country', array('type' => 'int', 'unsigned' => TRUE, 'size' => 'medium', 'not null' => TRUE, 'default' => 0));

  db_drop_index($ret, 'uc_order_admin_comments', 'order_id');
  db_change_field($ret, 'uc_order_admin_comments', 'comment_id', 'comment_id', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE));
  db_change_field($ret, 'uc_order_admin_comments', 'order_id', 'order_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), array('indexes' => array('order_id' => array('order_id'))));
  db_change_field($ret, 'uc_order_admin_comments', 'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
  if ($GLOBALS['db_type'] == 'pgsql') {
    db_add_primary_key($ret, 'uc_order_admin_comments', array('comment_id'));
  }

  db_drop_index($ret, 'uc_order_comments', 'order_id');
  db_change_field($ret, 'uc_order_comments', 'comment_id', 'comment_id', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE));
  db_change_field($ret, 'uc_order_comments', 'order_id', 'order_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), array('indexes' => array('order_id' => array('order_id'))));
  db_change_field($ret, 'uc_order_comments', 'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
  if ($GLOBALS['db_type'] == 'pgsql') {
    db_add_primary_key($ret, 'uc_order_comments', array('comment_id'));
  }

  db_drop_index($ret, 'uc_order_line_items', 'order_id');
  db_change_field($ret, 'uc_order_line_items', 'line_item_id', 'line_item_id', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE));
  db_change_field($ret, 'uc_order_line_items', 'order_id', 'order_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), array('indexes' => array('order_id' => array('order_id'))));
  if ($GLOBALS['db_type'] == 'pgsql') {
    db_add_primary_key($ret, 'uc_order_line_items', array('line_item_id'));
  }

  db_drop_index($ret, 'uc_order_log', 'order_id');
  db_change_field($ret, 'uc_order_log', 'order_log_id', 'order_log_id', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE));
  db_change_field($ret, 'uc_order_log', 'order_id', 'order_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), array('indexes' => array('order_id' => array('order_id'))));
  db_change_field($ret, 'uc_order_log', 'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
  if ($GLOBALS['db_type'] == 'pgsql') {
    db_add_primary_key($ret, 'uc_order_log', array('order_log_id'));
  }

  db_drop_index($ret, 'uc_order_products', 'order_id');
  db_change_field($ret, 'uc_order_products', 'order_product_id', 'order_product_id', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE));
  db_change_field($ret, 'uc_order_products', 'order_id', 'order_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), array('indexes' => array('order_id' => array('order_id'))));
  db_change_field($ret, 'uc_order_products', 'nid', 'nid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_order_products', 'qty', 'qty', array('type' => 'int', 'unsigned' => TRUE, 'size' => 'small', 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_order_products', 'cost', 'cost', array('type' => 'numeric', 'precision' => 10, 'scale' => 2, 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_order_products', 'price', 'price', array('type' => 'numeric', 'precision' => 10, 'scale' => 2, 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_order_products', 'weight', 'weight', array('type' => 'float', 'not null' => TRUE, 'default' => 0));
  if ($GLOBALS['db_type'] == 'pgsql') {
    db_add_primary_key($ret, 'uc_order_products', array('order_product_id'));
  }

  db_change_field($ret, 'uc_order_statuses', 'weight', 'weight', array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_order_statuses', 'locked', 'locked', array('type' => 'int', 'unsigned' => TRUE, 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));

  return $ret;
}

/**
 * Make sure that those who had the faulty 6000 update have the right precision
 * and scale.
 */
function uc_order_update_6001() {
  $ret = array();

  db_change_field($ret, 'uc_order_products', 'cost', 'cost', array('type' => 'numeric', 'precision' => 10, 'scale' => 2, 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_order_products', 'price', 'price', array('type' => 'numeric', 'precision' => 10, 'scale' => 2, 'not null' => TRUE, 'default' => 0));

  return $ret;
}

/**
 * Add the ability to log IPs with each order taken.
 */
function uc_order_update_6002() {
  $ret = array();

  $host_schema = array(
    'description' => 'Host IP address of the person paying for the order.',
    'type' => 'varchar',
    'length' => 255,
    'not null' => TRUE,
    'default' => '',
  );

  if (!db_column_exists('uc_orders', 'host')) {
    db_add_field($ret, 'uc_orders', 'host', $host_schema);
  }

  return $ret;
}

/**
 * Make the numeric fields signed for Postgres compatibility.
 */
function uc_order_update_6003() {
  $ret = array();

  db_change_field($ret, 'uc_order_products', 'cost', 'cost', array('type' => 'numeric', 'precision' => 10, 'scale' => 2, 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_order_products', 'price', 'price', array('type' => 'numeric', 'precision' => 10, 'scale' => 2, 'not null' => TRUE, 'default' => 0));

  return $ret;
}

function uc_order_update_6004() {
  $ret = array();

  db_change_field($ret, 'uc_orders', 'order_total', 'order_total', array('type' => 'numeric', 'precision' => 15, 'scale' => 3, 'not null' => TRUE, 'default' => 0.0));
  db_change_field($ret, 'uc_order_line_items', 'amount', 'amount', array('type' => 'numeric', 'precision' => 15, 'scale' => 3, 'not null' => TRUE, 'default' => 0.0));
  db_change_field($ret, 'uc_order_products', 'cost', 'cost', array('type' => 'numeric', 'precision' => 15, 'scale' => 3, 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_order_products', 'price', 'price', array('type' => 'numeric', 'precision' => 15, 'scale' => 3, 'not null' => TRUE, 'default' => 0));

  return $ret;
}

/**
 * Replace all instances of 'delete any order' with 'unconditionally delete orders' in the permissions table.
 */
function uc_order_update_6005() {
  $ret = array();

  $result = db_query("SELECT * FROM {permission}");
  while ($perm = db_fetch_object($result)) {
    $perm->perm = str_replace("delete any order", "unconditionally delete orders", $perm->perm);
    drupal_write_record('permission', $perm, 'pid');
  }
  $ret[] = array('success' => TRUE, 'query' => "Replaced all instances of 'delete any order' with 'unconditionally delete orders' in the permissions table.");

  return $ret;
}

/**
 * Change to signed floats.
 */
function uc_order_update_6006() {
  $ret = array();

  $schema = array(
    'weight' => array(
      'description' => 'The physical weight.',
      'type' => 'float',
      'not null' => TRUE,
      'default' => 0.0,
    ),
  );
  db_change_field($ret, 'uc_order_products', 'weight', 'weight', $schema['weight']);

  return $ret;
}

/**
 * Add data field to uc_order_line_items.
 */
function uc_order_update_6007() {

  $ret = array();

  if (!db_column_exists('uc_order_line_items', 'data')) {
    db_add_field($ret, 'uc_order_line_items', 'data', array('type' => 'text'));
  }

  return $ret;
}

/**
 * Moved to 6010 to take care of a broken release.
 */
function uc_order_update_6008() {
  return array();
}

function uc_order_update_6009() {
  $ret = array();

  $count = 0;
  $result = db_query("SELECT pid, actions FROM {ca_predicates} WHERE actions LIKE '%%uc_order_email_invoice%%'");
  while ($predicate = db_fetch_object($result)) {
    $save = FALSE;
    $actions = unserialize($predicate->actions);
    foreach ($actions as $key => $action) {
      if ($action['#name'] == 'uc_order_email_invoice') {
        unset($actions[$key]['#settings']['format']);
        $save = TRUE;
      }
    }
    if ($save) {
      db_query("UPDATE {ca_predicates} SET actions = '%s' WHERE pid = %d", serialize($actions), $predicate->pid);
      $count++;
    }
  }

  $t = get_t();
  $ret[] = array('success' => TRUE, 'query' => $t('Fixed %count predicates with the action "uc_order_email_invoice".', array('%count' => $count)));

  return $ret;
}

/**
 * Remove new users' passwords from order data.
 */
function uc_order_update_6010(&$sandbox) {
  $ret = array();

  if (!isset($sandbox['progress'])) {
    $sandbox['progress'] = 0;
    $sandbox['current_order_id'] = 0;
    $sandbox['max'] = db_result(db_query("SELECT COUNT(order_id) FROM {uc_orders} WHERE data LIKE '%%new_user%%'"));
  }

  $limit = 100;

  $result = db_query_range("SELECT order_id, data FROM {uc_orders} WHERE data LIKE '%%new_user%%' AND order_id > %d ORDER BY order_id", $sandbox['current_order_id'], 0, $limit);
  while ($order = db_fetch_object($result)) {
    $order->data = unserialize($order->data);
    if (isset($order->data['new_user']['pass'])) {
      unset($order->data['new_user']['pass']);
      db_query("UPDATE {uc_orders} SET data = '%s' WHERE order_id = %d", serialize($order->data), $order->order_id);
    }

    $sandbox['progress']++;
    $sandbox['current_order_id'] = $order->order_id;
  }

  $t = get_t();
  $ret[] = array('success' => TRUE, 'query' => $t("Removed new users' passwords from order data."));

  $ret['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);

  return $ret;
}

/**
 * Add a total product quantity column to {uc_orders}.
 */
function uc_order_update_6011() {
  $ret = array();

  $spec = array(
    'description' => 'The total product quantity of the order.',
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
  );
  db_add_field($ret, 'uc_orders', 'product_count', $spec);

  return $ret;
}

/**
 * Populate the total product quantity.
 */
function uc_order_update_6012(&$sandbox) {
  $ret = array();

  if (!isset($sandbox['progress'])) {
    $sandbox['progress'] = 0;
    $sandbox['current_order_id'] = 0;
    $sandbox['max'] = db_result(db_query("SELECT COUNT(DISTINCT order_id) FROM {uc_order_products} WHERE order_id <> 0"));
  }

  $limit = 100;

  $result = db_query_range("SELECT order_id, SUM(qty) AS product_count FROM {uc_order_products} WHERE order_id > %d GROUP BY order_id", $sandbox['current_order_id'], 0, $limit);
  while ($row = db_fetch_object($result)) {
    db_query("UPDATE {uc_orders} SET product_count = %d WHERE order_id = %d", $row->product_count, $row->order_id);

    $sandbox['progress']++;
    $sandbox['current_order_id'] = $row->order_id;
  }


  $ret['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);

  if ($ret['#finished'] == 1) {
    $t = get_t();
    $ret[] = array('success' => TRUE, 'query' => $t("Populated the product count column for {uc_orders}."));
  }

  return $ret;
}

/**
 * Convert the settings for the uc_order_condition_has_products to models.
 */
function uc_order_update_6013() {
  $ret = array();

  $models = array();
  $count = 0;

  $result = db_query("SELECT pid, conditions FROM {ca_predicates} WHERE conditions LIKE '%%uc_order_condition_has_products%%'");
  while ($predicate = db_fetch_object($result)) {
    $conditions = unserialize($predicate->conditions);

    $save = uc_order_6013_condition_helper($conditions['#conditions'], $predicate->pid);

    if ($save) {
      db_query("UPDATE {ca_predicates} SET conditions = '%s' WHERE pid = '%s'", serialize($conditions), $predicate->pid);
      $count++;
    }
  }

  $t = get_t();
  $ret[] = array('success' => TRUE, 'query' => $t('Fixed %count predicates with the condition "uc_order_condition_has_products".', array('%count' => $count)));

  return $ret;
}

function uc_order_6013_condition_helper(&$conditions, $pid, $save = FALSE) {
  foreach ($conditions as $key => &$condition) {
    if (isset($condition['#conditions'])) {
      $save = uc_order_6013_condition_helper($condition['#conditions'], $pid, $save);
    }
    else {
      if ($condition['#name'] == 'uc_order_condition_has_products' && isset($condition['#settings']['products'])) {
        $save = TRUE;
        $products = array();

        foreach ($condition['#settings']['products'] as $x => $nid) {
          // The "Any" setting will be an empty string.
          if (is_numeric($nid)) {
            if (!isset($models[$nid])) {
              // Get the latest revision's model.
              $models[$nid] = db_result(db_query("SELECT p.model FROM {uc_products} AS p LEFT JOIN {node} AS n ON n.vid = p.vid WHERE n.nid = %d", $nid));
            }

            $model = $models[$nid];
          }
          else {
            $model = $nid;
          }

          $condition['#settings']['products'][$x] = $model;
        }
      }
    }
  }

  return $save;
}

/**
 * Change currency fields to numeric(16,5).
 */
function uc_order_update_6014() {
  $ret = array();

  db_change_field($ret, 'uc_orders', 'order_total', 'order_total', array('type' => 'numeric', 'precision' => 16, 'scale' => 5, 'not null' => TRUE, 'default' => 0.0));
  db_change_field($ret, 'uc_order_line_items', 'amount', 'amount', array('type' => 'numeric', 'precision' => 16, 'scale' => 5, 'not null' => TRUE, 'default' => 0.0));
  db_change_field($ret, 'uc_order_products', 'cost', 'cost', array('type' => 'numeric', 'precision' => 16, 'scale' => 5, 'not null' => TRUE, 'default' => 0));
  db_change_field($ret, 'uc_order_products', 'price', 'price', array('type' => 'numeric', 'precision' => 16, 'scale' => 5, 'not null' => TRUE, 'default' => 0));

  return $ret;
}

/**
 * Check for old .itpl.php invoice template files.
 */
function uc_order_update_6015() {
  $ret = array();

  $dir = drupal_get_path('module', 'uc_order') .'/templates';
  $templates = file_scan_directory($dir, '.*\.itpl\.php', array('.', '..', 'CVS'), 0, FALSE);

  if (!empty($templates)) {
    $ret[] = array('success' => FALSE, 'query' => 'Old Ubercart .itpl.php invoice templates were found! These must be manually upgraded to use the Drupal theme layer. See the <a href="http://www.ubercart.org/docs/developer/17385/changing_invoice_templates_ubercart_23_and_later">template upgrade guide on Ubercart.org</a> for details.');
  }

  return $ret;
}

/**
 * Remove unused setting.
 */
function uc_order_update_6016() {
  variable_del('uc_ubrowser_product_select');
  return array();
}

/**
 * Change size of {uc_order_products}.title and {uc_order_line_items}.title
 * to match size of {node}.title.
 */
function uc_order_update_6017() {
  $ret = array();

  db_change_field($ret, 'uc_order_products', 'title', 'title', array(
    'description' => 'The product title, from {node}.title.',
    'type' => 'varchar',
    'length' => 255,
    'not null' => TRUE,
    'default' => '',
  ));

  db_change_field($ret, 'uc_order_line_items', 'title', 'title', array(
    'description' => 'The label of the line item.',
    'type' => 'varchar',
    'length' => 255,
    'not null' => TRUE,
    'default' => '',
  ));

  return $ret;
}

/**
 * Add currency code field.
 */
function uc_order_update_6018() {
  $ret = array();

  db_add_field($ret, 'uc_orders', 'currency', array(
    'type' => 'char',
    'length' => 3,
    'not null' => TRUE,
    'default' => '',
  ));

  db_query("UPDATE {uc_orders} SET currency = '%s'", variable_get('uc_currency_code', 'USD'));

  return $ret;
}

/**
 * Add indexes so product and customer reports are usable with large datasets.
 */
function uc_order_update_6019() {
  $ret = array();

  db_add_index($ret, 'uc_order_products', 'qty', array('qty'));
  db_add_index($ret, 'uc_order_products', 'nid', array('nid'));

  return $ret;
}

/**
 * Increase maximum order item quantity.
 */
function uc_order_update_6020() {
  $ret = array();

  db_change_field($ret, 'uc_order_products', 'qty', 'qty', array(
    'description' => 'The number of the same product ordered.',
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
   ));

  return $ret;
}

/**
 * Delete unwanted sensitive data.
 */
function uc_order_update_6200() {
  $ret = array();

  $result = db_query("SELECT order_id, data FROM {uc_orders} WHERE data LIKE '%s:4:\"pass\"%'");
  while ($row = db_fetch_object($result)) {
    $data = unserialize($row->data);
    if (isset($data['new_user']['pass'])) {
      unset($data['new_user']['pass']);
      db_query("UPDATE {uc_orders} SET data = '%s' WHERE order_id = %d", serialize($data), $row->order_id);
    }
  }

  variable_del('uc_order_cron_last');

  $ret[] = array('success' => TRUE, 'query' => 'Deleted unwanted sensitive data.');
  return $ret;
}
