/[drupal]/contributions/modules/ubercart/uc_order/uc_order.module
ViewVC logotype

Contents of /contributions/modules/ubercart/uc_order/uc_order.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.12 - (show annotations) (download) (as text)
Thu Jul 10 12:41:02 2008 UTC (16 months, 2 weeks ago) by islandusurper
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--2
Changes since 1.11: +754 -726 lines
File MIME type: text/x-php
Begin the Ubercart 6.x-2.x branch.
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * Handles all things concerning Ubercart orders.
7 *
8 * The order system allows for backend order creation, editing, and management.
9 * Hooks allow for third party module integration, automated fulfillment, and
10 * more. This module also governs the order review options and invoices
11 * displayed to customers.
12 */
13
14 require_once('uc_order_order_pane.inc');
15 require_once('uc_order_line_item.inc');
16 require_once('uc_order.ca.inc');
17
18 /*******************************************************************************
19 * Hook Functions (Drupal)
20 ******************************************************************************/
21
22 /**
23 * Implementation of hook_menu().
24 */
25 function uc_order_menu() {
26 global $user;
27 $items = array();
28
29 $items['admin/store/settings/orders'] = array(
30 'title' => 'Order settings',
31 'description' => 'Configure the order settings.',
32 'page callback' => 'uc_order_settings_overview',
33 'access arguments' => array('administer store'),
34 'type' => MENU_NORMAL_ITEM,
35 );
36 $items['admin/store/settings/orders/overview'] = array(
37 'title' => 'Overview',
38 'description' => t('View the order settings.'),
39 'type' => MENU_DEFAULT_LOCAL_TASK,
40 'weight' => -10,
41 );
42 $items['admin/store/settings/orders/edit'] = array(
43 'title' => 'Edit',
44 'description' => 'Edit the order settings.',
45 'page callback' => 'drupal_get_form',
46 'page arguments' => array('uc_order_settings_form'),
47 'access arguments' => array('administer store'),
48 'type' => MENU_LOCAL_TASK,
49 'weight' => -5,
50 );
51 $items['admin/store/settings/orders/edit/basic'] = array(
52 'title' => 'Order settings',
53 'description' => t('Edit the basic order settings.'),
54 'type' => MENU_DEFAULT_LOCAL_TASK,
55 'weight' => -10,
56 );
57 $items['admin/store/settings/orders/edit/workflow'] = array(
58 'title' => 'Order workflow',
59 'description' => 'Modify and configure order states and statuses.',
60 'page callback' => 'drupal_get_form',
61 'page arguments' => array('uc_order_workflow_form'),
62 'access arguments' => array('administer order workflow'),
63 'type' => MENU_LOCAL_TASK,
64 'weight' => -5,
65 );
66 $items['admin/store/settings/orders/edit/panes'] = array(
67 'title' => 'Order panes',
68 'description' => 'Edit the pane settings for order pages.',
69 'page callback' => 'drupal_get_form',
70 'page arguments' => array('uc_order_panes_form'),
71 'access arguments' => array('administer store'),
72 'type' => MENU_LOCAL_TASK,
73 'weight' => 0,
74 );
75
76 $items['admin/store/settings/orders/edit/workflow/create'] = array(
77 'title' => 'Create an order status',
78 'description' => 'Create a custom order status for your store.',
79 'page callback' => 'drupal_get_form',
80 'page arguments' => array('uc_order_status_create_form'),
81 'access arguments' => array('administer order workflow'),
82 'type' => MENU_CALLBACK,
83 );
84
85 $items['admin/store/orders'] = array(
86 'title' => 'Orders',
87 'description' => 'View and process orders.',
88 'page callback' => 'uc_order_admin',
89 'page arguments' => array(NULL, NULL, FALSE),
90 'access arguments' => array('view all orders'),
91 'type' => MENU_NORMAL_ITEM,
92 'weight' => -10,
93 );
94 $items['admin/store/orders/view'] = array(
95 'title' => 'View orders',
96 'description' => 'View and process the orders received through your website.',
97 'page arguments' => array(NULL, NULL, FALSE),
98 'access arguments' => array('view all orders'),
99 'type' => MENU_NORMAL_ITEM,
100 'weight' => -10,
101 );
102 $items['admin/store/orders/create'] = array(
103 'title' => 'Create order',
104 'description' => 'Create an empty new order.',
105 'page callback' => 'uc_order_create',
106 'access arguments' => array('edit orders'),
107 'type' => MENU_NORMAL_ITEM,
108 'weight' => -5,
109 );
110 $items['admin/store/orders/search'] = array(
111 'title' => 'Search orders',
112 'description' => 'Search existing orders.',
113 'page callback' => 'uc_order_usearch',
114 'access arguments' => array('view all orders'),
115 'type' => MENU_NORMAL_ITEM,
116 'weight' => 0,
117 );
118 $items['admin/store/orders/address_book'] = array(
119 'title' => 'Select address',
120 'page callback' => 'uc_order_address_book',
121 'access arguments' => array('edit orders'),
122 'type' => MENU_CALLBACK,
123 );
124 $items['admin/store/orders/customer'] = array(
125 'title' => 'Select customer',
126 'page callback' => 'uc_order_select_customer',
127 'page arguments' => array(NULL),
128 'access arguments' => array('edit orders'),
129 'type' => MENU_CALLBACK,
130 );
131 $items['user/%user/orders'] = array(
132 'title' => 'Orders',
133 'description' => 'View your order history.',
134 'page callback' => 'uc_order_history',
135 'page arguments' => array(1),
136 'access callback' => 'uc_order_can_view_order',
137 'access arguments' => array(1),
138 'type' => MENU_LOCAL_TASK,
139 );
140 $items['user/%user/order/%uc_order'] = array(
141 'title callback' => 'uc_order_page_title',
142 'title arguments' => array(3),
143 'description' => 'View order.',
144 'page callback' => 'uc_order_view',
145 'page arguments' => array(3, 'customer'),
146 'access callback' => 'uc_order_can_view_order',
147 'access arguments' => array(1),
148 'type' => MENU_CALLBACK,
149 );
150 $items['user/%user/order/%uc_order/invoice'] = array(
151 'title' => 'View invoice',
152 'description' => 'View order invoice.',
153 'page callback' => 'uc_order_view',
154 'page arguments' => array(3, 'invoice'),
155 'access callback' => 'uc_order_can_view_order',
156 'access arguments' => array(1),
157 'type' => MENU_CALLBACK,
158 );
159
160 $items['admin/store/orders/create/%user'] = array(
161 'title' => 'Create order',
162 'description' => 'Create an order for a customer.',
163 'callback' => 'uc_order_create',
164 'callback arguments' => array(4),
165 'access arguments' => array('edit orders'),
166 'type' => MENU_CALLBACK,
167 );
168
169 $items['admin/store/orders/%uc_order'] = array(
170 'title callback' => 'uc_order_page_title',
171 'title arguments' => array(3),
172 'description' => 'View order',
173 'page callback' => 'uc_order_view',
174 'page arguments' => array(3, 'view'),
175 'access arguments' => array('view all orders'),
176 'type' => MENU_CALLBACK
177 );
178 $items['admin/store/orders/%uc_order/view'] = array(
179 'title' => 'View',
180 'type' => MENU_DEFAULT_LOCAL_TASK,
181 'weight' => -10
182 );
183 $items['admin/store/orders/%uc_order/edit'] = array(
184 'title' => 'Edit',
185 'page callback' => 'drupal_get_form',
186 'page arguments' => array('uc_order_edit_form', 3),
187 'access arguments' => array('edit orders'),
188 'type' => MENU_LOCAL_TASK,
189 'weight' => 1,
190 );
191 $items['admin/store/orders/%uc_order/add_line_item/%'] = array(
192 'title' => 'Add a line item',
193 'page callback' => 'drupal_get_form',
194 'page arguments' => array('uc_order_add_line_item_form', 3, 5),
195 'access arguments' => array('edit orders'),
196 'type' => MENU_CALLBACK,
197 );
198 $items['admin/store/orders/%uc_order/products'] = array(
199 'title' => 'Products',
200 'page callback' => 'uc_order_edit_products',
201 'page arguments' => array(3),
202 'access arguments' => array('edit orders'),
203 'type' => MENU_CALLBACK,
204 );
205 $items['admin/store/orders/%uc_order/product_select'] = array(
206 'title' => 'Product select',
207 'page callback' => 'uc_order_load_product_select',
208 'page arguments' => array(3),
209 'access arguments' => array('edit orders'),
210 'type' => MENU_CALLBACK,
211 );
212 $items['admin/store/orders/%uc_order/add_product/%node'] = array(
213 'title' => 'Add product',
214 'page callback' => 'uc_order_add_product',
215 'page arguments' => array(3, 5),
216 'access arguments' => array('edit orders'),
217 'type' => MENU_CALLBACK,
218 );
219 $items['admin/store/orders/%uc_order/invoice'] = array(
220 'title' => 'Invoice',
221 'page callback' => 'uc_order_invoice',
222 'page arguments' => array(3),
223 'access arguments' => array('view all orders'),
224 'type' => MENU_LOCAL_TASK,
225 'weight' => 3,
226 );
227 $items['admin/store/orders/%uc_order/invoice/view'] = array(
228 'title' => 'View invoice',
229 'type' => MENU_DEFAULT_LOCAL_TASK,
230 'weight' => -10,
231 );
232 $items['admin/store/orders/%uc_order/invoice/print'] = array(
233 'title' => 'Printable invoice',
234 'page arguments' => array(3, 'print'),
235 'access arguments' => array('view all orders'),
236 'type' => MENU_LOCAL_TASK,
237 'weight' => -5,
238 );
239 $items['admin/store/orders/%uc_order/invoice/mail'] = array(
240 'title' => 'Mail invoice',
241 'page callback' => 'drupal_get_form',
242 'page arguments' => array('uc_order_mail_invoice_form', 3),
243 'access arguments' => array('view all orders'),
244 'type' => MENU_LOCAL_TASK,
245 'weight' => 0,
246 );
247 $items['admin/store/orders/%uc_order/log'] = array(
248 'title' => 'Log',
249 'page callback' => 'uc_order_log',
250 'page arguments' => array(3),
251 'access callback' => 'uc_order_access_order_log',
252 'type' => MENU_LOCAL_TASK,
253 'weight' => 10,
254 );
255 $items['admin/store/orders/%uc_order/delete'] = array(
256 'title' => 'Delete order?',
257 'description' => 'Delete order?',
258 'page callback' => 'uc_order_delete_confirm',
259 'page arguments' => array(3),
260 'access callback' => 'uc_order_can_delete',
261 'access arguments' => array(3),
262 'type' => MENU_CALLBACK,
263 );
264
265 return $items;
266 }
267
268 function uc_order_page_title($order) {
269 return t('Order @order_id', array('@order_id' => $order->order_id));
270 }
271
272 function uc_order_init() {
273 drupal_add_css(drupal_get_path('module', 'uc_order') .'/uc_order.css');
274
275 if (arg(0) == 'admin' && arg(1) == 'store' && arg(2) == 'orders' && is_numeric(arg(3)) && arg(4) == 'edit') {
276 uc_add_js(drupal_get_path('module', 'uc_order') .'/uc_order.js');
277 }
278 }
279
280 function uc_order_theme() {
281 return array(
282 'uc_order_state_table' => array(
283 'arguments' => array('form' => NULL),
284 ),
285 'uc_order_status_table' => array(
286 'arguments' => array('form' => NULL),
287 ),
288 'uc_order_edit_form' => array(
289 'arguments' => array('form' => NULL),
290 ),
291 'uc_order_edit_products_form' => array(
292 'arguments' => array('form' => NULL),
293 ),
294 );
295 }
296
297 /**
298 * Implementation of hook_token_values(). (token.module)
299 */
300 function uc_order_token_values($type, $object = NULL) {
301 switch ($type) {
302 case 'order':
303 $order = $object;
304
305 if (isset($_SESSION['new_user']) && is_array($_SESSION['new_user'])) {
306 $values['new-username'] = check_plain($_SESSION['new_user']['name']);
307 $values['new-password'] = check_plain($_SESSION['new_user']['pass']);
308 }
309 else {
310 $values['new-username'] = '';
311 $values['new-password'] = '';
312 }
313 $values['order-id'] = $order->order_id;
314 $values['order-uid'] = $order->uid;
315 $values['order-url'] = url('user/'. $order->uid .'/order/'. $order->order_id, array('absolute' => TRUE));
316 $values['order-link'] = l($order->order_id, $values['order-url']);
317 $values['order-admin-url'] = url('admin/store/orders/'. $order->order_id, array('absolute' => TRUE));
318 $admin_url = url('admin/store/orders/'. $order->order_id, array('absolute' => TRUE));
319 $values['order-admin-link'] = l($order->order_id, $admin_url);
320 if (is_array($order->line_items)) {
321 foreach ($order->line_items as $key => $value) {
322 if ($value['type'] == 'subtotal') {
323 $subtotal = uc_currency_format($order->line_items[$key]['amount']);
324 }
325 if ($value['type'] == 'shipping' && is_null($ship_method)) {
326 $ship_method = $value['title'];
327 }
328 }
329 }
330 $values['order-subtotal'] = $subtotal;
331 $values['order-total'] = uc_currency_format($order->order_total);
332 $values['order-email'] = check_plain($order->primary_email);
333 $values['order-shipping-address'] = uc_order_address($order, 'delivery');
334 $values['order-shipping-phone'] = check_plain($order->delivery_phone);
335 $values['order-shipping-method'] = is_null($ship_method) ? t('Standard delivery') : $ship_method;
336 $values['order-billing-address'] = uc_order_address($order, 'billing');
337 $values['order-billing-phone'] = check_plain($order->billing_phone);
338 if (variable_get('uc_customer_list_address', 'billing') == 'shipping') {
339 $values['order-first-name'] = check_plain($order->delivery_first_name);
340 $values['order-last-name'] = check_plain($order->delivery_last_name);
341 }
342 else {
343 $values['order-first-name'] = check_plain($order->billing_first_name);
344 $values['order-last-name'] = check_plain($order->billing_last_name);
345 }
346 $result = db_result(db_query("SELECT message FROM {uc_order_comments} WHERE order_id = %d AND uid = 0 ORDER BY created DESC LIMIT 1", $order->order_id));
347 $values['order-comments'] = empty($result) ? t('<i>No comments left.</i>') : check_plain($result);
348 $result = db_result(db_query("SELECT message FROM {uc_order_comments} WHERE order_id = %d AND uid > 0 ORDER BY created DESC LIMIT 1", $order->order_id));
349 $values['order-last-comment'] = empty($result) ? t('<i>No comment found.</i>') : check_plain($result);
350 $values['order-status'] = uc_order_status_data($order->order_status, 'title');
351 $values['order-date-created'] = format_date($order->created, 'small');
352 $values['order-date-modified'] = format_date($order->modified, 'small');
353 break;
354 }
355
356 return $values;
357 }
358
359 /**
360 * Implementation of hook_token_list(). (token.module)
361 */
362 function uc_order_token_list($type = 'all') {
363 if ($type == 'order' || $type == 'ubercart' || $type == 'all') {
364 $tokens['order']['new-username'] = t('New username associated with an order if applicable.');
365 $tokens['order']['new-password'] = t('New password associated with an order if applicable.');
366 $tokens['order']['order-id'] = t('The order ID.');
367 $tokens['order']['order-uid'] = t('The user ID of the order.');
368 $tokens['order']['order-url'] = t('The URL to the order');
369 $tokens['order']['order-link'] = t('A link to the order using the order ID.');
370 $tokens['order']['order-admin-url'] = t('The URL to the admin view page using the order ID.');
371 $tokens['order']['order-admin-link'] = t('A link to the order admin view page using the order ID.');
372 $tokens['order']['order-subtotal'] = t('The subtotal of products on an order.');
373 $tokens['order']['order-total'] = t('The order total.');
374 $tokens['order']['order-email'] = t('The primary e-mail address of the order.');
375 $tokens['order']['order-shipping-address'] = t('The order shipping address.');
376 $tokens['order']['order-shipping-phone'] = t('The phone number for the shipping address.');
377 $tokens['order']['order-billing-address'] = t('The order billing address.');
378 $tokens['order']['order-billing-phone'] = t('The phone number for the billing address.');
379 $tokens['order']['order-shipping-method'] = t('The title of the first shipping line item.');
380 $tokens['order']['order-first-name'] = t('The first name associated with the order.');
381 $tokens['order']['order-last-name'] = t('The last name associated with the order.');
382 $tokens['order']['order-comments'] = t('Comments left by the customer.');
383 $tokens['order']['order-last-comment'] = t('Last order comment left by an administrator (not counting the order admin comments).');
384 $tokens['order']['order-status'] = t('The current order status.');
385 $tokens['order']['order-date-created'] = t('The date and time when the order was created.');
386 $tokens['order']['order-date-modified'] = t('The date and time when the order was last modified.');
387 }
388
389 return $tokens;
390 }
391
392 /**
393 * Implementation of hook_perm().
394 */
395 function uc_order_perm() {
396 return array('view all orders', 'create orders', 'edit orders', 'delete orders', 'delete any order', 'administer order workflow');
397 }
398
399 function uc_order_can_view_order($order_user) {
400 global $user;
401 return user_access('view all orders') || $user->uid == $order_user->uid;
402 }
403
404 function uc_order_access_order_log() {
405 return user_access('view all orders') && variable_get('uc_order_logging', TRUE);
406 }
407
408 /**
409 * Implementation of hook_user().
410 */
411 function uc_order_user($op, &$edit, &$account, $category = NULL) {
412 global $user;
413 switch ($op) {
414 case 'view':
415 if ($user->uid && ($user->uid == $account->uid || user_access('view all orders'))) {
416 $items['orders'] = array(
417 'value' => l(t('Click here to view your order history.'), 'user/'. $account->uid .'/orders'),
418 'class' => 'member',
419 );
420 return array(t('Orders') => $items);
421 }
422 else {
423 return NULL;
424 }
425 }
426 }
427
428 function uc_order_mail($key, &$message, $params) {
429 switch ($key) {
430 case 'invoice':
431 $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
432 $message['subject'] = t('Your Order Invoice');
433 $message['from'] = uc_store_email_from();
434 $message['body'][] = uc_order_load_invoice($params['order'], 'admin-mail', variable_get('uc_cust_order_invoice_template', 'customer'));
435 break;
436 case 'user-register-welcome':
437 $variables = array('!username' => $params['account']->name, '!site' => variable_get('site_name', 'Drupal'), '!password' => $params['account']->pass, '!uri' => $base_url, '!uri_brief' => substr($base_url, strlen('http://')), '!mailto' => $params['account']->mail, '!date' => format_date(time()), '!login_uri' => url('user', array('absolute' => TRUE)), '!edit_uri' => url('user/'. $params['account']->uid .'/edit', array('absolute' => TRUE)), '!login_url' => user_pass_reset_url($params['account']));
438 $message['from'] = uc_store_email_from();
439 $message['subject'] = _user_mail_text('welcome_subject', $variables);
440 $message['body'][] = _user_mail_text('welcome_body', $variables);
441 break;
442 }
443 }
444
445 /*******************************************************************************
446 * Hook Functions (TAPIr)
447 ******************************************************************************/
448
449 /**
450 * Implementation of hook_table_settings().
451 */
452 function uc_order_table_settings() {
453 $tables[] = array(
454 'id' => 'op_products_view_table',
455 'description' => t('The products table on the order view screen.'),
456 'path' => 'admin/store/settings/tables',
457 'access' => 'administer store',
458 'preview' => FALSE,
459 );
460 $tables[] = array(
461 'id' => 'op_products_customer_table',
462 'description' => t('The products table on the customer order screen.'),
463 'path' => 'admin/store/settings/tables',
464 'access' => 'administer store',
465 'preview' => FALSE,
466 );
467 $tables[] = array(
468 'id' => 'op_products_edit_table',
469 'description' => t('The products table on the order edit screen.'),
470 'path' => 'admin/store/settings/tables',
471 'access' => 'administer store',
472 'preview' => FALSE,
473 );
474
475 $tables[] = array(
476 'id' => 'op_order_comments_view_table',
477 'description' => t('The order comments table on the order view screen.'),
478 'path' => 'admin/store/settings/tables',
479 'access' => 'administer store',
480 'preview' => FALSE,
481 );
482 $tables[] = array(
483 'id' => 'op_admin_comments_view_table',
484 'description' => t('The admin comments table on the order view screen.'),
485 'path' => 'admin/store/settings/tables',
486 'access' => 'administer store',
487 'preview' => FALSE,
488 );
489
490 return $tables;
491 }
492
493
494 /*******************************************************************************
495 * Hook Functions (Ubercart)
496 ******************************************************************************/
497
498 /**
499 * Implementation of hook_order_pane().
500 */
501 function uc_order_order_pane() {
502 $panes[] = array(
503 'id' => 'ship_to',
504 'callback' => 'uc_order_pane_ship_to',
505 'title' => t('Ship to'),
506 'desc' => t("Manage the order's shipping address and contact information."),
507 'class' => 'pos-left',
508 'weight' => 1,
509 'show' => array('view', 'edit', 'invoice', 'customer'),
510 );
511 $panes[] = array(
512 'id' => 'bill_to',
513 'callback' => 'uc_order_pane_bill_to',
514 'title' => t('Bill to'),
515 'desc' => t("Manage the order's billing address and contact information."),
516 'class' => 'pos-left',
517 'weight' => 2,
518 'show' => array('view', 'edit', 'invoice', 'customer'),
519 );
520 $panes[] = array(
521 'id' => 'customer',
522 'callback' => 'uc_order_pane_customer',
523 'title' => t('Customer info'),
524 'desc' => t("Manage the information for the customer's user account."),
525 'class' => 'pos-left',
526 'weight' => 3,
527 'show' => array('view', 'edit'),
528 );
529 $panes[] = array(
530 'id' => 'products',
531 'callback' => 'uc_order_pane_products',
532 'title' => t('Products'),
533 'desc' => t('Manage the products an order contains.'),
534 'class' => 'abs-left',
535 'weight' => 5,
536 'show' => array('view', 'edit', 'invoice', 'customer'),
537 );
538 $panes[] = array(
539 'id' => 'line_items',
540 'callback' => 'uc_order_pane_line_items',
541 'title' => t('Line items'),
542 'desc' => t("View and modify an order's line items."),
543 'class' => 'abs-left',
544 'weight' => 6,
545 'show' => array('view', 'edit', 'invoice', 'customer'),
546 );
547 $panes[] = array(
548 'id' => 'order_comments',
549 'callback' => 'uc_order_pane_order_comments',
550 'title' => t('Order comments'),
551 'desc' => t('View the order comments, used for communicating with customers.'),
552 'class' => 'abs-left',
553 'weight' => 8,
554 'show' => array('view', 'invoice', 'customer'),
555 );
556 $panes[] = array(
557 'id' => 'admin_comments',
558 'callback' => 'uc_order_pane_admin_comments',
559 'title' => t('Admin comments'),
560 'desc' => t('View the admin comments, used for administrative notes and instructions.'),
561 'class' => 'abs-left',
562 'weight' => 9,
563 'show' => array('view', 'edit'),
564 );
565 $panes[] = array(
566 'id' => 'update',
567 'callback' => 'uc_order_pane_update',
568 'title' => t('Update order'),
569 'desc' => t("Update an order's status or add comments to an order."),
570 'class' => 'abs-left',
571 'weight' => 10,
572 'show' => array('view'),
573 );
574
575 return $panes;
576 }
577
578 /**
579 * Implementation of hook_order_state().
580 */
581 function uc_order_order_state() {
582 $states[] = array(
583 'id' => 'canceled',
584 'title' => t('Canceled'),
585 'weight' => -20,
586 'scope' => 'specific',
587 );
588 $states[] = array(
589 'id' => 'in_checkout',
590 'title' => t('In checkout'),
591 'weight' => -10,
592 'scope' => 'specific',
593 );
594 $states[] = array(
595 'id' => 'post_checkout',
596 'title' => t('Post checkout'),
597 'weight' => 0,
598 'scope' => 'general',
599 );
600 $states[] = array(
601 'id' => 'completed',
602 'title' => t('Completed'),
603 'weight' => 20,
604 'scope' => 'general',
605 );
606
607 return $states;
608 }
609
610 /**
611 * Implementation of hook_line_item().
612 */
613 function uc_order_line_item() {
614 $items[] = array(
615 'id' => 'subtotal',
616 'title' => t('Subtotal'),
617 'weight' => 0,
618 'stored' => FALSE,
619 'calculated' => FALSE,
620 'callback' => 'uc_line_item_subtotal',
621 );
622 $items[] = array(
623 'id' => 'generic',
624 'title' => t('Empty line'),
625 'weight' => 2,
626 'stored' => TRUE,
627 'add_list' => TRUE,
628 'calculated' => TRUE,
629 'callback' => 'uc_line_item_generic',
630 );
631 $items[] = array(
632 'id' => 'total',
633 'title' => t('Total'),
634 'weight' => 15,
635 'stored' => FALSE,
636 'calculated' => FALSE,
637 'display_only' => TRUE,
638 'callback' => 'uc_line_item_total',
639 );
640
641 return $items;
642 }
643
644
645 /*******************************************************************************
646 * Callback Functions, Forms, and Tables
647 ******************************************************************************/
648
649 /**
650 * Display the order settings overview.
651 */
652 function uc_order_settings_overview() {
653 $items = array(
654 t('Displaying !number orders at a time on the order admin overview.', array('!number' => variable_get('uc_order_number_displayed', 30))),
655 t('Order logging is !status.', array('!status' => variable_get('uc_order_logging', TRUE) ? t('enabled') : t('disabled'))),
656 t('Addresses on order view pages are !status.', array('!status' => variable_get('uc_order_capitalize_addresses', TRUE) ? t('capitalized') : t('displayed as entered'))),
657 );
658 if (module_exists('ubrowser') && module_exists('uc_catalog')) {
659 $items[] = t('You are !status the uBrowser to add products to orders.', array('!status' => variable_get('uc_ubrowser_product_select', TRUE) ? t('using') : t('not using')));
660 }
661 $cust_template = variable_get('uc_cust_order_invoice_template', 'customer');
662 $items[] = t('Order invoice template: !template', array('!template' => $cust_template == '0' ? t('custom') : $cust_template));
663 $sections[] = array(
664 'edit' => 'admin/store/settings/orders/edit',
665 'title' => t('Order settings'),
666 'items' => $items,
667 );
668
669 foreach (uc_order_status_list() as $status) {
670 $statuses[] = $status['title'];
671 }
672 $items = array();
673 $items[] = t('The following order statuses have been defined:')
674 . theme('item_list', $statuses);
675 $sections[] = array(
676 'edit' => 'admin/store/settings/orders/edit/workflow',
677 'title' => t('Order workflow'),
678 'items' => $items,
679 );
680
681 $items = array();
682 $panes = _order_pane_list();
683 foreach ($panes as $pane) {
684 foreach ($pane['show'] as $view) {
685 $lists[$view][$pane['id']]['title'] = $pane['title'];
686 $lists[$view][$pane['id']]['enabled'] = variable_get('uc_order_pane_'. $pane['id'] .'_show_'. $view, TRUE);
687 $lists[$view][$pane['id']]['weight'] = variable_get('uc_order_pane_'. $pane['id'] .'_weight_'. $view, $pane['weight']);
688 }
689 }
690 $titles = _get_order_screen_titles();
691 foreach ($lists as $view => $data) {
692 uasort($lists[$view], 'uc_weight_sort');
693 }
694 foreach ($lists as $view => $data) {
695 $title = t('Order panes on !screen screen', array('!screen' => $titles[$view]));
696 $pitems = array();
697 foreach ($data as $id => $pane_data) {
698 $pitems[] = t('!title is !status.', array('!title' => $pane_data['title'], '!status' => $pane_data['enabled'] ? t('enabled') : t('disabled')));
699 }
700 $items[] = $title . theme('item_list', $pitems);
701 }
702
703 $sections[] = array(
704 'edit' => 'admin/store/settings/orders/edit/panes',
705 'title' => t('Order panes'),
706 'items' => $items,
707 );
708
709 $output = theme('uc_settings_overview', $sections);
710
711 return $output;
712 }
713
714 /**
715 * Generate the settings form for orders.
716 */
717 function uc_order_settings_form() {
718 $form['admin'] = array(
719 '#type' => 'fieldset',
720 '#title' => t('Admin settings'),
721 '#collapsible' => FALSE,
722 '#collapsed' => FALSE,
723 );
724
725 for ($i = 10; $i <= 100; $i += 10) {
726 $options[$i] = $i;
727 }
728 $form['admin']['uc_order_number_displayed'] = array(
729 '#type' => 'select',
730 '#title' => t('Number of orders on overview screen'),
731 '#options' => $options,
732 '#default_value' => variable_get('uc_order_number_displayed', 30),
733 );
734 $form['admin']['uc_order_logging'] = array(
735 '#type' => 'checkbox',
736 '#title' => t('Enable order logging'),
737 '#default_value' => variable_get('uc_order_logging', TRUE),
738 );
739 $form['admin']['uc_order_capitalize_addresses'] = array(
740 '#type' => 'checkbox',
741 '#title' => t('Capitalize address on order screens'),
742 '#default_value' => variable_get('uc_order_capitalize_addresses', TRUE),
743 );
744 if (module_exists('ubrowser') && module_exists('uc_catalog')) {
745 $form['admin']['uc_ubrowser_product_select'] = array(
746 '#type' => 'checkbox',
747 '#title' => t('Use the uBrowser product select on order edit screens'),
748 '#default_value' => variable_get('uc_ubrowser_product_select', TRUE),
749 );
750 }
751
752 $form['customer'] = array(
753 '#type' => 'fieldset',
754 '#title' => t('Customer settings'),
755 '#collapsible' => FALSE,
756 '#collapsed' => FALSE,
757 );
758 $form['customer']['uc_cust_view_order_invoices'] = array(
759 '#type' => 'checkbox',
760 '#title' => t('Allow customers to view order invoices from their accounts.'),
761 '#default_value' => variable_get('uc_cust_view_order_invoices', TRUE),
762 );
763 $form['customer']['uc_cust_order_invoice_template'] = array(
764 '#type' => 'select',
765 '#title' => t('Invoice template'),
766 '#description' => t('Select the invoice template to use for your site.'),
767 '#options' => uc_order_template_options(),
768 '#default_value' => variable_get('uc_cust_order_invoice_template', 'customer'),
769 );
770
771 return system_settings_form($form);
772 }
773
774 // Display the order workflow form for order state and status customization.
775 function uc_order_workflow_form() {
776 $states = uc_order_state_list();
777 $statuses = uc_order_status_list();
778
779 $form['order_states'] = array(
780 '#type' => 'fieldset',
781 '#title' => t('Order states'),
782 '#collapsible' => TRUE,
783 '#collapsed' => TRUE,
784 '#theme' => 'uc_order_state_table',
785 '#tree' => TRUE,
786 );
787
788 foreach ($states as $state) {
789 $form['order_states'][$state['id']]['title'] = array(
790 '#value' => $state['title'],
791 );
792
793 // Create the select box for specifying a default status per order state.
794 $options = array();
795 foreach ($statuses as $status) {
796 if ($status['state'] == $state['id']) {
797 $options[$status['id']] = $status['title'];
798 }
799 }
800 if (empty($options)) {
801 $form['order_states'][$state['id']]['default'] = array(
802 '#value' => t('- N/A -'),
803 );
804 }
805 else {
806 $form['order_states'][$state['id']]['default'] = array(
807 '#type' => 'select',
808 '#options' => $options,
809 '#default_value' => uc_order_state_default($state['id']),
810 );
811 }
812 }
813
814 $form['order_statuses'] = array(
815 '#type' => 'fieldset',
816 '#title' => t('Order statuses'),
817 '#collapsible' => FALSE,
818 '#theme' => 'uc_order_status_table',
819 '#tree' => TRUE,
820 );
821
822 // Build the state option array for the order status table.
823 $options = array();
824 foreach ($states as $state) {
825 $options[$state['id']] = $state['title'];
826 }
827
828 foreach ($statuses as $status) {
829 $form['order_statuses'][$status['id']]['id'] = array(
830 '#value' => $status['id'],
831 );
832 $form['order_statuses'][$status['id']]['title'] = array(
833 '#type' => 'textfield',
834 '#default_value' => $status['title'],
835 '#size' => 32,
836 '#required' => TRUE,
837 );
838 $form['order_statuses'][$status['id']]['weight'] = array(
839 '#type' => 'weight',
840 '#delta' => 20,
841 '#default_value' => $status['weight'],
842 );
843 if ($status['locked']) {
844 $form['order_statuses'][$status['id']]['state'] = array(
845 '#value' => uc_order_state_data($status['state'], 'title'),
846 );
847 $form['order_statuses'][$status['id']]['locked'] = array(
848 '#type' => 'hidden',
849 '#value' => TRUE,
850 );
851 }
852 else {
853 $form['order_statuses'][$status['id']]['state'] = array(
854 '#type' => 'select',
855 '#options' => $options,
856 '#default_value' => $status['state'],
857 );
858 $form['order_statuses'][$status['id']]['remove'] = array(
859 '#type' => 'checkbox',
860 );
861 }
862 }
863
864 $form['order_statuses']['create'] = array(
865 '#type' => 'submit',
866 '#value' => t('Create new status'),
867 );
868
869 $form['submit'] = array(
870 '#type' => 'submit',
871 '#value' => t('Submit changes'),
872 );
873
874 return $form;
875 }
876
877 // Save changes to states and statuses from the order workflow settings form.
878 function uc_order_workflow_form_submit($form, &$form_state) {
879 foreach ($form_state['values']['order_states'] as $key => $value) {
880 variable_set('uc_state_'. $key .'_default', $value['default']);
881 }
882
883 foreach ($form_state['values']['order_statuses'] as $key => $value) {
884 if ($value['locked'] != TRUE && $value['remove'] == TRUE) {
885 db_query("DELETE FROM {uc_order_statuses} WHERE order_status_id = '%s'", $key);
886 drupal_set_message(t('Order status %status removed.', array('%status' => $key)));
887 }
888 else {
889 if ($value['locked'] == TRUE) {
890 db_query("UPDATE {uc_order_statuses} SET title = '%s', weight = %d "
891 ."WHERE order_status_id = '%s'", $value['title'],
892 $value['weight'], $key);
893 }
894 else {
895 db_query("UPDATE {uc_order_statuses} SET title = '%s', state = '%s', "
896 ."weight = %d WHERE order_status_id = '%s'", $value['title'],
897 $value['state'], $value['weight'], $key);
898 }
899 }
900 }
901
902 switch ($form_state['values']['op']) {
903 case t('Submit changes'):
904 drupal_set_message(t('Order workflow information saved.'));
905 break;
906 case t('Create new status'):
907 $form_state['redirect'] = 'admin/store/settings/orders/edit/workflow/create';
908 }
909 }
910
911 // Theme the order state table in the order workflow settings.
912 function theme_uc_order_state_table($form) {
913 $header = array(t('State'), t('Default order status'));
914
915 foreach (element_children($form) as $state_id) {
916 $rows[] = array(
917 drupal_render($form[$state_id]['title']),
918 drupal_render($form[$state_id]['default']),
919 );
920 }
921
922 return theme('table', $header, $rows);
923 }
924
925 // Theme the order state table in the order workflow settings.
926 function theme_uc_order_status_table($form) {
927 $header = array(t('ID'), t('Title'), t('Weight'), t('State'), t('Remove'));
928
929 foreach (element_children($form) as $state_id) {
930 if ($state_id == 'create') {
931 $create = '<br />'. t('Use this button to create a custom order status: ')
932 . drupal_render($form['create']);
933
934 }
935 else {
936 $rows[] = array(
937 drupal_render($form[$state_id]['id']),
938 drupal_render($form[$state_id]['title']),
939 drupal_render($form[$state_id]['weight']),
940 drupal_render($form[$state_id]['state']),
941 array('data' => drupal_render($form[$state_id]['remove']), 'align' => 'center'),
942 );
943 }
944 }
945
946 return theme('table', $header, $rows) . $create;
947 }
948
949 // Present the form to create a custom order status.
950 function uc_order_status_create_form() {
951 $form['status_id'] = array(
952 '#type' => 'textfield',
953 '#title' => t('Order status ID'),
954 '#description' => t('Must be a unique ID with no spaces.'),
955 '#size' => 32,
956 '#maxlength' => 32,
957 '#required' => TRUE,
958 );
959
960 $form['status_title'] = array(
961 '#type' => 'textfield',
962 '#title' => t('Title'),
963 '#description' => t('The order status title displayed to users.'),
964 '#size' => 32,
965 '#maxlength' => 48,
966 '#required' => TRUE,
967 );
968
969 // Build the state option array for the order status table.
970 $options = array();
971 foreach (uc_order_state_list() as $state) {
972 $options[$state['id']] = $state['title'];
973 }
974 $form['status_state'] = array(
975 '#type' => 'select',
976 '#title' => t('Order state'),
977 '#description' => t('Set which order state this status is for.'),
978 '#options' => $options,
979 '#default_value' => 'post_checkout',
980 );
981
982 $form['status_weight'] = array(
983 '#type' => 'weight',
984 '#title' => t('Weight'),
985 '#delta' => 20,
986 '#default_value' => 0,
987 );
988
989 $form['create'] = array(
990 '#type' => 'submit',
991 '#value' => t('Create'),
992 );
993 $form['cancel'] = array(
994 '#value' => l(t('Cancel'), 'admin/store/settings/orders/edit/workflow'),
995 );
996
997 return $form;
998 }
999
1000 function uc_order_status_create_form_validate($form, &$form_state) {
1001 $new_status = strtolower(trim($form_state['values']['status_id']));
1002 if (strpos($new_status, ' ') !== FALSE || $new_status == 'all') {
1003 form_set_error('status_id', t('You have entered an invalid status ID.'));
1004 }
1005
1006 $statuses = uc_order_status_list();
1007 foreach ($statuses as $status) {
1008 if ($new_status == $status['id']) {
1009 form_set_error('status_id', t('This ID is already in use. Please specify a unique ID.'));
1010 }
1011 }
1012 }
1013
1014 function uc_order_status_create_form_submit($form, &$form_state) {
1015 db_query("INSERT INTO {uc_order_statuses} (order_status_id, title, state, "
1016 ."weight, locked) VALUES ('%s', '%s', '%s', %d, 0)",
1017 $form_state['values']['status_id'], $form_state['values']['status_title'],
1018 $form_state['values']['status_state'], $form_state['values']['status_weight']);
1019
1020 drupal_set_message(t('Custom order status created.'));
1021
1022 $form_state['redirect'] = 'admin/store/settings/orders/edit/workflow';
1023 }
1024
1025 function uc_order_panes_form() {
1026 $panes = _order_pane_list();
1027
1028 foreach ($panes as $pane) {
1029 foreach ($pane['show'] as $view) {
1030 $form['panes'][$view][$pane['id']]['title'] = array(
1031 '#value' => $pane['title'],
1032 );
1033 $form['panes'][$view][$pane['id']]['uc_order_pane_'. $pane['id'] .'_show_'. $view] = array(
1034 '#type' => 'checkbox',
1035 '#default_value' => variable_get('uc_order_pane_'. $pane['id'] .'_show_'. $view, TRUE),
1036 );
1037 $form['panes'][$view][$pane['id'