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

Contents of /contributions/modules/tax_receipt/tax_receipt.module

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


Revision 1.9 - (show annotations) (download) (as text)
Tue Sep 11 17:41:34 2007 UTC (2 years, 2 months ago) by suydam
Branch: MAIN
CVS Tags: DRUPAL-5--1-5, HEAD
Changes since 1.8: +10 -3 lines
File MIME type: text/x-php
Fixed install script to support db_prefix.  Fixed situation where null values were being passed during nodeapi for insert/update on nodes.
1 <?php
2 // $Id: tax_receipt.module,v 1.8 2007/08/31 15:06:16 suydam Exp $
3
4 /**
5 * @file
6 * Email the user a receipt for tax-deductible purchases.
7 */
8
9
10 /* implement hook_ecommerceapi() with op='on payment completion' */
11 function tax_receipt_ecommerceapi( &$txn, $op ) {
12 switch( $op ) {
13 case 'on payment completion':
14 watchdog('tax_receipt','Payment completed for transaction ' . $txn['txnid'] );
15
16 // does this order have any items where tax receipts are enabled?
17 // group them together and email out the stuff
18
19 $items_count=0;
20 foreach ( array_keys( $txn['items'] ) as $itemKey ) {
21
22 //$trvars = _tax_receipt_getvars($objItem->nid);
23 $pnode = node_load( $txn['items'][ $itemKey ]->nid);
24
25 watchdog('tax_receipt','Item NID = ' . $txn['items'][ $itemKey ]->nid . "<PRE>\n" . sprint_r($pnode) . "</pre>\n");
26 if ( isset( $pnode->tax_receipt_enabled ) && ( $pnode->tax_receipt_enabled == 1 || $pnode->tax_receipt_enabled == '1' ) ) {
27 // transaction object doesn't store fairmarketvalue...shoe-horn that in.
28 $txn['items'][ $itemKey]->tax_receipt_fairmarketvalue = $pnode->tax_receipt_fairmarketvalue;
29 $txn['items'][ $itemKey]->tax_receipt_enabled = $pnode->tax_receipt_enabled;
30 $items_count++;
31 }
32
33 }
34
35 watchdog('tax_receipt','There are ' . $items_count . ' items for the tax_receipt');
36 if ( $items_count ) {
37 $tr_header = variable_get('tax_receipt_header_html','');
38 $tr_footer = variable_get('tax_receipt_footer_html','');
39 $tr_css = "\n<style>\n" . variable_get('tax_receipt_css','') . "\n</style>\n";
40
41 $mailkey = 'tax_receipt_mail';
42 $to = $txn['mail'];
43 $subject = variable_get('tax_receipt_mail_subject','Tax Receipt');
44 $from = variable_get('tax_receipt_mail_from','nobody@nowhere.com');
45 $headers["MIME-Version"] = '1.0';
46 $headers["Content-Transfer-Encoding"] = '8bit';
47 $headers["Content-Type"] = "text/html; charset='utf-8';";
48
49 $message_body = $tr_css . "\n" . $tr_header . _tax_receipt_mailer_table( $txn ) . $tr_footer;
50 $stripped_body = $message_body;
51 $stripped_body = preg_replace("/</",'&lt;',$stripped_body);
52
53 if ( ! drupal_mail($mailkey,$to,$subject,$message_body,$from,$headers)) {
54 watchdog("tax_receipt","<PRE>Mailer failed:\nkey:$mailkey\nto:$to\nsubj:$subject\nFROM:$from\nHeaders: " . sprint_r($headers) . "\nBODY:$stripped_body</pre>");
55 }
56 else {
57 watchdog("tax_receipt","<PRE>Mailer successfully delivered:\nkey:$mailkey\nto:$to\nsubj:$subject\nFROM:$from\nHeaders: " . sprint_r($headers) . "\nBODY:$stripped_body</pre>");
58 }
59
60 }
61 break;
62 }
63 }
64
65 function _tax_receipt_mailer_table( $n ) {
66 // as a bug fix for v1.3 we brought in the entire txn to build this table.
67 // I don't see anywhere that we're only checking those items that are actually eligible.
68 // that has to be wrong.
69 watchdog('tax_receipt',"<strong>tax receipt mailer table being built from this node:<BR>\n<PRE>" . sprint_r($n) . "</pre>");
70 /*
71 TABLE.tax_receipt { border-collapse: collapse; padding:0; margin:0; }
72 TABLE.tax_receipt TR TD { padding: 5px; vertical-align: top; }
73 TABLE.tax_receipt TR TD.tax_receipt_header { color: #cccccc; font-weight: bold; background-color:#000000; }
74 TABLE.tax_receipt TR TD.tax_receipt_value { text-align: right; font-weight: bold; }
75 TABLE.tax_receipt TR TD.product_description { font-size: 0.8em; }
76 */
77
78 $the_table = "\n\n\n<table class='tax_receipt'>\n";
79 $the_table .= "\t<TR>\n";
80 $the_table .= "\t\t<TD class=tax_receipt_header>Item</td>\n";
81 $the_table .= "\t\t<TD class=tax_receipt_header>Value</td>\n";
82 $the_table .= "\t\t<TD class=tax_receipt_header>Price</td>\n";
83 $the_table .= "\t\t<TD class=tax_receipt_header>Deduction</td>\n";
84 $the_table .= "\t</tr>\n";
85
86 $total_deduction = 0;
87 //foreach ( $n as $objNode ) {
88 foreach ( array_keys( $n['items'] ) as $itemKey ) {
89 // only add those items to the table that are actually eligible for tax-deductions
90 if ( isset( $n['items'][ $itemKey]->tax_receipt_enabled ) && ( $n['items'][ $itemKey]->tax_receipt_enabled == 1 || $n['items'][ $itemKey]->tax_receipt_enabled == '1' ) ) {
91 $net = $n['items'][ $itemKey ]->price - $n['items'][ $itemKey ]->tax_receipt_fairmarketvalue;
92 $total_deduction += $net;
93 $the_table .= "\t<TR>\n";
94 $the_table .= "\t\t<TD class=product_description>" . $n['items'][ $itemKey ]->title . "</td>\n";
95 $the_table .= "\t\t<TD class=tax_receipt_value>$" . number_format( $n['items'][ $itemKey ]->tax_receipt_fairmarketvalue, 2 ) . "</td>\n";
96 $the_table .= "\t\t<TD class=tax_receipt_value>$" . number_format( $n['items'][ $itemKey ]->price, 2 ) . "</td>\n";
97 $the_table .= "\t\t<TD class=tax_receipt_value>$" . number_format( $net, 2 ) . "</td>\n";
98 $the_table .= "\t</TR>\n";
99 }
100 }
101
102 $the_table .= "\t<TR>\n";
103 $the_table .= "\t\t<TD class=tax_receipt_total_text colspan=3>TOTAL:</td>\n";
104 $the_table .= "\t\t<TD class='tax_receipt_value tax_receipt_total'>$" . number_format( $total_deduction, 2) . "</td>\n";
105 $the_table .= "\t</TR>\n";
106 $the_table .= "</table>\n\n\n";
107
108 $stripped_table = $the_table;
109 $stripped_table = preg_replace("/</",'&lt;',$stripped_table);
110 watchdog('tax_receipt',"Mailer table created: <PRE>$stripped_table</pre>\n");
111
112 return $the_table;
113
114 }
115
116 // hook_menu()
117 function tax_receipt_menu($may_cache) {
118 $items = array();
119 if ( !$may_cache ) {
120 $items[] = array(
121 'path' => 'admin/ecsettings/tax_receipt',
122 'title' => t('Tax Receipt Settings'),
123 'description' => t('Set system defaults for the Tax Receipt module.'),
124 'callback' => 'tax_receipt_admin_settings_form',
125 'access' => user_access('administer tax_receipt settings')
126 );
127 $items[] = array(
128 'path' => 'admin/ecsettings/tax_receipt_preview',
129 'title' => t('Tax Receipt HTML Preview'),
130 'description' => t('Preview the HTML output of your tax receipt.'),
131 'callback' => '_tax_receipt_preview',
132 'access' => user_access('administer tax_receipt settings'),
133 'type' => MENU_CALLBACK
134 );
135 }
136 return $items;
137 }
138
139 function _tax_receipt_preview() {
140 $from = variable_get('tax_receipt_mail_from','nobody@nowhere.com');
141 $subj = variable_get('tax_receipt_mail_subject','Tax Receipt');
142 $head = variable_get('tax_receipt_header_html','<h1>Tax Receipt</h1>');
143 $foot = variable_get('tax_receipt_footer_html','Thanks, Brian');
144 $css = variable_get('tax_receipt_css','');
145
146 $output = '<h1>Tax Receipt Preview</h1><strong>' . l('Back to Settings','admin/ecsettings/tax_receipt') . '</strong><BR>Your preview starts below this line:<HR>';
147 $output .= "<style>$css</style>\n$head\n";
148 $output .= "\n\n\n<table class='tax_receipt'>\n";
149 $output .= "\t<TR>\n";
150 $output .= "\t\t<TD class=tax_receipt_header>Item</td>\n";
151 $output .= "\t\t<TD class=tax_receipt_header>Value</td>\n";
152 $output .= "\t\t<TD class=tax_receipt_header>Price</td>\n";
153 $output .= "\t\t<TD class=tax_receipt_header>Deduction</td>\n";
154 $output .= "\t</tr>\n";
155 $output .= "\t<TR>\n";
156 $output .= "\t\t<TD class=product_description>Item #1</td>\n";
157 $output .= "\t\t<TD class=tax_receipt_value>$3.45</td>\n";
158 $output .= "\t\t<TD class=tax_receipt_value>$6.00</td>\n";
159 $output .= "\t\t<TD class=tax_receipt_value>$2.55</td>\n";
160 $output .= "\t</TR>\n";
161 $output .= "\t<TR>\n";
162 $output .= "\t\t<TD class=product_description>Item #2</td>\n";
163 $output .= "\t\t<TD class=tax_receipt_value>$0.00</td>\n";
164 $output .= "\t\t<TD class=tax_receipt_value>$50.00</td>\n";
165 $output .= "\t\t<TD class=tax_receipt_value>$50.00</td>\n";
166 $output .= "\t</TR>\n";
167 $output .= "\t<TR>\n";
168 $output .= "\t\t<TD class=tax_receipt_total_text colspan=3>TOTAL:</td>\n";
169 $output .= "\t\t<TD class='tax_receipt_value tax_receipt_total'>$52.55</td>\n";
170 $output .= "\t</TR>\n";
171 $output .= "</table>\n\n\n";
172 $output .= "<HR>End of Preview\n";
173
174 return $output;
175 }
176
177 function tax_receipt_admin_settings_form() {
178 return drupal_get_form('tax_receipt_admin_settings');
179 }
180
181 function _tax_receipt_eligible( $type ) {
182 $allowed_list = variable_get('tax_receipt_eligibles',array());
183 if ( count( preg_grep("/^$type$/", $allowed_list))) {
184 return true;
185 }
186 else {;
187 return false;;
188 }
189
190 }
191
192 function tax_receipt_nodeapi(&$node,$op) {
193 switch($op) {
194 case 'insert':
195 case 'update':
196 $eligibles = variable_get("tax_receipt_eligibles",array());
197 if ( in_array( $node->type, $eligibles ) ) {
198 // wonder why we'd even get this...
199 if ( !isset( $node->tax_receipt_enabled ) ) {
200 $node->tax_receipt_enabled = 0;
201 }
202 if ( !isset( $node->tax_receipt_fairmarketvalue ) ) {
203 $node->tax_receipt_fairmarketvalue = 0;
204 }
205 db_query( "DELETE FROM {tax_receipt_nodes} WHERE nid=%d", $node->nid );
206 db_query("INSERT INTO {tax_receipt_nodes} (nid,tax_receipt_enabled,tax_receipt_fairmarketvalue)
207 VALUES
208 (" . $node->nid . "," . $node->tax_receipt_enabled . ",'" . $node->tax_receipt_fairmarketvalue . "')"
209 );
210 }
211 break;
212 case 'delete':
213 db_query("DELETE FROM {tax_receipt_nodes} WHERE nid = %d", $node->nid );
214 break;
215 case 'load':
216 $thearray = array();
217 // check this node-type to see if it's tax_receipt enabled.
218 // if it's not, don't even get any vars.
219 // tax_receipt_eligibles is an array of node types for which we can have tax_receipts
220 $eligibles = variable_get("tax_receipt_eligibles",array());
221 if ( in_array( $node->type, $eligibles ) ) {
222 //drupal_set_message($node->type . "is eligible for tax_receipt...get vars");
223 $thearray = _tax_receipt_getvars( $node->nid );
224 }
225 //else {
226 //drupal_set_message($node->type . "is not eligible for tax_receipt");
227 //}
228 return $thearray;
229 break;
230 case 'prepare':
231 if ( !isset( $node->tax_receipt_enabled ) ) {
232 $node->tax_receipt_enabled = '0';
233 }
234 if ( !isset( $node->tax_receipt_fairmarketvalue ) ) {
235 $node->tax_receipt_fairmarketvalue = '0';
236 }
237 break;
238 case 'view':
239 }
240 }
241
242 function _tax_receipt_getvars( $nid ) {
243 // only do this for ints
244 if ( is_numeric( $nid ) ) {
245 //watchdog("tax_receipt",'tax receipt getvars called for $nid');
246 $statement = "SELECT * FROM {tax_receipt_nodes} WHERE nid = $nid";
247 //drupal_set_message($statement);
248 $sth = db_query( $statement );
249 $row = array();
250 if ( db_num_rows( $sth ) ) {
251 $row = db_fetch_array( $sth );
252
253 // If it's empty string, use default text for the link
254 if ( $row['tax_receipt_fairmarketvalue'] == '' || $row['tax_receipt_fairmarketvalue'] == 0 ) {
255 $row['tax_receipt_fairmarketvalue'] = 0;
256 }
257
258 }
259 else {
260 $row = array('tax_receipt_enabled' => 0, 'tax_receipt_fairmarketvalue' => '0' );
261 }
262 //drupal_set_message("<PRE>" . sprint_r($row) . "</pre>");
263 return $row;
264 }
265 else {
266 return;
267 }
268 }
269
270 // remove a specific item from an array
271 if ( !function_exists('array_remval') ) {
272 function array_remval($val, &$arr) {
273 $array_remval = $arr;
274 for($x=0;$x<count($array_remval);$x++) {
275 $i=array_search($val,$array_remval);
276 if (is_numeric($i)) {
277 $array_temp = array_slice($array_remval, 0, $i );
278 $array_temp2 = array_slice($array_remval, $i+1, count($array_remval)-1 );
279 $array_remval = array_merge($array_temp, $array_temp2);
280 }
281 }
282 return $array_remval;
283 }
284 }
285
286
287 // create the "should be part of PHP's core" sprint_r function...but only if I haven't
288 // already added it elsewhere...
289 if (!function_exists('sprint_r')) {
290 function sprint_r($var) {
291 ob_start();
292 print_r($var);
293 $ret = ob_get_contents();
294 ob_end_clean();
295 return $ret;
296 }
297 }
298
299
300 function tax_receipt_form_alter( $form_id, &$form ) {
301 if ( $form_id == 'product_node_form' ) {
302 $tax_receipt_vars = _tax_receipt_getvars( arg(1) );
303 $yesno = array('1' => ('Yes'), '0' => t('No') );
304
305 //drupal_set_message("getting skipcart vars....");
306 // why doesn't global $node;$node->nid work here????
307 //drupal_set_message('$skipcart_vars[\'skipcart_enabled\'] = ' . $skipcart_vars['skipcart_enabled'] );
308
309 $form['tax_receipt'] = array(
310 '#type' => 'fieldset',
311 '#title' => 'Tax Receipt Configuration',
312 '#collapsible' => TRUE,
313 '#collapsed' => FALSE,
314 '#weight' => 100
315 );
316 $form['tax_receipt']['tax_receipt_enabled'] = array(
317 '#type' => 'radios',
318 '#title' => t('Enable Tax Receipt for this product?'),
319 '#options' => $yesno,
320 '#default_value' => $tax_receipt_vars['tax_receipt_enabled'],
321 '#description' => t('If this is checked then user will receive a tax receipt for this product on purchase.'),
322 );
323
324 // use "DEFAULT" to use the sitewide default
325 $form['tax_receipt']['tax_receipt_fairmarketvalue'] = array(
326 '#type' => 'textfield',
327 '#title' => t('Fair Market Value'),
328 '#default_value' => $tax_receipt_vars['tax_receipt_fairmarketvalue'],
329 '#description' => t('What is the fair market value of this product? Cash donations are face-value deductible, for those leave this number at 0. Charitable purchases are only deductible above and beyond fair market value. For example, buying a coffee mug from NPR for $25 allows you to deduct probably $19 since the coffee mug has a fair market value of about $6.'),
330 '#maxlength' => 255,
331 '#required' => FALSE,
332 '#size' => 25,
333 '#weight' => 300
334 );
335 }
336
337 }
338
339 // admin settings function
340 function tax_receipt_admin_settings() {
341 $yesno = array('1' => t('Yes'), '0' => t('No') );
342
343 $default_css = "
344 TABLE.tax_receipt {
345 border-collapse: collapse;
346 padding:0;
347 margin:0;
348 }
349 TABLE.tax_receipt TR TD {
350 padding: 5px;
351 vertical-align: top;
352 }
353 TABLE.tax_receipt TR TD.tax_receipt_header {
354 color: #cccccc;
355 background-color:#000000;
356 font-weight: bold;
357 }
358 TABLE.tax_receipt TR TD.tax_receipt_value {
359 text-align: right;
360 font-weight: bold;
361 }
362 TABLE.tax_receipt TR TD.product_description {
363 font-size: 0.8em;
364 }";
365
366 $form['tax_receipt_eligibles'] = array(
367 '#type' => 'checkboxes',
368 '#title' => t('These node types should store a tax_receipt yes/no setting'),
369 '#options' => node_get_types('names'),
370 '#default_value' => variable_get('tax_receipt_eligibles',array('product')),
371 '#description' => t('These node-types can have a tax_receipt yes/no setting. This is intentionally *not* synchronized with those nodes that can be products.'),
372 );
373
374 $form['tax_receipt_mail_from'] = array(
375 '#type' => 'textfield',
376 '#title' => t('Mail From'),
377 '#default_value' => variable_get('tax_receipt_mail_from','nobody@nowhere.com'),
378 '#size' => 60,
379 '#maxlength' => 64,
380 '#description' => t('Tax receipts are emailed to purchasers. What should the from address on the message be?'),
381 );
382
383 $form['tax_receipt_mail_subject'] = array(
384 '#type' => 'textfield',
385 '#title' => t('Mail Subject'),
386 '#default_value' => variable_get('tax_receipt_mail_subject','Tax Receipt'),
387 '#size' => 60,
388 '#maxlength' => 64,
389 '#description' => t('Tax receipts are emailed to purchasers. What should the subject be?'),
390 );
391
392 $form['tax_receipt_header_html'] = array(
393 '#type' => 'textarea',
394 '#title' => t('HTML Header for receipt'),
395 '#description' => t('This text will appear atop your tax receipt, followed by a list of products and then the footer (below)'),
396 '#default_value' => variable_get('tax_receipt_header_html','<h1>Tax Receipt</h1>')
397 );
398
399 $form['tax_receipt_footer_html'] = array(
400 '#type' => 'textarea',
401 '#title' => t('HTML Footer for receipt'),
402 '#description' => t('This text will appear at the bottom of your tax receipt.'),
403 '#default_value' => variable_get('tax_receipt_footer_html','')
404 );
405
406 $form['tax_receipt_css'] = array(
407 '#type' => 'textarea',
408 '#title' => t('Inline CSS for Receipt Table'),
409 '#description' => t('tax_receipt.module creates a table of class tax_receipt, with cells called tax_receipt_header (column headers),
410 tax_receipt_value (price cell) and tax_receipt_product_name, tax_receipt_product_description. You can use this
411 textarea to over-ride the css (default is provided here for you). Because many email clients will not access remotely
412 sourced css, this code will be placed <i>inline</i> and delivered with your message.<BR /><BR />' . l('Click here to
413 preview the email which will be sent','admin/ecsettings/tax_receipt_preview') . '. <strong>Be sure to save changes
414 <i>first</i> as this link takes you away from this page</strong><BR /><BR />In case you screw up the css, here is the
415 shipped default: <BR><PRE>'.$default_css .'</pre>'),
416 '#rows' => 15,
417 '#default_value' => variable_get('tax_receipt_css',$default_css)
418 );
419
420
421 //$form['array_filter'] = array('#type' => 'hidden' );
422 return system_settings_form( $form );
423 }
424
425 /* permissons for access_control */
426 function tax_receipt_perm() {
427 return array('administer tax_receipt settings');
428 }

  ViewVC Help
Powered by ViewVC 1.1.2