Index: README.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_edi/README.txt,v
retrieving revision 1.4
diff -u -p -r1.4 README.txt
--- README.txt	24 Nov 2010 16:37:17 -0000	1.4
+++ README.txt	13 Dec 2010 16:38:09 -0000
@@ -38,15 +38,11 @@ To submit bug reports and feature sugges
   - Update an order after export predicate:
     admin/store/ca/uc_edi_order_export_update/edit
   - Ubercart EDI settings page: admin/store/settings/edi
-  - Manual import/export form: admin/store/edi
+  - Manual order import form: admin/store/edi/orders/import
+  - Manual order export form: admin/store/edi/orders/export
   - Ubercart EDI permissions: admin/user/permissions#module-uc_edi
 
 * Export Configuration
-  - Directories
-    Set the "Export directory" and "Export archive directory" fields to
-    directories where export files will be written too, preferably outside
-    the Drupal root folder.
-
   - Methods
     Ubercart EDI has 3 methods for exporting orders. You can export orders "On
     checkout completion", "At a specified interval" or "Manually".
@@ -85,7 +81,7 @@ To submit bug reports and feature sugges
 
     - Manually
       To export orders manually:
-      - Use the "Manual import/export form".
+      - Use the "Manual order export form".
 
   - Template files
     EDI templates use Drupal's theme system to allow complete control over
@@ -108,7 +104,7 @@ To submit bug reports and feature sugges
       function which lets you pass any data to all EDI templates as a variable.
       The default template_preprocess_uc_edi() function adds all correctly
       defined order tokens to the template files as variables. For a list of
-      order token variables spcifically added by Ubercart EDI, see the
+      order token variables specifically added by Ubercart EDI, see the
       documentation block at the top of the default template file.
 
     - Testing
@@ -119,8 +115,19 @@ To submit bug reports and feature sugges
       import process of your fulfillment houses.
       *This order export form does not update the order status and should only
       be used for testing template files or viewing and saving orders that have
-      already been processed. For manually exporting orders, the Manual
-      import/export form should be used.*
+      already been processed. For manually exporting orders, the "Manual Order
+      Export Form" should be used.*
+
+  - Delivery Methods
+    Ubercart EDI offers different methods for delivering export files to
+    locations. Included with Ubercart EDI are the filesystem and e-mail
+    delivery methods, each implemented by its own sub-module. See a delivery
+    methods help page for more information on that delivery method. Other
+    modules can provide their own delivery methods by implementing the
+    uc_edi_export_delivery_methods hook.
+
+    - E-mail: Deliver export files to a specified e-mail address.
+    - Filesystem: Deliver export files to the local filesystem.
 
   - Update an order after export
     Ubercart EDI leverages "Conditional Actions" for updating orders after a
@@ -173,9 +180,6 @@ To submit bug reports and feature sugges
   - administer edi orders
     Users in roles with "administer edi orders" permissions can modify module
     settings and manually import and export orders.
-  - download edi orders
-    Users in roles with the "download edi orders" permissions can download and
-    archive EDI order export files.
 
 
 -- CONTACT --
Index: uc_edi.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_edi/uc_edi.admin.inc,v
retrieving revision 1.2
diff -u -p -r1.2 uc_edi.admin.inc
--- uc_edi.admin.inc	24 Nov 2010 16:37:17 -0000	1.2
+++ uc_edi.admin.inc	13 Dec 2010 16:38:09 -0000
@@ -7,51 +7,38 @@
  */
 
 /**
- * Form builder for the general EDI settings form.
+ * Form builder for the EDI import settings form.
  *
- * @see uc_edi_settings_form_validate()
+ * @see uc_edi_settings_import_form_validate()
  * @ingroup forms.
  */
