/[drupal]/contributions/modules/uc_fee/uc_fee.module
ViewVC logotype

Contents of /contributions/modules/uc_fee/uc_fee.module

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


Revision 1.1 - (show annotations) (download) (as text)
Sun Nov 16 23:47:51 2008 UTC (12 months, 1 week ago) by mrfelton
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1, DRUPAL-6--2
File MIME type: text/x-php
Initial commit of uc_fee module. This module allows fees to be added to products which will appear as line items. Fees are configurable at the class and product level.
1 <?php
2 // $Id$
3
4 /******************************************************************************
5 * Drupal Hooks *
6 ******************************************************************************/
7
8 /**
9 * Implementation of hook_help().
10 */
11 function uc_fee_help($path, $arg) {
12 switch ($path) {
13 // Help messages for the fees overview on products and classes.
14 case 'node/%/edit/fees':
15 return t('Add fees to this product using the <a href="!url">add fees form</a>. You may then adjust the settings for these fees on this page.', array('!url' => url('node/'. $arg[1] .'/edit/fees/add')));
16 case 'admin/store/products/classes/%/fees':
17 return t('Add fees to the product class using the <a href="!url">add fees form</a>. You may then adjust the settings for these fees.', array('!url' => url('admin/store/products/classes/'. $arg[4] .'/fees/add')));
18
19 // Help message for adding a fee to a product or class.
20 case 'node/%/edit/fees/add':
21 case 'admin/store/products/classes/%/fees/add':
22 return t('Select the fees you want to add and submit the form.');
23 }
24 }
25
26 /**
27 * Implementation of hook_menu().
28 */
29 function uc_fee_menu() {
30 $items['admin/store/fees'] = array(
31 'title' => 'Fees',
32 'description' => 'Create and edit fees.',
33 'page callback' => 'drupal_get_form',
34 'page arguments' => array('uc_fee_admin_form'),
35 'access arguments' => array('administer products'),
36 'type' => MENU_NORMAL_ITEM,
37 'weight' => -1,
38 'file' => 'uc_fee.admin.inc',
39 );
40 $items['admin/store/fees/overview'] = array(
41 'title' => 'Overview',
42 'type' => MENU_DEFAULT_LOCAL_TASK,
43 'weight' => 0,
44 );
45 $items['admin/store/fees/add'] = array(
46 'title' => 'Add a fee',
47 'page callback' => 'drupal_get_form',
48 'page arguments' => array('uc_fee_form'),
49 'access arguments' => array('administer products'),
50 'type' => MENU_LOCAL_TASK,
51 'weight' => 5,
52 'file' => 'uc_fee.admin.inc',
53 );
54 $items['admin/store/settings/fees'] = array(
55 'title' => 'Fee settings',
56 'description' => 'Configure the fee settings',
57 'page callback' => 'drupal_get_form',
58 'page arguments' => array('uc_fee_admin_settings'),
59 'access arguments' => array('administer products'),
60 'type' => MENU_NORMAL_ITEM,
61 'file' => 'uc_fee.admin.inc',
62 );
63 $items['admin/store/fees/%uc_fee/edit'] = array(
64 'title' => 'Edit fee',
65 'page callback' => 'drupal_get_form',
66 'page arguments' => array('uc_fee_form', 3),
67 'access arguments' => array('administer products'),
68 'type' => MENU_CALLBACK,
69 'file' => 'uc_fee.admin.inc',
70 );
71 $items['admin/store/fees/%uc_fee/delete'] = array(
72 'page callback' => 'drupal_get_form',
73 'page arguments' => array('uc_fee_delete_confirm', 3),
74 'access arguments' => array('administer products'),
75 'type' => MENU_CALLBACK,
76 'file' => 'uc_fee.admin.inc',
77 );
78
79 // Menu items for default product class fees.
80 $items['admin/store/products/classes/%uc_product_class/fees'] = array(
81 'title' => 'Fees',
82 'page callback' => 'drupal_get_form',
83 'page arguments' => array('uc_object_fees_form', 4, 'class'),
84 'access arguments' => array('administer product classes'),
85 'type' => MENU_LOCAL_TASK,
86 'weight' => 1,
87 'file' => 'uc_fee.admin.inc',
88 );
89
90 // Insert subitems into the edit node page for product types.
91 $items['node/%node/edit/fees'] = array(
92 'title' => 'Fees',
93 'page callback' => 'drupal_get_form',
94 'page arguments' => array('uc_object_fees_form', 1, 'product', 'overview'),
95 'access callback' => 'uc_fee_product_fee_access',
96 'access arguments' => array(1),
97 'type' => MENU_LOCAL_TASK,
98 'weight' => 1,
99 'file' => 'uc_fee.admin.inc',
100 );
101 $items['node/%node/edit/fees/add'] = array(
102 'title' => 'Fees',
103 'page callback' => 'drupal_get_form',
104 'page arguments' => array('uc_object_fees_form', 1, 'product', 'add'),
105 'access callback' => 'uc_product_is_product',
106 'access arguments' => array(1),
107 'type' => MENU_LOCAL_TASK,
108 'weight' => 1,
109 'file' => 'uc_fee.admin.inc',
110 );
111
112 return $items;
113 }
114
115 function uc_fee_product_fee_access($node) {
116 return uc_product_is_product($node) && node_access('update', $node);
117 }
118
119 function uc_fee_init() {
120 drupal_add_css(drupal_get_path('module', 'uc_fee') .'/uc_fee.css');
121 }
122
123 /*
124 * Implementation of hook_theme().
125 */
126 function uc_fee_theme() {
127 return array(
128 'uc_fee_admin_form' => array(
129 'arguments' => array('form' => NULL),
130 'file' => 'uc_fee.admin.inc',
131 ),
132 'uc_object_fees_form' => array(
133 'arguments' => array('form' => NULL),
134 'file' => 'uc_fee.admin.inc',
135 ),
136 'uc_fee' => array(
137 'arguments' => array('type' => NULL, 'data' => NULL, 'nid' => NULL),
138 ),
139 );
140 }
141
142 /**
143 * Implementation of hook_form_alter().
144 *
145 * Attach fee descriptions to the form with the "Add to Cart" button.
146 */
147 function uc_fee_form_alter(&$form, &$form_state, $form_id) {
148 if (strpos($form_id, 'add_to_cart_form') || strpos($form_id, 'add_product_form')) {
149 // If the node has a product list, add fees to them
150 if (count(element_children($form['products']))) {
151 foreach (element_children($form['products']) as $key) {
152 $form['products'][$key]['fees'] = _uc_fee_alter_form(node_load($key));
153 if (is_array($form['products'][$key]['fees'])) {
154 $form['products'][$key]['fees']['#tree'] = TRUE;
155 $form['products'][$key]['#type'] = 'fieldset';
156 }
157 }
158 }
159 // If not, add fees to the node.
160 else {
161 $form['fees'] = _uc_fee_alter_form($form['#parameters'][2]);
162 if (is_array($form['fees'])) {
163 $form['fees']['#weight'] = -0.8;
164 }
165 }
166 }
167 }
168
169 /**
170 * Implementation of hook_nodeapi().
171 */
172 function uc_fee_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
173 if (in_array($node->type, module_invoke_all('product_types'))) {
174 switch ($op) {
175 case 'load':
176 $fees = uc_product_get_fees($node->nid);
177 if (is_array($fees) && !empty($fees)) {
178 return array('fees' => $fees);
179 }
180 break;
181 case 'insert':
182 switch ($GLOBALS['db_type']) {
183 case 'mysqli':
184 case 'mysql':
185 db_query("INSERT IGNORE INTO {uc_product_fees} (nid, fid, ordering, default_price) SELECT %d, fid, ordering, default_price FROM {uc_class_fees} WHERE pcid = '%s'", $node->nid, $node->type);
186 break;
187 case 'pgsql':
188 db_query("INSERT INTO {uc_product_fees} (nid, fid, ordering, default_price) SELECT %d, fid, ordering, default_price FROM {uc_class_fees} WHERE pcid = '%s'", $node->nid, $node->type);
189 break;
190 }
191 break;
192 case 'delete':
193 db_query("DELETE FROM {uc_product_fees} WHERE nid = %d", $node->nid);
194 break;
195 case 'update index':
196 $output = '';
197 $fees = uc_product_get_fees($node->nid);
198 foreach ($fees as $fee) {
199 $output .= '<h3>'. $fee->name .'</h3>';
200 $output .= "\n";
201 }
202 return $output;
203 }
204 }
205 }
206
207 /******************************************************************************
208 * Ubercart Hooks *
209 ******************************************************************************/
210
211 /**
212 * Implementation of hook_product_class().
213 */
214 function uc_fee_product_class($type, $op) {
215 switch ($op) {
216 case 'delete':
217 db_query("DELETE FROM {uc_class_fees} WHERE pcid = '%s'", $type);
218 break;
219 }
220 }
221
222 /**
223 * Implementation of Übercart's hook_line_item().
224 */
225 function uc_fee_line_item() {
226 $items = array();
227 $result = db_query("SELECT * FROM {uc_fees}");
228 while ($fee = db_fetch_object($result)) {
229 $items[] = array(
230 'id' => 'uc_fee_'.$fee->fid,
231 'title' => t($fee->name),
232 'callback' => 'uc_fee_line_item_fees',
233 'weight' => 9,
234 'stored' => TRUE,
235 'add_list' => TRUE,
236 'default' => FALSE,
237 'calculated' => TRUE,
238 'display_only' => FALSE,
239 );
240 }
241 return $items;
242 }
243
244 /**
245 * Implementation of hook_order
246 *
247 * Update and save tax line items to the order.
248 */
249 function uc_fee_order($op, $arg1, $arg2) {
250 switch ($op) {
251 case 'save':
252 $changes = array();
253 $line_items = uc_fee_line_item_fees('load', $arg1);
254 if (is_array($arg1->line_items)) {
255 //drupal_set_message('<pre>'. var_export($arg1->line_items, TRUE) .'</pre>');
256 foreach ($arg1->line_items as $line) {
257 if ($line['type'] == 'fee') {
258 $delete = TRUE;
259 foreach ($line_items as $id => $new_line) {
260 if ($new_line['title'] == $line['title']) {
261 if ($new_line['amount'] != $line['amount']) {
262 uc_order_update_line_item($line['line_item_id'], $new_line['title'], $new_line['amount']);
263 $changes[] = t('Changed %title to %amount.', array('%amount' => uc_currency_format($new_line['amount']), '%title' => $new_line['title']));
264 }
265 unset($line_items[$id]);
266 $delete = FALSE;
267 break;
268 }
269 }
270 if ($delete) {
271 uc_order_delete_line_item($line['line_item_id']);
272 $changes[] = t('Removed %title.', array('%title' => $line['title']));
273 }
274 }
275 }
276 }
277 if (is_array($line_items)) {
278 foreach ($line_items as $line) {
279 uc_order_line_item_add($arg1->order_id, $line['id'], $line['title'], $line['amount'], $line['weight']);
280 $changes[] = t('Added %amount for %title.', array('%amount' => uc_currency_format($line['amount']), '%title' => $line['title']));
281 }
282 }
283 if (count($changes)) {
284 uc_order_log_changes($arg1->order_id, $changes);
285 }
286 break;
287 }
288 }
289
290 /******************************************************************************
291 * Module Functions *
292 ******************************************************************************/
293
294 /**
295 * Load a fee from the database.
296 *
297 * @param $fee_id
298 * The id of the fee.
299 * @param $nid
300 * Node id. If given, the fee will have the options that have been
301 * assigned to that node for the fee.
302 */
303 function uc_fee_load($fee_id, $nid = NULL, $type = '') {
304 if ($nid) {
305 switch ($type) {
306 case 'product':
307 $fee = db_fetch_object(db_query("SELECT f.fid, f.name, f.ordering AS default_ordering, f.price AS default_price, f.description, pf.default_price, pf.ordering FROM {uc_fees} AS f LEFT JOIN {uc_product_fees} AS pf ON f.fid = pf.fid AND pf.nid = %d WHERE f.fid = %d", $nid, $fee_id));
308 break;
309 case 'class':
310 $fee = db_fetch_object(db_query("SELECT f.fid, f.name, f.ordering AS default_ordering, f.price AS default_price, f.description, cf.default_price, cf.ordering FROM {uc_fees} AS f LEFT JOIN {uc_class_fees} AS cf ON f.fid = cf.fid AND cf.pcid = '%s' WHERE f.fid = %d", $nid, $fee_id));
311 break;
312 default:
313 $fee = db_fetch_object(db_query("SELECT * FROM {uc_fees} WHERE fid = %d", $fee_id));
314 break;
315 }
316 if (isset($fee->default_ordering) && is_null($fee->ordering)) {
317 $fee->ordering = $fee->default_ordering;
318 }
319 if (isset($fee->default_price) && is_null($fee->price)) {
320 $fee->price = $fee->default_price;
321 }
322 }
323 else {
324 $fee = db_fetch_object(db_query("SELECT * FROM {uc_fees} WHERE fid = %d", $fee_id));
325 }
326 return $fee;
327 }
328
329 // Loads all fees associated with an order.
330 function uc_order_get_fees($order) {
331 $fees = array();
332 //FIXME: this should add fees together
333 foreach($order->products as $product) {
334 $result = db_query("SELECT upf.fid FROM {uc_product_fees} AS upf LEFT JOIN {uc_fees} AS uf ON upf.fid = uf.fid WHERE upf.nid = %d ORDER BY upf.ordering, uf.name", $product->nid);
335 while ($fee = db_fetch_object($result)) {
336 $fees[$fee->fid] = uc_fee_load($fee->fid, $nid, 'product');
337 }
338 }
339 return $fees;
340 }
341
342 // Loads all fees associated with a cart.
343 function uc_cart_get_fees($cart) {
344 $fees = array();
345 //FIXME: this should add fees together
346 foreach($cart as $cart_item) {
347 $result = db_query("SELECT upf.fid FROM {uc_product_fees} AS upf LEFT JOIN {uc_fees} AS uf ON upf.fid = uf.fid WHERE upf.nid = %d ORDER BY upf.ordering, uf.name", $cart_item->nid);
348 while ($fee = db_fetch_object($result)) {
349 $fees[$fee->fid] = uc_fee_load($fee->fid, $nid, 'product');
350 }
351 }
352 return $fees;
353 }
354
355 // Loads all fees associated with a product node.
356 function uc_product_get_fees($nid) {
357 $fees = array();
358
359 $result = db_query("SELECT upf.fid FROM {uc_product_fees} AS upf LEFT JOIN {uc_fees} AS uf ON upf.fid = uf.fid WHERE upf.nid = %d ORDER BY upf.ordering, uf.name", $nid);
360 while ($fee = db_fetch_object($result)) {
361 $fees[$fee->fid] = uc_fee_load($fee->fid, $nid, 'product');
362 }
363 return $fees;
364 }
365
366 // Loads all fees associated with a product class.
367 function uc_class_get_fees($pcid) {
368 $fees = array();
369
370 $result = db_query("SELECT ucf.fid FROM {uc_class_fees} AS ucf LEFT JOIN {uc_fees} AS uf ON ucf.fid = uf.fid WHERE ucf.pcid = '%s' ORDER BY ucf.ordering, uf.name", $pcid);
371 while ($fee = db_fetch_object($result)) {
372 $fees[$fee->fid] = uc_fee_load($fee->fid, $pcid, 'class');
373 }
374 return $fees;
375 }
376
377 /**
378 * Helper function for uc_fee_form_alter()
379 */
380 function _uc_fee_alter_form($product) {
381 $nid = $product->nid;
382 $qty = $product->default_qty;
383 if (!$qty) {
384 $qty = 1;
385 }
386
387 // Load all product fees for the given nid.
388 $fees = $product->fees;
389
390 // If the product doesn't have fees, return the form as it is.
391 if (!is_array($fees)) {
392 return NULL;
393 }
394
395 $form_fees = array();
396
397 // Loop through each product fee and generate its form element.
398 foreach ($fees as $fee) {
399 $form_fees[$fee->fid] = array(
400 '#type' => 'item',
401 '#title' => $fee->name,
402 '#description' => $fee->description,
403 '#value' => uc_currency_format($fee->price),
404 );
405 }
406 return $form_fees;
407 }
408
409
410
411
412 /******************************************************************************
413 * Menu Callbacks *
414 ******************************************************************************/
415
416 /**
417 * Handle the tax line item.
418 */
419 function uc_fee_line_item_fees($op, $order) {
420 switch ($op) {
421 case 'cart-preview':
422 $fees = uc_cart_get_fees($order);
423 $script = '';
424 foreach ($fees as $fee) {
425 if ($fee->price > 0) {
426 $weight = variable_get('uc_fee_weight', 9) + ($fee->ordering / 10);
427 $script .= "set_line_item('uc_fee_". $fee->fid ."', '". $fee->name ."', ". $fee->price .", + ". $weight .", 1, false);\n";
428 }
429 }
430 if ($script) {
431 drupal_add_js("if (Drupal.jsEnabled) { \$(document).ready(function() {
432 if (window.set_line_item) {
433 ". $script .";
434 render_line_items();
435 }
436 })};", 'inline');
437 }
438 break;
439 case 'load':
440 $lines = array();
441 $fees = uc_order_get_fees($order);
442 foreach ($fees as $fee) {
443 if ($fee->price > 0) {
444 $lines[] = array(
445 'id' => 'uc_fee_'.$fee->fid,
446 'title' => $fee->name,
447 'amount' => $fee->price,
448 'weight' => variable_get('uc_fee_weight', 9) + $fee->ordering / 10,
449 );
450 }
451 }
452 return $lines;
453 }
454 }

  ViewVC Help
Powered by ViewVC 1.1.2