-function uc_edi_settings_form() {
+function uc_edi_settings_import_form() {
   if ((trim(variable_get('uc_edi_order_import_dir', '')) == '' ||
-       trim(variable_get('uc_edi_order_import_archive_dir', '')) == '' ||
-       trim(variable_get('uc_edi_order_export_dir', '')) == '') &&
+       trim(variable_get('uc_edi_order_import_archive_dir', '')) == '') &&
        empty($_POST['form_id'])) {
     drupal_set_message(t('One or more required directory fields need to be filled out. It is recommended that you use a directory outside of your document root for improved security. You may specify an absolute path on the server or a relative path from the Drupal directory.'), 'error');
   }
 
-  $form['import'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Import settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-  );
-  $form['import']['orders'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Order import settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['import']['orders']['uc_edi_order_import_dir'] = array(
+  $form['uc_edi_order_import_dir'] = array(
     '#type' => 'textfield',
     '#title' => t('Import directory'),
     '#description' => t('The directory path to search for data files ready for import. Omit the trailing slash.'),
     '#default_value' => variable_get('uc_edi_order_import_dir', ''),
   );
-  $form['import']['orders']['uc_edi_order_import_archive_dir'] = array(
+  $form['uc_edi_order_import_archive_dir'] = array(
     '#type' => 'textfield',
     '#title' => t('Import archive directory'),
     '#description' => t('The directory path to move processed data files to for storage. Omit the trailing slash.'),
     '#default_value' => variable_get('uc_edi_order_import_archive_dir', ''),
   );
-  $form['import']['orders']['uc_edi_order_import_extension'] = array(
+  $form['uc_edi_order_import_extension'] = array(
     '#type' => 'textfield',
     '#title' => t('Import file extension'),
     '#description' => t('Enter the file extension expected for order import files.'),
     '#default_value' => variable_get('uc_edi_order_import_extension', 'edi'),
     '#maxlength' => 6,
   );
-  $form['import']['orders']['uc_edi_order_import_delimiter'] = array(
+  $form['uc_edi_order_import_delimiter'] = array(
     '#type' => 'select',
     '#title' => t('Import pattern delimiter'),
     '#options' => array(
@@ -61,7 +48,7 @@ function uc_edi_settings_form() {
     ),
     '#default_value' => variable_get('uc_edi_order_import_delimiter', '\t'),
   );
-  $form['import']['orders']['uc_edi_order_import_freq'] = array(
+  $form['uc_edi_order_import_freq'] = array(
     '#type' => 'select',
     '#title' => t('Import frequency'),
     '#description' => t('The frequency at which automatic imports should occur.'),
@@ -78,91 +65,63 @@ function uc_edi_settings_form() {
   foreach (uc_order_status_list('general') as $status) {
     $options[$status['id']] = $status['title'];
   }
-  $form['import']['orders']['uc_edi_order_imported_status'] = array(
+  $form['uc_edi_order_imported_status'] = array(
     '#type' => 'select',
     '#title' => t('Imported order status'),
     '#description' => t('Select a status for orders to be moved to when a response is received for that order.'),
     '#options' => $options,
     '#default_value' => variable_get('uc_edi_order_imported_status', 'completed'),
   );
-  $form['import']['orders']['uc_edi_order_import_rules'] = array(
+  $form['uc_edi_order_import_rules'] = array(
     '#type' => 'textarea',
     '#title' => t('Order import rules'),
     '#description' => t('Order import rules have set patterns and keywords. <a href="!url">Click here</a> for help.', array('!url' => url('admin/help/uc_edi'))),
     '#default_value' => variable_get('uc_edi_order_import_rules', 'ORD|id:2|us|oc:Your order has shipped via #3 with tracking number #4.'),
   );
 
-  $form['export'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Export settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-  );
-  $form['export']['orders'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Order export settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['export']['orders']['uc_edi_order_export_dir'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Export directory'),
-    '#description' => t('The directory path for exported data files. Omit the trailing slash.'),
-    '#default_value' => variable_get('uc_edi_order_export_dir', ''),
-  );
-  $form['export']['orders']['uc_edi_order_export_archive_dir'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Export archive directory'),
-    '#description' => t('The directory path for archiving exported data files. Omit the trailing slash.'),
-    '#default_value' => variable_get('uc_edi_order_export_archive_dir', ''),
-  );
-  $form['export']['orders']['uc_edi_order_export_prefix'] = array(
+  $form = system_settings_form($form);
+
+  return $form;
+}
+
+/**
+ * Handels validation of the EDI import settings form.
+ *
+ * @see uc_edi_settings_import_form()
+ */
+function uc_edi_settings_import_form_validate($form, &$form_state) {
+  if (trim($form_state['values']['uc_edi_order_import_dir']) != '' &&
+      !is_dir($form_state['values']['uc_edi_order_import_dir'])) {
+    form_set_error('uc_edi_order_import_dir', t('You have specified a non-existent order import directory.'));
+  }
+  if (trim($form_state['values']['uc_edi_order_import_archive_dir']) != '' &&
+      !is_dir($form_state['values']['uc_edi_order_import_archive_dir'])) {
+    form_set_error('uc_edi_order_import_archive_dir', t('You have specified a non-existent order import archive directory.'));
+  }
+}
+
+/**
+ * Form builder for the EDI export settings form.
+ *
+ * @see uc_edi_settings_export_form_validate()
+ * @ingroup forms.
+ */
+function uc_edi_settings_export_form() {
+  $form['filesystem']['uc_edi_order_export_prefix'] = array(
     '#type' => 'textfield',
     '#title' => t('Export file prefix'),
     '#description' => t('Enter a prefix to use for your exported order files. Leave blank for none.'),
     '#default_value' => variable_get('uc_edi_order_export_prefix', 'export-'),
     '#maxlength' => 10,
   );
-  $form['export']['orders']['uc_edi_order_export_extension'] = array(
+  $form['filesystem']['uc_edi_order_export_extension'] = array(
     '#type' => 'textfield',
     '#title' => t('Export file extension'),
     '#description' => t('Enter the file extension to use for your exported order files.'),
     '#default_value' => variable_get('uc_edi_order_export_extension', 'edi'),
     '#maxlength' => 6,
   );
-  $form['export']['orders']['mail'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Export by email settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-  );
-  $form['export']['orders']['mail']['uc_edi_order_export_mail_to'] = array(
-    '#type' => 'textfield',
-    '#title' => t('E-mail a copy of the report file to this address (Requires the Mimemail module)'),
-    '#description' => t('If left blank, no e-mail will be sent.'),
-    '#disabled' => !(module_exists('mimemail')),
-    '#default_value' => variable_get('uc_edi_order_export_mail_to', ''),
-  );
-  $form['export']['orders']['mail']['uc_edi_order_export_mail_from'] = array(
-    '#type' => 'textfield',
-    '#title' => t('From address'),
-    '#description' => t('If left blank, the default site email address @mail will be used', array('@mail' => variable_get('site_mail', 'test@example.com'))),
-    '#disabled' => !(module_exists('mimemail')),
-    '#default_value' => variable_get('uc_edi_order_export_mail_from', ''),
-  );
-  $form['export']['orders']['mail']['uc_edi_order_export_mail_subject'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Message Subject'),
-    '#disabled' => !(module_exists('mimemail')),
-    '#default_value' => variable_get('uc_edi_order_export_mail_subject', ''),
-  );
-   $form['export']['orders']['mail']['uc_edi_order_export_mail_body'] = array(
-    '#type' => 'textarea',
-    '#title' => t('E-mail Message'),
-    '#disabled' => !(module_exists('mimemail')),
-    '#default_value' => variable_get('uc_edi_order_export_mail_body', ''),
-  );
-  $form['export']['orders']['uc_edi_order_export_method'] = array(
+  $form['uc_edi_order_export_method'] = array(
     '#type' => 'radios',
     '#title' => t('Export method'),
     '#description' => t('The method used to export the order.'),
@@ -174,19 +133,19 @@ function uc_edi_settings_form() {
     '#default_value' => variable_get('uc_edi_order_export_method', 'cron'),
     '#ahah' => array(
       'method' => 'replace',
-      'path' => 'admin/store/settings/edi/order-export-method-js',
+      'path' => 'admin/store/edi/export/method-js',
       'wrapper' => 'method-sub-wrapper',
     ),
   );
-  $form['export']['orders']['uc_edi_order_export_method_sub'] = uc_edi_order_export_method();
-  $form['export']['orders']['uc_edi_order_export_template'] = array(
+  $form['uc_edi_order_export_method_sub'] = uc_edi_order_export_method();
+  $form['uc_edi_order_export_template'] = array(
     '#type' => 'select',
     '#title' => t('Export template'),
     '#description' => t('Select the export template to use.<br />This is separate from the template used when exporting on checkout completion which is configured through <a href="!url">Conditional actions</a>.', array('!url' => url(CA_UI_PATH))),
     '#options' => uc_edi_template_options(),
     '#default_value' => variable_get('uc_edi_order_export_template', 'default'),
   );
-  $form['export']['orders']['uc_edi_order_export_next_batch_id'] = array(
+  $form['uc_edi_order_export_next_batch_id'] = array(
     '#type' => 'textfield',
     '#title' => t('Next order batch ID'),
     '#description' => t('<b>DISABLED:</b> Adjusting this value may result in duplicate batch IDs. Adjustments must be made in the database.<br />The batch ID is incremented for every export and useful for tracking.'),
@@ -248,7 +207,7 @@ function uc_edi_order_export_method() {
     '#ahah' => array(
       'event' => 'change',
       'method' => 'replace',
-      'path' => 'admin/store/settings/edi/order-export-method-js',
+      'path' => 'admin/store/edi/export/method-js',
       'wrapper' => 'method-sub-wrapper',
     ),
   );
@@ -317,40 +276,6 @@ function uc_edi_order_export_method_js()
 }
 
 /**
- * Handels validation of the general EDI settings form.
- *
- * @see uc_edi_settings_form()
- */
-function uc_edi_settings_form_validate($form, &$form_state) {
-  if (trim($form_state['values']['uc_edi_order_import_dir']) != '' &&
-      !is_dir($form_state['values']['uc_edi_order_import_dir'])) {
-    form_set_error('uc_edi_order_import_dir', t('You have specified a non-existent order import directory.'));
-  }
-  if (trim($form_state['values']['uc_edi_order_import_archive_dir']) != '' &&
-      !is_dir($form_state['values']['uc_edi_order_import_archive_dir'])) {
-    form_set_error('uc_edi_order_import_archive_dir', t('You have specified a non-existent order import archive directory.'));
-  }
-  if (trim($form_state['values']['uc_edi_order_export_dir']) != '' &&
-      !is_dir($form_state['values']['uc_edi_order_export_dir'])) {
-    form_set_error('uc_edi_order_export_dir', t('You have specified a non-existent order export directory.'));
-  }
-  if (trim($form_state['values']['uc_edi_order_export_archive_dir']) != '' &&
-      !is_dir($form_state['values']['uc_edi_order_export_archive_dir'])) {
-    form_set_error('uc_edi_order_export_archive_dir', t('You have specified a non-existent order export archive directory.'));
-  }
-  if (!valid_email_address($form_state['values']['uc_edi_order_export_mail_to']) &&
-      !empty($form_state['values']['uc_edi_order_export_mail_to']) &&
-      module_exists('mimemail')) {
-    form_set_error('uc_edi_order_export_mail_to', t('You have specified an invalid "to" e-mail address.'));
-  }
-  if (!valid_email_address($form_state['values']['uc_edi_order_export_mail_from']) &&
-      !empty($form_state['values']['uc_edi_order_export_mail_from']) &&
-      module_exists('mimemail')) {
-    form_set_error('uc_edi_order_export_mail_from', t('You have specified an invalid "from" e-mail address.'));
-  }
-}
-
-/**
  * Verify Conditional Actions is configured to work with Ubercart EDI.
  *
  * @param $method
@@ -413,15 +338,15 @@ function uc_edi_order_export_status_vali
 }
 
 /**
- * Handler for submitting the settings form.
+ * Handler for submitting the export settings form.
  */
-function uc_edi_settings_form_submit($form, &$form_state) {
+function uc_edi_settings_export_form_submit($form, &$form_state) {
   // Call the default submit handler first.
   system_settings_form_submit($form, $form_state);
 
   // If the export method has changed from or to 'checkout'.
-  if ($form['export']['orders']['uc_edi_order_export_method']['#default_value'] != $form['export']['orders']['uc_edi_order_export_method']['#value'] &&
-     ($form['export']['orders']['uc_edi_order_export_method']['#default_value'] == 'checkout' || $form['export']['orders']['uc_edi_order_export_method']['#value'] == 'checkout')) {
+  if ($form['uc_edi_order_export_method']['#default_value'] != $form['uc_edi_order_export_method']['#value'] &&
+     ($form['uc_edi_order_export_method']['#default_value'] == 'checkout' || $form['uc_edi_order_export_method']['#value'] == 'checkout')) {
     // Load the order export predicate.
     $predicate = ca_load_predicate('uc_edi_order_export');
     $update = FALSE;
@@ -451,22 +376,45 @@ function uc_edi_settings_form_submit($fo
 }
 
 /**
- * Form builder for the manual import/export form.
+ * Form builder for the EDI export delivery methods settings form.
  *
- * @see uc_edi_manual_form_order_import_submit()
- * @see uc_edi_manual_form_order_import_reset()
- * @see uc_edi_manual_form_order_export_submit()
- * @see uc_edi_manual_form_order_export_reset()
- * @ingroup forms
+ * @see uc_edi_export_delivery_methods_form_validate()
+ * @ingroup forms.
  */
-function uc_edi_manual_form() {
-  $form['import'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Order import details'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
+function uc_edi_export_delivery_methods_form() {
+  $methods = uc_edi_export_delivery_method_list();
+
+  $form['methods_info'] = array(
+    '#value' => t('The settings forms below are for the export delivery methods defined by enabled modules. Click a name to expand its options and adjust the settings accordingly.') .'</div><br />',
   );
 
+  foreach ($methods as $method) {
+    $form[$method['id']] = array(
+      '#type' => 'fieldset',
+      '#title' => $method['title'],
+      '#description' => $method['description'],
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+    );
+    $form[$method['id']]['uc_edi_export_delivery_method_' . $method['id']] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Enabled'),
+      '#default_value' => variable_get('uc_edi_export_delivery_method_' . $method['id'], FALSE),
+    );
+    $form = array_merge_recursive($form, $method['callbacks']['settings']('settings'));
+  }
+
+  return system_settings_form($form);
+}
+
+/**
+ * Form builder for the order import manual form.
+ *
+ * @see uc_edi_order_import_manual_form_submit()
+ * @see uc_edi_order_import_manual_form_reset()
+ * @ingroup forms
+ */
+function uc_edi_order_import_manual_form() {
   // Grab all valid files in the import directory.
   $files = uc_edi_get_import_files(variable_get('uc_edi_order_import_dir', ''), variable_get('uc_edi_order_import_extension', 'edi'));
 
@@ -480,20 +428,51 @@ function uc_edi_manual_form() {
     $seconds = t('(auto import disabled) 0');
   }
 
-  $form['import']['import_info'] = array(
+  $form['import_info'] = array(
     '#value' => '<div><b>' . t('There are !count files ready to import in !seconds seconds:', array('!count' => count($files), '!seconds' => $seconds < 0 ? 0 : $seconds)) . '</b><br />' . implode(', ', $files) . '<p></p></div>',
   );
-  $form['import']['import_now'] = array(
+  $form['import_now'] = array(
     '#type' => 'submit',
-    '#submit' => array('uc_edi_manual_form_order_import_submit'),
+    '#submit' => array('uc_edi_order_import_manual_form_submit'),
     '#value' => t('Import orders now'),
   );
-  $form['import']['reset_import'] = array(
+  $form['reset_import'] = array(
     '#type' => 'submit',
-    '#submit' => array('uc_edi_manual_form_order_import_reset'),
+    '#submit' => array('uc_edi_order_import_manual_form_reset'),
     '#value' => t('Reset import timer'),
   );
 
+  return $form;
+}
+
+/**
+ * Handles manual order import submissions.
+ *
+ * @see uc_edi_order_import_manual_form()
+ */
+function uc_edi_order_import_manual_form_submit($form, &$form_state) {
+  uc_edi_import_orders();
+  drupal_set_message(t('Order import files have been processed.'));
+}
+
+/**
+ * Handles resetting the order import timer.
+ *
+ * @see uc_edi_order_import_manual_form()
+ */
+function uc_edi_order_import_manual_form_reset($form, &$form_state) {
+  variable_set('uc_edi_order_import_last', time());
+  drupal_set_message(t('Order import timer reset.'));
+}
+
+/**
+ * Form builder for the order export manual form.
+ *
+ * @see uc_edi_order_export_manual_form_submit()
+ * @see uc_edi_order_export_manual_form_reset()
+ * @ingroup forms
+ */
+function uc_edi_order_export_manual_form() {
   // Retrieve orders ready for export from database.
   $result = db_query("SELECT order_id FROM {uc_orders} WHERE order_status = '%s' ORDER BY order_id", variable_get('uc_edi_order_export_status', 'edi_export'));
   $orders = array();
@@ -519,13 +498,6 @@ function uc_edi_manual_form() {
     }
   }
 
-  $form['export'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Order export details'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-  );
-
   switch (variable_get('uc_edi_order_export_method', 'cron')) {
     case 'checkout':
       $message = t('Orders are configured to export on checkout completion. !count order(s) require manual export.', array('!count' => $count));
@@ -544,12 +516,12 @@ function uc_edi_manual_form() {
       break;
   }
 
-  $form['export']['export_info'] = array(
+  $form['export_info'] = array(
     '#value' => '<div><b>' . $message . '</b><br />' . implode(', ', $orders) . '<p></p></div>',
   );
 
   // Display a fieldset with a preview of the export file.
-  $form['export']['export_preview'] = array(
+  $form['export_preview'] = array(
     '#type' => 'fieldset',
     '#title' => t('Order export preview'),
     '#collapsible' => TRUE,
@@ -562,18 +534,18 @@ function uc_edi_manual_form() {
   elseif (empty($preview)) {
     $preview = t('No output was generated. Check your template files.');
   }
-  $form['export']['export_preview']['contents'] = array(
-    '#value' => '<div><pre>' . $preview . '</pre></div>',
+  $form['export_preview']['contents'] = array(
+    '#value' => '<div><pre>' . check_plain($preview) . '</pre></div>',
   );
 
-  $form['export']['export_now'] = array(
+  $form['export_now'] = array(
     '#type' => 'submit',
-    '#submit' => array('uc_edi_manual_form_order_export_submit'),
+    '#submit' => array('uc_edi_order_export_manual_form_submit'),
     '#value' => t('Export orders now'),
   );
-  $form['export']['reset_export'] = array(
+  $form['reset_export'] = array(
     '#type' => 'submit',
-    '#submit' => array('uc_edi_manual_form_order_export_reset'),
+    '#submit' => array('uc_edi_order_export_manual_form_reset'),
     '#value' => t('Reset export timer'),
   );
 
@@ -581,31 +553,11 @@ function uc_edi_manual_form() {
 }
 
 /**
- * Handles manual order import submissions.
- *
- * @see uc_edi_manual_form()
- */
-function uc_edi_manual_form_order_import_submit($form, &$form_state) {
-  uc_edi_import_orders();
-  drupal_set_message(t('Order import files have been processed.'));
-}
-
-/**
- * Handles resetting the order import timer.
- *
- * @see uc_edi_manual_form()
- */
-function uc_edi_manual_form_order_import_reset($form, &$form_state) {
-  variable_set('uc_edi_order_import_last', time());
-  drupal_set_message(t('Order import timer reset.'));
-}
-
-/**
  * Handles manual order export submissions.
  *
- * @see uc_edi_manual_form()
+ * @see uc_edi_order_export_manual_form()
  */
-function uc_edi_manual_form_order_export_submit($form, &$form_state) {
+function uc_edi_order_export_manual_form_submit($form, &$form_state) {
   // Export orders.
    $filename = uc_edi_export_orders();
 
@@ -623,92 +575,14 @@ function uc_edi_manual_form_order_export
 /**
  * Handles resetting the order export timer.
  *
- * @see uc_edi_manual_form()
+ * @see uc_edi_order_export_manual_form()
  */
-function uc_edi_manual_form_order_export_reset($form, &$form_state) {
+function uc_edi_order_export_manual_form_reset($form, &$form_state) {
   variable_set('uc_edi_order_export_last', time());
   drupal_set_message(t('Order export timer reset.'));
 }
 
 /**
- * Creates a table with links for downloading and archiving export files.
- *
- * @return string
- *   An HTML table of order export files to be downloaded or archived if order
- *   export files were found, otherwise a default message explaining that no
- *   order export files were found.
- */
-function uc_edi_export_download() {
-  $output = '';
-
-  $files = file_scan_directory(variable_get('uc_edi_order_export_dir', ''), '.*\\.' . variable_get('uc_edi_order_export_extension', 'edi'), array('.', '..', 'CVS'), 0, FALSE);
-  $rows = array();
-  foreach ($files as $file) {
-    $rows[] = array($file->basename, t('<a href="!url">Download</a>', array('!url' => url('admin/store/edi/download/file/' . $file->basename))), t('<a href="!url">Archive</a>', array('!url' => url('admin/store/edi/download/archive/' . $file->basename))));
-  }
-  $header = array(t('Order export file'), array('data' => t('Actions'), 'colspan' => 2));
-  if (count($rows)) {
-    $output .= theme('table', $header, $rows);
-  }
-  else {
-    $output .= t('No order EDI export files were found in the export directory.');
-  }
-
-  return $output;
-}
-
-/**
- * Allows an order export file to be downloaded.
- *
- * @param $filename
- *   The name of the order export file to be downloaded.
- */
-function uc_edi_order_export_download_file($filename = '') {
-  $file = variable_get('uc_edi_order_export_dir', '') . '/' . $filename;
-
-  if (file_exists($file)) {
-    $data = fopen($file, 'rb');
-    ob_end_clean();
-
-    $headers = array(
-      'Content-Length:' . filesize($file),
-      'Content-Disposition: attachment; filename="' . basename($file) . '"',
-      'Content-Type: application/octet-stream'
-    );
-    foreach ($headers as $header) {
-      $header = preg_replace('/\r?\n(?!\t| )/', '', $header);
-      drupal_set_header($header);
-    }
-
-    while (!feof($data)) {
-      print fread($data, 1024);
-    }
-    fclose($data);
-    exit();
-  }
-  else {
-    drupal_not_found();
-  }
-}
-
-/**
- * Archives an order export file.
- *
- * @param $filename
- *   The name of the order export file to be archived.
- */
-function uc_edi_order_export_archive_file($filename = '') {
-  if (@rename(variable_get('uc_edi_order_export_dir', '') . '/' . $filename, variable_get('uc_edi_order_export_archive_dir', '') . '/' . $filename)) {
-    drupal_set_message(t('The selected order export file %file was archived successfully.', array('%file' => $filename)));
-  }
-  else {
-    drupal_set_message(t('Problem archiving the order export file. Check your EDI settings and directory permissions.'), 'error');
-  }
-
-  drupal_goto('admin/store/edi/download');
-}
-
-/**
  * Generates a manual order export form for individual orders.
  */
 function uc_edi_order_export_form($form_state, $order) {
@@ -756,7 +630,7 @@ function uc_edi_order_export_form($form_
 function uc_edi_order_export_template(&$order, &$template) {
   // Create the order export string.
   $form = array(
-    '#value' => theme('uc_edi', $order, $template, TRUE, TRUE),
+    '#value' => check_plain(theme('uc_edi', $order, $template, TRUE, TRUE)),
   );
 
   // Add prefix and suffix elements.
Index: uc_edi.api.php
===================================================================
RCS file: uc_edi.api.php
diff -N uc_edi.api.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi.api.php	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,58 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Hooks provided by Ubercart EDI.
+ */
+
+/**
+ * Respond to EDI template definitions.
+ *
+ * This hook is invoked from uc_edi_template_list() when the Ubercart EDI
+ * settings page is loaded.
+ *
+ * @return
+ *   Array of EDI template names.
+ *
+ * @ingroup hooks
+ */
+function hook_uc_edi_templates() {
+  return array('default');
+}
+
+/**
+ * Respond to export delivery method definitions.
+ *
+ * This hook is invoked from uc_edi_export_delivery_method_list() when the
+ * Ubercart EDI Delivery Methods settings page is loaded and when an export is
+ * triggered.
+ *
+ * @return
+ *   An array containing the following keys.
+ *   - id: The machine readable name.
+ *   - title: The human readable name.
+ *   - description: A human readable description.
+ *   - callbacks: An array of callbacks for the supported operations.
+ *     - help: Return an HTML link to the delivery method specific help page
+ *       followed by a short description.
+ *     - settings: Returns an un-rendered settings form array to be added to
+ *       the Ubercart EDI Export Delivery Methods settings page.
+ *     - submit: Submits the export file found in $filepath for delivery.
+ *
+ * @ingroup hooks
+ */
+function hook_uc_edi_export_delivery_methods() {
+  $methods[] = array(
+    'id' => 'filesystem',
+    'title' => t('Filesystem'),
+    'description' => t('Deliver export files to the local filesystem.'),
+    'callbacks' => array(
+      'help' => 'uc_edi_filesystem_export_delivery_method_help',
+      'settings' => 'uc_edi_filesystem_export_delivery_method_form',
+      'submit' => 'uc_edi_filesystem_export_delivery_method_submit',
+    ),
+  );
+
+  return $methods;
+}
Index: uc_edi.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_edi/uc_edi.install,v
retrieving revision 1.5
diff -u -p -r1.5 uc_edi.install
--- uc_edi.install	24 Nov 2010 16:37:17 -0000	1.5
+++ uc_edi.install	13 Dec 2010 16:38:09 -0000
@@ -33,14 +33,8 @@ function uc_edi_uninstall() {
   variable_del('uc_edi_order_imported_status');
   variable_del('uc_edi_order_import_rules');
   variable_del('uc_edi_order_import_last');
-  variable_del('uc_edi_order_export_dir');
-  variable_del('uc_edi_order_export_archive_dir');
   variable_del('uc_edi_order_export_prefix');
   variable_del('uc_edi_order_export_extension');
-  variable_del('uc_edi_order_export_mail_to');
-  variable_del('uc_edi_order_export_mail_from');
-  variable_del('uc_edi_order_export_mail_subject');
-  variable_del('uc_edi_order_export_mail_body');
   variable_del('uc_edi_order_export_freq');
   variable_del('uc_edi_order_export_status');
   variable_del('uc_edi_order_export_template');
@@ -200,3 +194,96 @@ function uc_edi_update_6100() {
 
   return $return;
 }
+
+/**
+ * Implements hook_update_N().
+ */
+function uc_edi_update_6101() {
+  $return = array();
+
+  // Clear the menu cache.
+  menu_cache_clear_all();
+
+  // Configure the new Ubercart EDI filesystem module.
+  if (trim(variable_get('uc_edi_order_export_dir', '')) != '') {
+    // Install and enable the Ubercart EDI filesystem module.
+    require_once('includes/install.inc');
+    module_rebuild_cache();
+    drupal_install_modules(array('uc_edi_filesystem'));
+
+    // Create new and remove depricated variables.
+    variable_set('uc_edi_filesystem_export_dir', variable_get('uc_edi_order_export_dir', ''));
+    variable_del('uc_edi_order_export_dir');
+    variable_set('uc_edi_filesystem_export_archive_dir', variable_get('uc_edi_order_export_archive_dir', ''));
+    variable_del('uc_edi_order_export_archive_dir');
+
+    // Enable the export delivery method if the settings validate.
+    if (file_check_directory(variable_get('uc_edi_filesystem_export_dir', '')) &&
+        file_check_directory(variable_get('uc_edi_filesystem_export_archive_dir', ''))) {
+      // Enable the method.
+      variable_set('uc_edi_export_delivery_method_filesystem', TRUE);
+
+      $return[] = array(
+        'success' => TRUE,
+        'query' => 'The Ubercart EDI filesystem module has been installed and enabled and the filesystem export delivery method has been enabled.'
+      );
+    }
+    else {
+      $return[] = array(
+        'success' => TRUE,
+        'query' => 'The Ubercart EDI filesystem module has been installed and enabled but the filesystem export delivery method could not be enabled. Enable the module on the Ubercart EDI Export Delivery Methods settings page.'
+      );
+    }
+  }
+  else {
+    // Remove deprecated vaiables.
+    variable_del('uc_edi_order_export_dir');
+    variable_del('uc_edi_order_export_archive_dir');
+  }
+
+  // Configure the new Ubercart EDI e-mail module.
+  if (trim(variable_get('uc_edi_order_export_mail_to', '')) != '' &&
+      module_exists('mimemail')) {
+    // Install and enable the Ubercart EDI e-mail module.
+    require_once('includes/install.inc');
+    module_rebuild_cache();
+    drupal_install_modules(array('uc_edi_email'));
+
+    // Create new and remove depricated variables.
+    variable_set('uc_edi_email_from', variable_get('uc_edi_order_export_mail_from', ''));
+    variable_del('uc_edi_order_export_mail_from');
+    variable_set('uc_edi_email_to', variable_get('uc_edi_order_export_mail_to', ''));
+    variable_del('uc_edi_order_export_mail_to');
+    variable_set('uc_edi_email_subject', variable_get('uc_edi_order_export_mail_subject', ''));
+    variable_del('uc_edi_order_export_mail_subject');
+    variable_set('uc_edi_email_message', variable_get('uc_edi_order_export_mail_body', ''));
+    variable_del('uc_edi_order_export_mail_body');
+
+    // Enable the export delivery method if the settings validate.
+    if (valid_email_address(variable_get('uc_edi_email_to', '')) &&
+        valid_email_address(variable_get('uc_edi_email_to', ''))) {
+      // Enable the method.
+      variable_set('uc_edi_export_delivery_method_email', TRUE);
+
+      $return[] = array(
+        'success' => TRUE,
+        'query' => 'The Ubercart EDI e-mail module has been installed and enabled and the e-mail export delivery method has been enabled.'
+      );
+    }
+    else {
+      $return[] = array(
+        'success' => TRUE,
+        'query' => 'The Ubercart EDI e-mail module has been installed and enabled but the e-mail export delivery method could not be enabled. Enable the module on the Ubercart EDI Export Delivery Methods settings page.'
+      );
+    }
+  }
+  else {
+    // Remove deprecated vaiables.
+    variable_del('uc_edi_order_export_mail_from');
+    variable_del('uc_edi_order_export_mail_to');
+    variable_del('uc_edi_order_export_mail_subject');
+    variable_del('uc_edi_order_export_mail_body');
+  }
+
+  return $return;
+}
Index: uc_edi.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_edi/uc_edi.module,v
retrieving revision 1.9
diff -u -p -r1.9 uc_edi.module
--- uc_edi.module	24 Nov 2010 16:37:17 -0000	1.9
+++ uc_edi.module	13 Dec 2010 16:38:09 -0000
@@ -31,11 +31,10 @@ function uc_edi_help($path, $arg) {
       $output .= '<li>' . t('Export the order predicate: <a href="!url">admin/store/ca/uc_edi_order_export/edit</a>', array('!url' => url('admin/store/ca/uc_edi_order_export/edit'))) . '</li>';
       $output .= '<li>' . t('Update an order after export predicate: <a href="!url">admin/store/ca/uc_edi_order_export_update/edit</a>', array('!url' => url('admin/store/ca/uc_edi_order_export_update/edit'))) . '</li>';
       $output .= '<li>' . t('Ubercart EDI settings page: <a href="!url">admin/store/settings/edi</a>', array('!url' => url('admin/store/settings/edi'))) . '</li>';
-      $output .= '<li>' . t('Manual import/export form: <a href="!url">admin/store/edi</a>', array('!url' => url('admin/store/edi'))) . '</li>';
+      $output .= '<li>' . t('Manual order import form: <a href="!url">admin/store/edi/orders/import</a>', array('!url' => url('admin/store/edi/orders/import'))) . '</li>';
+      $output .= '<li>' . t('Manual order export form: <a href="!url">admin/store/edi/orders/export</a>', array('!url' => url('admin/store/edi/orders/export'))) . '</li>';
       $output .= '<li>' . t('Ubercart EDI permissions: <a href="!url">admin/user/permissions#module-uc_edi</a>', array('!url' => url('admin/user/permissions', array('fragment' => 'module-uc_edi')))) . '</li></ul>';
       $output .= '<a name="export-configuration"><h2>' . t('Export Configuration') . '</h2></a>';
-      $output .= '<h3>' . t('Directories') . '</h3>';
-      $output .= '<p>' . t('Set the "Export directory" and "Export archive directory" fields to directories where export files will be written too, preferably outside the Drupal root folder.') . '</p>';
       $output .= '<h3>' . t('Methods') . '</h3>';
       $output .= '<p>' . t('Ubercart EDI has 3 methods for exporting orders. You can export orders "On checkout completion", "At a specified interval" or "Manually".') . '</p>';
       $output .= '<h4>' . t('On checkout completion') . '</h4>';
@@ -56,7 +55,7 @@ function uc_edi_help($path, $arg) {
       $output .= '<li>' . t('Set the "Ready for export order status" to the status desired just before an order is to be exported ("Order processed" recommended). This status should match that of the predicate configured above.') . '</li></ul></li></ul>';
       $output .= '<h4>' . t('Manually') . '</h4>';
       $output .= '<p>' . t('To export orders manually:') . '</p>';
-      $output .= '<ul><li>' . t('Use the "Manual import/export form".</p>') . '</li></ul>';
+      $output .= '<ul><li>' . t('Use the "Manual order export form".</p>') . '</li></ul>';
       $output .= '<a name="export-template-files"><h3>' . t('Template files') . '</h3></a>';
       $output .= '<p>' . t("EDI templates use Drupal's theme system to allow complete control over exported content. To customize exported content you can either override existing templates or define new templates.") . '</p>';
       $output .= '<h4>' . t('Override existing templates') . '</h4>';
@@ -65,13 +64,28 @@ function uc_edi_help($path, $arg) {
       $output .= '<h4>' . t('Create new templates') . '</h4>';
       $output .= '<p>' . t('New templates can be defined by implementing hook_uc_edi_templates(). An array of template names should be returned.') . '</p>';
       $output .= '<h4>' . t('Preprocess functions') . '</h4>';
-      $output .= '<p>' . t('Both methods above can take advantage of the hook_preprocess_uc_edi() function which lets you pass any data to all EDI templates as a variable. The default template_preprocess_uc_edi() function adds all correctly defined order tokens to the template files as variables. For a list of order token variables spcifically added by Ubercart EDI, see the documentation block at the top of the default template file.') . '</p>';
+      $output .= '<p>' . t('Both methods above can take advantage of the hook_preprocess_uc_edi() function which lets you pass any data to all EDI templates as a variable. The default template_preprocess_uc_edi() function adds all correctly defined order tokens to the template files as variables. For a list of order token variables specifically added by Ubercart EDI, see the documentation block at the top of the default template file.') . '</p>';
       $output .= '<h4>' . t('Testing') . '</h4>';
       $output .= '<p>' . t('To easily test new template files, an "export" tab has been added to the order view page. This new tab allows you to select any defined template and automatically updates the output to that of the newly selected template. A save button allows you to save an export file for testing the import process of your fulfillment houses.') . '<br />';
-      $output .= '<strong>' . t('This order export form does not update the order status and should only be used for testing template files or viewing and saving orders that have already been processed. For manually exporting orders, the <a href="!url">Manual import/export form</a> should be used.', array('!url' => url('admin/store/edi'))) . '</strong></p>';
+      $output .= '<strong>' . t('This order export form does not update the order status and should only be used for testing template files or viewing and saving orders that have already been processed. For manually exporting orders, the "Manual Order Export Form" should be used.') . '</strong></p>';
+      $output .= '<h3>' . t('Delivery Methods') . '</h3>';
+      $output .= '<p>' . t('Ubercart EDI offers different methods for delivering export files to locations. Included with Ubercart EDI are the filesystem and e-mail delivery methods, each implemented by its own sub-module. See a delivery methods help page for more information on that delivery method. Other modules can provide their own delivery methods by implementing the uc_edi_export_delivery_methods hook.') . '</p>';
+
+      // List each delivery methods help page with a brief description.
+      $methods = uc_edi_export_delivery_method_list();
+      if (count($methods) > 0) {
+        $output .= '<ul>';
+        foreach ($methods as $method) {
+          if (isset($method['callbacks']['help'])) {
+            $output .= '<li>' . $method['callbacks']['help']() . '</li>';
+          }
+        }
+        $output .= '</ul>';
+      }
+
       $output .= '<h3>' . t('Update an order after export') . '</h3>';
       $output .= '<p>' . t('Ubercart EDI leverages "Conditional Actions" for updating orders after a successful export. The Ubercart EDI module creates an "Order has been exported" trigger that is pulled when an order is successfully exported. By default, an "Update an order after export" predicate is created which is tied to the "Order has been exported" trigger that adds an order comment, an admin comment and updates the order status of orders that have been successfully exported.');
-      $output .= '<a name="export-configuration"><h2>' . t('Import Configuration') . '</h2></a>';
+      $output .= '<a name="import-configuration"><h2>' . t('Import Configuration') . '</h2></a>';
       $output .= '<p>' . t('You may specify as many rules as you want to process order import files. Rules consist of a line identifier and action separated by | characters. Rules should be separated by line breaks (press enter after each one). Multiple rules may all use the same identifier, and they will all be applied for any matching lines in the import file.') . '</p>';
       $output .= '<p>' . t('Import files are parsed line by line, and each line may be handled differently based on the first value in the line. This first value is the identifier that should be used to refer to lines of that type. Use * to denote a rule that applies to any line.') . '</p>';
       $output .= '<p>' . t('When a line is processed, it is broken apart by the delimiter you have set for import files. Each piece may be referred to in actions by its number in sequence, i.e. #1, #2, #3.') . '</p>';
@@ -85,9 +99,7 @@ function uc_edi_help($path, $arg) {
       $output .= '<p>' . t('How about an example? The following rules: <pre>ORD|id:2|us|oc:Your order has shipped via #3 with tracking number #4.</pre> When applied to this line in a comma delimited import file: <pre>ORD,234,UPS,1Z1730398193</pre> Would add an order comment to the order to show the customer their tracking information and update the order status.') . '</p>';
       $output .= '<h2>' . t('Permissions') . '</h2>';
       $output .= '<ul><li>' . t('administer edi orders') . '<br />';
-      $output .= t('Users in roles with "administer edi orders" permissions can modify module settings and manually import and export orders.') . '</li>';
-      $output .= '<li>' . t('download edi orders') . '<br />';
-      $output .= t('Users in roles with the "download edi orders" permissions can download and archive EDI order export files.') . '</li></ul>';
+      $output .= t('Users in roles with "administer edi orders" permissions can modify module settings and manually import and export orders.') . '</li></ul>';
 
       return $output;
   }
@@ -99,54 +111,78 @@ function uc_edi_help($path, $arg) {
 function uc_edi_menu() {
   $items['admin/store/settings/edi'] = array(
     'title' => 'EDI settings',
-    'description' => 'Adjust gerneral EDI settings.',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('uc_edi_settings_form'),
+    'page arguments' => array('uc_edi_settings_import_form'),
     'access arguments' => array('administer edi orders'),
     'type' => MENU_NORMAL_ITEM,
     'file' => 'uc_edi.admin.inc',
   );
-  $items['admin/store/settings/edi/order-export-method-js'] = array(
+  $items['admin/store/settings/edi/import'] = array(
+    'title' => 'Import',
+    'description' => 'Adjust EDI import settings.',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -1,
+    'file' => 'uc_edi.admin.inc',
+  );
+  $items['admin/store/settings/edi/export'] = array(
+    'title' => 'Export',
+    'description' => 'Adjust EDI export settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uc_edi_settings_export_form'),
+    'access arguments' => array('administer edi orders'),
+    'type' => MENU_LOCAL_TASK,
+    'file' => 'uc_edi.admin.inc',
+  );
+  $items['admin/store/settings/edi/export/general'] = array(
+    'title' => 'General',
+    'description' => 'Adjust EDI export general settings.',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -1,
+    'file' => 'uc_edi.admin.inc',
+  );
+  $items['admin/store/edi/export/method-js'] = array(
     'page callback' => 'uc_edi_order_export_method_js',
     'access arguments' => array('administer edi orders'),
     'type' => MENU_CALLBACK,
     'file' => 'uc_edi.admin.inc',
   );
+  $items['admin/store/settings/edi/export/delivery-methods'] = array(
+    'title' => 'Delivery methods',
+    'description' => 'Edit the delivery method settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uc_edi_export_delivery_methods_form'),
+    'access arguments' => array('administer edi orders'),
+    'type' => MENU_LOCAL_TASK,
+    'file' => 'uc_edi.admin.inc',
+  );
   $items['admin/store/edi'] = array(
     'title' => 'EDI import/export',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('uc_edi_manual_form'),
+    'page arguments' => array('uc_edi_order_import_manual_form'),
     'access arguments' => array('administer edi orders'),
     'type' => MENU_NORMAL_ITEM,
     'file' => 'uc_edi.admin.inc',
   );
-  $items['admin/store/edi/manual'] =  array(
-    'title' => 'Manual import/export',
-    'description' => 'Manually import and export EDI files.',
+  $items['admin/store/edi/orders'] =  array(
+    'title' => 'Orders',
     'type' => MENU_DEFAULT_LOCAL_TASK,
     'weight' => -1,
     'file' => 'uc_edi.admin.inc',
   );
-  $items['admin/store/edi/download'] = array(
-    'title' => 'Download/Archive export files',
-    'description' => 'Download and archive exported order EDI files.',
-    'page callback' => 'uc_edi_export_download',
-    'access arguments' => array('download edi orders'),
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'uc_edi.admin.inc',
-  );
-  $items['admin/store/edi/download/file/%'] = array(
-    'page callback' => 'uc_edi_order_export_download_file',
-    'page arguments' => array(5),
-    'access arguments' => array('download edi orders'),
-    'type' => MENU_CALLBACK,
+  $items['admin/store/edi/orders/import'] =  array(
+    'title' => 'Import',
+    'description' => 'Manually import EDI files.',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -1,
     'file' => 'uc_edi.admin.inc',
   );
-  $items['admin/store/edi/download/archive/%'] = array(
-    'page callback' => 'uc_edi_order_export_archive_file',
-    'page arguments' => array(5),
-    'access arguments' => array('download edi orders'),
-    'type' => MENU_CALLBACK,
+  $items['admin/store/edi/orders/export'] = array(
+    'title' => 'Export',
+    'description' => 'Manually export EDI files.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uc_edi_order_export_manual_form'),
+    'access arguments' => array('administer edi orders'),
+    'type' => MENU_LOCAL_TASK,
     'file' => 'uc_edi.admin.inc',
   );
   $items['admin/store/orders/%uc_order/export'] = array(
@@ -173,7 +209,7 @@ function uc_edi_menu() {
  * Implements hook_perm().
  */
 function uc_edi_perm() {
-  return array('administer edi orders', 'download edi orders');
+  return array('administer edi orders');
 }
 
 /**
@@ -234,7 +270,7 @@ function uc_edi_token_values($type, $obj
     case 'order':
       $order = $object;
 
-      $values['order-edi-batch-id'] = variable_get('uc_edi_order_next_batch_id', 1000);
+      $values['order-edi-batch-id'] = variable_get('uc_edi_order_export_next_batch_id', 1000);
       $values['order-payment-method'] = check_plain($order->payment_method);
 
       $shipping_charges = 0;
@@ -468,20 +504,6 @@ function template_preprocess_uc_edi(&$va
 }
 
 /**
- * Respond to EDI template definitions.
- *
- * This hook is invoked from uc_edi_template_list().
- *
- * @return
- *   Array of EDI template names.
- *
- * @ingroup hooks
- */
-function hook_uc_edi_templates() {
-  return array('default');
-}
-
-/**
  * Return an array of EDI templates.
  */
 function uc_edi_template_list() {
@@ -507,7 +529,28 @@ function uc_edi_template_options($custom
 }
 
 /**
- * Creates an export file containing $contents and calls delievery methods.
+ * Builds a list of export delivery methods defined in the enabled modules.
+ *
+ * @param $action
+ *   A string containing the action to perform.
+ *   - rebuild: rebuilds the list of export delivery methods.
+ */
+function uc_edi_export_delivery_method_list($action = NULL) {
+  static $_uc_edi_export_delivery_methods;
+
+  if (count($_uc_edi_export_delivery_methods) > 0 && $action !== 'rebuild') {
+    return $_uc_edi_export_delivery_methods;
+  }
+
+  $_uc_edi_export_delivery_methods = module_invoke_all('uc_edi_export_delivery_methods');
+  sort($_uc_edi_export_delivery_methods);
+
+  return $_uc_edi_export_delivery_methods;
+}
+
+/**
+ * Creates an export file containing $contents in the Drupal temporary folder
+ * and submits the file to all enabled delievery methods.
  *
  * @param $type
  *   The type of export file to create:
@@ -523,41 +566,29 @@ function uc_edi_template_options($custom
 function uc_edi_create_export($type, $filename, $contents) {
   // Don't bother creating an export file if no data was passed in.
   if (!empty($contents)) {
-    // Generate the file path.
-    $filepath = variable_get('uc_edi_order_export_dir', '') . '/' . $filename;
+    // Generate a file path in the Drupal tmp directory.
+    $filepath = file_destination(file_create_path(file_directory_temp() .'/'. $filename), FILE_EXISTS_RENAME);
 
-    switch ($type) {
-      case 'order':
-        // If file fails to open.
-        if (!$file = @fopen($filepath, 'wb')) {
-          watchdog('uc_edi', 'Problem creating the order export file. Check your EDI settings and directory permissions.', array(), WATCHDOG_ERROR);
-          return FALSE;
-        }
+    // Create the file.
+    if (file_save_data($contents, $filepath)) {
+      switch ($type) {
+        case 'order':
+          // Get a list of delivery methods.
+          $methods = uc_edi_export_delivery_method_list();
+          // Pass the file to each enabled delivery method.
+          foreach ($methods as $method) {
+            if (variable_get('uc_edi_export_delivery_method_' . $method['id'], FALSE)) {
+              $method['callbacks']['submit']($filepath, $filename);
+            }
+          }
+          break;
+      }
 
-        // Write the contents to the file and close it.
-        fwrite($file, $contents);
-        fclose($file);
-
-        // Create log of file creation.
-        watchdog('uc_edi', 'Order export file !filename created.', array('!filename' => $filename));
-
-        // Handle delivery methods here.
-        $mail_to = variable_get('uc_edi_order_export_mail_to', '');
-        if (!empty($mail_to) && module_exists('mimemail')) {
-          $mail_from = variable_get('uc_edi_order_export_mail_from', variable_get('site_mail', 'test@example.com'), 'test@example.com');
-          $subject = variable_get('uc_edi_order_export_mail_subject', '');
-          $body = variable_get('uc_edi_order_export_mail_body', '');
-          $attachments = array(
-            0 => array(
-              'filepath' => $filepath,
-              'filemime' => 'text/csv',
-            ),
-          );
-          mimemail($mail_from, $mail_to, $subject, $body, FALSE, array(), NULL, $attachments);
-          watchdog('uc_edi', t('Export mailed to @mail-to .', array('@mail-to' => $mail_to)));
-        }
+      // Increment the batch number.
+      $batch_id = variable_get('uc_edi_order_export_next_batch_id', 1000);
+      variable_set('uc_edi_order_export_next_batch_id', ++$batch_id);
 
-        return TRUE;
+      return TRUE;
     }
   }
 
Index: uc_edi_email/CHANGELOG.txt
===================================================================
RCS file: uc_edi_email/CHANGELOG.txt
diff -N uc_edi_email/CHANGELOG.txt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_email/CHANGELOG.txt	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,5 @@
+$Id$
+
+Journal 6.x-1.x, 2010-12-13
+---------------------------
+by AntoineSolutions: Created the Ubercart EDI e-mail sub-module.
Index: uc_edi_email/README.txt
===================================================================
RCS file: uc_edi_email/README.txt
diff -N uc_edi_email/README.txt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_email/README.txt	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,45 @@
+$Id$
+
+-- SUMMARY --
+
+The Ubercart EDI e-mail module provides an e-mail delivery method for the
+Ubercart EDI module.
+
+
+-- REQUIREMENTS --
+
+* Ubercart EDI: http://drupal.org/project/uc_edi
+* Mime Mail: http://drupal.org/project/mimemail
+
+
+-- INSTALLATION --
+
+* Install as usual, see http://drupal.org/node/70151 for further information.
+
+
+-- CONFIGURATION --
+
+* Resources
+  - Export Delivery Methods settings page:
+    admin/store/settings/edi/export/delivery-methods
+
+* Description
+  The Ubercart EDI e-mail module provides an E-mail Export Delivery Method. The
+  export file will be attached to an e-mail using the specified settings.
+
+
+-- CONTACT --
+
+Current maintainers:
+* Jon Antoine (AntoineSolutions) - http://drupal.org/user/192192
+
+This project has been sponsored by:
+* Antoine Solutions
+  Specializing in Drupal powered sites, Antoine Solutions offers Design,
+  Development, Search Engine Optimisation (SEO) and Search Engine Marketing
+  (SEM). Visit http://www.antoinesolutions.com for more information.
+
+* Showers Pass
+  Technically engineered cycling gear for racers, commuters, messengers and
+  everyday cycling enthusiasts. Visit http://www.showerspass.com for more
+  information.
Index: uc_edi_email/uc_edi_email.info
===================================================================
RCS file: uc_edi_email/uc_edi_email.info
diff -N uc_edi_email/uc_edi_email.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_email/uc_edi_email.info	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,7 @@
+; $Id$
+name = Ubercart EDI e-mail
+description = Provides an e-mail export delivery method for the Ubercart EDI module.
+dependencies[] = uc_edi
+dependencies[] = mimemail
+package = Ubercart - EDI
+core = 6.x
Index: uc_edi_email/uc_edi_email.install
===================================================================
RCS file: uc_edi_email/uc_edi_email.install
diff -N uc_edi_email/uc_edi_email.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_email/uc_edi_email.install	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,19 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Install, update and uninstall functions for the Ubercart EDI e-mail module.
+ */
+
+/**
+ * Implements hook_uninstall().
+ */
+function uc_edi_email_uninstall() {
+  // Delete module variables.
+  variable_del('uc_edi_export_delivery_method_email');
+  variable_del('uc_edi_email_from');
+  variable_del('uc_edi_email_to');
+  variable_del('uc_edi_email_subject');
+  variable_del('uc_edi_email_message');
+}
Index: uc_edi_email/uc_edi_email.module
===================================================================
RCS file: uc_edi_email/uc_edi_email.module
diff -N uc_edi_email/uc_edi_email.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_email/uc_edi_email.module	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,156 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Defines an e-mail export delivery method.
+ */
+
+/*******************************************************************************
+ * Hook Functions (Drupal)
+ ******************************************************************************/
+
+/**
+ * Implements hook_help().
+ */
+function uc_edi_email_help($path, $arg) {
+  switch ($path) {
+    case 'admin/help#uc_edi_email':
+      $output = '';
+      $output .= '<h2>' . t('Resources') . '</h2>';
+      $output .= '<ul><li>' . t('Export Delivery Methods settings page: <a href="!url">admin/store/settings/edi/export/delivery-methods</a>', array('!url' => url('admin/store/settings/edi/export/delivery-methods'))) . '</li>';
+      $output .= '<h2>' . t('Description') . '</h2>';
+      $output .= '<p>' . t('The Ubercart EDI e-mail module provides an E-mail Export Delivery Method. The export file will be attached to an e-mail using the specified settings.') . '</p>';
+
+      return $output;
+  }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function uc_edi_email_form_uc_edi_export_delivery_methods_form_alter(&$form, &$form_state) {
+  $form['#validate'][] = 'uc_edi_email_export_delivery_method_form_validate';
+}
+
+/*******************************************************************************
+ * Hook Functions (Ubercart)
+ ******************************************************************************/
+
+/**
+ * Implementation of hook_uc_edi_export_delivery_methods().
+ */
+function uc_edi_email_uc_edi_export_delivery_methods() {
+  $methods[] = array(
+    'id' => 'email',
+    'title' => t('E-mail'),
+    'description' => t('Deliver export files by e-mail.'),
+    'callbacks' => array(
+      'help' => 'uc_edi_email_export_delivery_method_help',
+      'settings' => 'uc_edi_email_export_delivery_method_form',
+      'submit' => 'uc_edi_email_export_delivery_method_submit',
+    ),
+  );
+
+  return $methods;
+}
+
+/******************************************************************************
+ * Module and Helper Functions
+ *****************************************************************************/
+
+/**
+ * Callback function for the e-mail export delivery method help.
+ *
+ * @return
+ *   HTML link to the e-mail delivery method help page followed by a short
+ *   description.
+ */
+function uc_edi_email_export_delivery_method_help() {
+  return t('<a href="!url">E-mail</a>: Deliver export files to a specified e-mail address.', array('!url' => url('admin/help/uc_edi_email')));
+}
+
+/**
+ * Callback function for the filesystem export delivery method form.
+ *
+ * @return
+ *   An un-rendered settings form for the filesystem export delivery method.
+ */
+function uc_edi_email_export_delivery_method_form() {
+  $form['email']['uc_edi_email_from'] = array(
+    '#type' => 'textfield',
+    '#title' => t('From'),
+    '#description' => t('If left blank, the default site email address @mail will be used.', array('@mail' => variable_get('site_mail', 'test@example.com'))),
+    '#default_value' => variable_get('uc_edi_email_from', variable_get('site_mail', 'test@example.com')),
+  );
+  $form['email']['uc_edi_email_to'] = array(
+    '#type' => 'textfield',
+    '#title' => t('To'),
+    '#description' => t('Send the export file to this address.'),
+    '#default_value' => variable_get('uc_edi_email_to', ''),
+    '#required' => TRUE,
+  );
+  $form['email']['uc_edi_email_subject'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Subject'),
+    '#default_value' => variable_get('uc_edi_email_subject', ''),
+  );
+  $form['email']['uc_edi_email_message'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Message'),
+    '#default_value' => variable_get('uc_edi_email_message', ''),
+  );
+
+  return $form;
+}
+
+/**
+ * Handles validation of the Ubercart EDI e-mail export delivery method form.
+ *
+ * @see uc_edi_email_export_delivery_method_form()
+ */
+function uc_edi_email_export_delivery_method_form_validate($form, &$form_state) {
+  if ($form_state['values']['uc_edi_export_delivery_method_email']) {
+    if (!valid_email_address($form_state['values']['uc_edi_email_to'])) {
+      form_set_error('uc_edi_email_to', t('You have specified an invalid "to" e-mail address.'));
+    }
+  }
+}
+
+/**
+ * Callback function for the e-mail export delivery method submission.
+ *
+ * @return
+ *   TRUE if the file was submitted successfully, otherwise false.
+ */
+function uc_edi_email_export_delivery_method_submit($filepath, $filename) {
+  $from = variable_get('uc_edi_email_from', variable_get('site_mail', 'test@example.com'));
+  $to = variable_get('uc_edi_email_to', '');
+  $subject = variable_get('uc_edi_email_subject', '');
+  $message = variable_get('uc_edi_email_message', '');
+
+  // @todo: Remove when mimemail supports absolute paths.
+  $temp = file_create_filename($filename, file_directory_path());
+  file_copy($filepath, $temp);
+
+  $attachments = array(
+    0 => array(
+      'filepath' => $temp,
+      'filemime' => file_get_mimetype($filename),
+    ),
+  );
+
+  if (mimemail($from, $to, $subject, $message, FALSE, array(), NULL, $attachments)) {
+    // @todo: Remove when mimemail supports absolute paths.
+    file_delete($temp);
+
+    watchdog('uc_edi_email', t('Order export mailed to @mail-to.', array('@mail-to' => $to)));
+    return TRUE;
+  }
+
+  // @todo: Remove when mimemail supports absolute paths.
+  file_delete($temp);
+
+  watchdog('uc_edi_email', t('Order export failed to send to @mail-to. Check your Mime Mail settings.', array('@mail-to' => $to)));
+  return FALSE;
+}
Index: uc_edi_filesystem/CHANGELOG.txt
===================================================================
RCS file: uc_edi_filesystem/CHANGELOG.txt
diff -N uc_edi_filesystem/CHANGELOG.txt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_filesystem/CHANGELOG.txt	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,5 @@
+$Id$
+
+Journal 6.x-1.x, 2010-12-13
+---------------------------
+by AntoineSolutions: Created the Ubercart EDI filesystem sub-module.
Index: uc_edi_filesystem/README.txt
===================================================================
RCS file: uc_edi_filesystem/README.txt
diff -N uc_edi_filesystem/README.txt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_filesystem/README.txt	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,59 @@
+$Id$
+
+-- SUMMARY --
+
+The Ubercart EDI filesystem module provides a local filesystem delivery method
+for the Ubercart EDI module.
+
+
+-- REQUIREMENTS --
+
+* Ubercart EDI: http://drupal.org/project/uc_edi
+
+
+-- INSTALLATION --
+
+* Install as usual, see http://drupal.org/node/70151 for further information.
+
+
+-- CONFIGURATION --
+
+* Resources
+  - Export Delivery Methods settings page:
+    admin/store/settings/edi/export/delivery-methods
+  - Order export files: admin/store/edi/orders/export/files
+  - Ubercart EDI filesystem permissions:
+    admin/user/permissions#module-uc_edi_filesystem
+
+* Description
+  The Ubercart EDI filesystem module provides a Filesystem Export Delivery
+  Method. The user must specify directories on the local filesystem for saving
+  and archiving export files to. Export files can be downloaded and archived
+  from the Export Files page.
+
+* Directories
+  Set the "Export directory" and "Export archive directory" fields to
+  directories on the local filesystem where export files will be written too,
+  preferably outside the Drupal root folder.
+
+* Permissions
+  - download edi orders
+    Users in roles with the "download edi orders" permissions can download and
+    archive EDI order export files.
+
+
+-- CONTACT --
+
+Current maintainers:
+* Jon Antoine (AntoineSolutions) - http://drupal.org/user/192192
+
+This project has been sponsored by:
+* Antoine Solutions
+  Specializing in Drupal powered sites, Antoine Solutions offers Design,
+  Development, Search Engine Optimisation (SEO) and Search Engine Marketing
+  (SEM). Visit http://www.antoinesolutions.com for more information.
+
+* Showers Pass
+  Technically engineered cycling gear for racers, commuters, messengers and
+  everyday cycling enthusiasts. Visit http://www.showerspass.com for more
+  information.
Index: uc_edi_filesystem/uc_edi_filesystem.admin.inc
===================================================================
RCS file: uc_edi_filesystem/uc_edi_filesystem.admin.inc
diff -N uc_edi_filesystem/uc_edi_filesystem.admin.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_filesystem/uc_edi_filesystem.admin.inc	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,85 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Ubercart EDI filesystem administration and module settings UI.
+ */
+
+/**
+ * Creates a table with links for downloading and archiving export files.
+ *
+ * @return string
+ *   An HTML table of order export files to be downloaded or archived if order
+ *   export files were found, otherwise a default message explaining that no
+ *   order export files were found.
+ */
+function uc_edi_filesystem_order_export_files() {
+  $output = '';
+
+  $files = file_scan_directory(variable_get('uc_edi_filesystem_export_dir', ''), '.*\\.' . variable_get('uc_edi_order_export_extension', 'edi'), array('.', '..', 'CVS'), 0, FALSE);
+  $rows = array();
+  foreach ($files as $file) {
+    $rows[] = array($file->basename, t('<a href="!url">Download</a>', array('!url' => url('admin/store/edi/orders/export/files/download/' . $file->basename))), t('<a href="!url">Archive</a>', array('!url' => url('admin/store/edi/orders/export/files/archive/' . $file->basename))));
+  }
+  $header = array(t('Order export file'), array('data' => t('Actions'), 'colspan' => 2));
+  if (count($rows)) {
+    $output .= theme('table', $header, $rows);
+  }
+  else {
+    $output .= t('No order EDI export files were found in the export directory.');
+  }
+
+  return $output;
+}
+
+/**
+ * Allows an order export file to be downloaded.
+ *
+ * @param $filename
+ *   The name of the order export file to be downloaded.
+ */
+function uc_edi_filesystem_order_export_files_download($filename = '') {
+  $file = rtrim(variable_get('uc_edi_filesystem_export_dir', ''), '/\\') . '/' . $filename;
+
+  if (file_exists($file)) {
+    $data = fopen($file, 'rb');
+    ob_end_clean();
+
+    $headers = array(
+      'Content-Length:' . filesize($file),
+      'Content-Disposition: attachment; filename="' . basename($file) . '"',
+      'Content-Type: application/octet-stream'
+    );
+    foreach ($headers as $header) {
+      $header = preg_replace('/\r?\n(?!\t| )/', '', $header);
+      drupal_set_header($header);
+    }
+
+    while (!feof($data)) {
+      print fread($data, 1024);
+    }
+    fclose($data);
+    exit();
+  }
+  else {
+    drupal_not_found();
+  }
+}
+
+/**
+ * Archives an order export file.
+ *
+ * @param $filename
+ *   The name of the order export file to be archived.
+ */
+function uc_edi_filesystem_order_export_files_archive($filename = '') {
+  if (@rename(rtrim(variable_get('uc_edi_filesystem_export_dir', ''), '/\\') . '/' . $filename, rtrim(variable_get('uc_edi_filesystem_export_archive_dir', ''), '/\\') . '/' . $filename)) {
+    drupal_set_message(t('The selected order export file %file was archived successfully.', array('%file' => $filename)));
+  }
+  else {
+    drupal_set_message(t('Problem archiving the order export file. Check your EDI settings and directory permissions.'), 'error');
+  }
+
+  drupal_goto('admin/store/edi/orders/export/files');
+}
Index: uc_edi_filesystem/uc_edi_filesystem.info
===================================================================
RCS file: uc_edi_filesystem/uc_edi_filesystem.info
diff -N uc_edi_filesystem/uc_edi_filesystem.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_filesystem/uc_edi_filesystem.info	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,6 @@
+; $Id$
+name = Ubercart EDI filesystem
+description = Provides a filesystem export delivery method for the Ubercart EDI module.
+dependencies[] = uc_edi
+package = Ubercart - EDI
+core = 6.x
Index: uc_edi_filesystem/uc_edi_filesystem.install
===================================================================
RCS file: uc_edi_filesystem/uc_edi_filesystem.install
diff -N uc_edi_filesystem/uc_edi_filesystem.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_filesystem/uc_edi_filesystem.install	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,18 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Install, update and uninstall functions for the Ubercart EDI filesystem
+ * module.
+ */
+
+/**
+ * Implements hook_uninstall().
+ */
+function uc_edi_filesystem_uninstall() {
+  // Delete module variables.
+  variable_del('uc_edi_export_delivery_method_filesystem');
+  variable_del('uc_edi_filesystem_export_dir');
+  variable_del('uc_edi_filesystem_export_archive_dir');
+}
Index: uc_edi_filesystem/uc_edi_filesystem.module
===================================================================
RCS file: uc_edi_filesystem/uc_edi_filesystem.module
diff -N uc_edi_filesystem/uc_edi_filesystem.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_edi_filesystem/uc_edi_filesystem.module	13 Dec 2010 16:38:09 -0000
@@ -0,0 +1,168 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Defines a filesystem export delivery method.
+ */
+
+/*******************************************************************************
+ * Hook Functions (Drupal)
+ ******************************************************************************/
+
+/**
+ * Implements hook_help().
+ */
+function uc_edi_filesystem_help($path, $arg) {
+  switch ($path) {
+    case 'admin/help#uc_edi_filesystem':
+      $output = '';
+      $output .= '<h2>' . t('Resources') . '</h2>';
+      $output .= '<ul><li>' . t('Export Delivery Methods settings page: <a href="!url">admin/store/settings/edi/export/delivery-methods</a>', array('!url' => url('admin/store/settings/edi/export/delivery-methods'))) . '</li>';
+      $output .= '<li>' . t('Order export files: <a href="!url">admin/store/edi/orders/export/files</a>', array('!url' => url('admin/store/edi/orders/export/files'))) . '</li>';
+      $output .= '<li>' . t('Ubercart EDI filesystem permissions: <a href="!url">admin/user/permissions#module-uc_edi_filesystem</a>', array('!url' => url('admin/user/permissions', array('fragment' => 'module-uc_edi_filesystem')))) . '</li></ul>';
+      $output .= '<h2>' . t('Description') . '</h2>';
+      $output .= '<p>' . t('The Ubercare EDI filesystem module provides a Filesystem Export Delivery Method. The user must specify directories on the local filesystem for saving and archiving export files to. Export files can be downloaded and archived from the Export Files page.') . '</p>';
+      $output .= '<h3>' . t('Directories') . '</h3>';
+      $output .= '<p>' . t('Set the "Export directory" and "Export archive directory" fields to directories on the local filesystem where export files will be written too, preferably outside the Drupal root folder.') . '</p>';
+      $output .= '<h2>' . t('Permissions') . '</h2>';
+      $output .= '<ul><li>' . t('download edi orders') . '<br />';
+      $output .= t('Users in roles with the "download edi orders" permissions can download and archive EDI order export files.') . '</li></ul>';
+      
+      return $output;
+  }
+}
+
+/**
+ * Implements hook_menu().
+ */
+function uc_edi_filesystem_menu() {
+  $items['admin/store/edi/orders/export/files'] = array(
+    'title' => 'Files',
+    'description' => 'Download and archive EDI order export files.',
+    'page callback' => 'uc_edi_filesystem_order_export_files',
+    'access arguments' => array('download edi orders'),
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -1,
+    'file' => 'uc_edi_filesystem.admin.inc',
+  );
+  $items['admin/store/edi/orders/export/files/download'/*/%*/] = array(
+    'page callback' => 'uc_edi_filesystem_order_export_files_download',
+    //'page arguments' => array(7),
+    'access arguments' => array('download edi orders'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_edi_filesystem.admin.inc',
+  );
+  $items['admin/store/edi/orders/export/files/archive'/*/%*/] = array(
+    'page callback' => 'uc_edi_filesystem_order_export_files_archive',
+    //'page arguments' => array(7),
+    'access arguments' => array('download edi orders'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_edi_filesystem.admin.inc',
+  );
+
+  return $items;
+}
+
+/**
+ * Implements hook_perm().
+ */
+function uc_edi_filesystem_perm() {
+  return array('download edi orders');
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function uc_edi_filesystem_form_uc_edi_export_delivery_methods_form_alter(&$form, &$form_state) {
+  $form['#validate'][] = 'uc_edi_filesystem_export_delivery_method_form_validate';
+}
+
+/*******************************************************************************
+ * Hook Functions (Ubercart)
+ ******************************************************************************/
+
+/**
+ * Implementation of hook_uc_edi_export_delivery_methods().
+ */
+function uc_edi_filesystem_uc_edi_export_delivery_methods() {
+  $methods[] = array(
+    'id' => 'filesystem',
+    'title' => t('Filesystem'),
+    'description' => t('Deliver export files to the local filesystem.'),
+    'callbacks' => array(
+      'help' => 'uc_edi_filesystem_export_delivery_method_help',
+      'settings' => 'uc_edi_filesystem_export_delivery_method_form',
+      'submit' => 'uc_edi_filesystem_export_delivery_method_submit',
+    ),
+  );
+
+  return $methods;
+}
+
+/******************************************************************************
+ * Module and Helper Functions
+ *****************************************************************************/
+
+/**
+ * Callback function for the filesystem export delivery method help.
+ *
+ * @return
+ *   HTML link to the filesystem delivery method help page followed by a short
+ *   description.
+ */
+function uc_edi_filesystem_export_delivery_method_help() {
+  return t('<a href="!url">Filesystem</a>: Deliver export files to the local filesystem.', array('!url' => url('admin/help/uc_edi_filesystem')));
+}
+
+/**
+ * Callback function for the filesystem export delivery method form.
+ *
+ * @return
+ *   An un-rendered settings form for the filesystem export delivery method.
+ */
+function uc_edi_filesystem_export_delivery_method_form() {
+  $form['filesystem']['uc_edi_filesystem_export_dir'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Export directory'),
+    '#description' => t('The directory path for exported data files. It is recommended that you use a directory outside of your document root for improved security.'),
+    '#default_value' => variable_get('uc_edi_filesystem_export_dir', ''),
+  );
+  $form['filesystem']['uc_edi_filesystem_export_archive_dir'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Export archive directory'),
+    '#description' => t('The directory path for archiving exported data files. It is recommended that you use a directory outside of your document root for improved security.'),
+    '#default_value' => variable_get('uc_edi_filesystem_export_archive_dir', ''),
+  );
+
+  return $form;
+}
+
+/**
+ * Handles validation of the Ubercart EDI e-mail export delivery method form.
+ *
+ * @see uc_edi_filesystem_export_delivery_method_form()
+ */
+function uc_edi_filesystem_export_delivery_method_form_validate($form, &$form_state) {
+  if ($form_state['values']['uc_edi_export_delivery_method_filesystem']) {
+    file_check_directory($form_state['values']['uc_edi_filesystem_export_dir'], FALSE, 'uc_edi_filesystem_export_dir');
+    file_check_directory($form_state['values']['uc_edi_filesystem_export_archive_dir'], FALSE, 'uc_edi_filesystem_export_archive_dir');
+  }
+}
+
+/**
+ * Callback function for the filesystem export delivery method submission.
+ *
+ * @return
+ *   TRUE if the file was submitted successfully, otherwise false.
+ */
+function uc_edi_filesystem_export_delivery_method_submit($filepath, $filename) {
+  // Copy the file into the export directory.
+  if (@copy($filepath, rtrim(variable_get('uc_edi_filesystem_export_dir', ''), '/\\') . '/' . $filename)) {
+    watchdog('uc_edi_filesystem', t('EDI export saved to @filepath.', array('@filepath' => $filepath)));
+    return TRUE;
+  }
+
+  watchdog('uc_edi_filesystem', 'Problem saving the order export file. Check your Ubercart EDI filesystem export delivery method settings and directory permissions.', array(), WATCHDOG_ERROR);
+  return FALSE;
+}
