/[drupal]/contributions/modules/invoice/invoice_ajax.inc
ViewVC logotype

Contents of /contributions/modules/invoice/invoice_ajax.inc

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


Revision 1.5 - (show annotations) (download) (as text)
Sat Dec 13 14:03:32 2008 UTC (11 months, 2 weeks ago) by pvogelaar
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +6 -6 lines
File MIME type: text/x-php
* Fixed bug: "Invoice items : Unit Cost incl VAT is wrong whent you use a VAT less of 10%" => http://drupal.org/node/345800
* Added a TODO: Possibility to link an invoice to a site user + page for that user to view his invoices => http://drupal.org/node/346516
  - With a extra option to also send the invoice by email (if no site user is selected the customer email field that is not implemented yet
    will be choosen, if both are empty an error will be thrown if this checkbox is still checked. => http://drupal.org/node/346005
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * Invoice module
7 *
8 * This module was developed by Platina Designs, http://www.platinadesigns.nl
9 *
10 * @author Pieter Vogelaar <ps.vogelaar@platinadesigns.nl>
11 */
12
13 /**
14 * Helper function to get invoice Javascript
15 */
16 function _invoice_get_js() {
17 return
18 <<<EOD
19 $(document).ready(function(){
20 $("#edit-search").blur(function(){
21 if ($("#edit-search").val().length > 0 && $("#edit-search").val() > 0) {
22 invoice_get_customer_info($("#edit-search").val());
23 }
24 else if ($("#edit-search").val().length < 1) {
25 invoice_get_customer_info('set_empty');
26 }
27 });
28 });
29
30 function invoice_set_template(value) {
31 $.get("http://"+Drupal.settings['invoice']['host']+Drupal.settings['basePath']+"invoice/set/template",
32 { value: value
33 },
34 function(data) {
35 if (data['error'] != undefined && data['error'] != '') {
36 alert(data['error']);
37 }
38 else {
39 $('#edit-vat').val(data['vat']);
40 }
41 },
42 "json"
43 );
44 }
45
46 function invoice_get_customer_info(value) {
47 $.get("http://"+Drupal.settings['invoice']['host']+Drupal.settings['basePath']+"invoice/get/customer_info",
48 { value: value
49 },
50 function(data) {
51 if (data['error'] != undefined && data['error'] != '') {
52 alert(data['error']);
53 }
54 else if (value == 'set_empty' || (data['set_empty'] != undefined && data['set_empty'] != '')) {
55 $('#edit-company-name').val('');
56 $('#edit-firstname').val('');
57 $('#edit-lastname').val('');
58 $('#edit-street').val('');
59 $('#edit-building-number').val('');
60 $('#edit-zipcode').val('');
61 $('#edit-city').val('');
62 $('#edit-country').val('');
63 $('#edit-customer-description').val('');
64 $('#edit-coc-number').val('');
65 $('#edit-vat-number').val('');
66 }
67 else {
68 $('#edit-search').val(data['search_customer']);
69 $('#edit-company-name').val(data['company_name']);
70 $('#edit-firstname').val(data['firstname']);
71 $('#edit-lastname').val(data['lastname']);
72 $('#edit-street').val(data['street']);
73 $('#edit-building-number').val(data['building_number']);
74 $('#edit-zipcode').val(data['zipcode']);
75 $('#edit-city').val(data['city']);
76 $('#edit-country').val(data['country']);
77 $('#edit-coc-number').val(data['coc_number']);
78 $('#edit-vat-number').val(data['vat_number']);
79 if (window.mceToggle) { mceToggle('edit-customer-description', 'wysiwyg4customer-description'); }
80 $('#edit-customer-description').val(data['description']);
81 if (window.mceToggle) { mceToggle('edit-customer-description', 'wysiwyg4customer-description'); }
82 }
83 },
84 "json"
85 );
86 }
87
88 function invoice_save_item(value) {
89 $.post("http://"+Drupal.settings['invoice']['host']+Drupal.settings['basePath']+"invoice/save/item",
90 { iid: $("#edit-iid").val(),
91 invoice_number: $("#edit-invoice-number").val(),
92 description: $("#edit-description").val(),
93 quantity: $("#edit-quantity").val(),
94 price_without_vat: $("#edit-price-without-vat").val(),
95 price_with_vat: $("#edit-price-with-vat").val(),
96 vat: $("#edit-vat").val()
97 },
98 function(data) {
99 if (data['error'] != undefined && data['error'] != '') {
100 alert(data['error']);
101 }
102 else {
103 if (data['remove_empty_row'] != undefined && data['remove_empty_row'] != '') {
104 $('.invoice-items-empty').remove();
105 }
106
107 // if invoice item id is not empty we just changed an invoice item, so update the row
108 if (data['iid'] != undefined && data['iid'] != '') {
109 $('.invoice-items .item-'+data['iid']+' td:nth-child(1)').html(data['description']);
110 $('.invoice-items .item-'+data['iid']+' td:nth-child(2)').html(data['vat']);
111 $('.invoice-items .item-'+data['iid']+' td:nth-child(3)').html(data['quantity']);
112 $('.invoice-items .item-'+data['iid']+' td:nth-child(4)').html(data['exunitcost']);
113 $('.invoice-items .item-'+data['iid']+' td:nth-child(5)').html(data['incunitcost']);
114 $('.invoice-items .item-'+data['iid']+' td:nth-child(6)').html(data['exsubtotal']);
115 $('.invoice-items .item-'+data['iid']+' td:nth-child(7)').html(data['incsubtotal']);
116 }
117 else {
118 $('.invoice-items table').append(data['content']);
119 }
120
121 // reset invoice item form
122 $('#edit-iid').val('');
123 $('#edit-description').val('');
124 $('#edit-quantity').val('');
125 $('#edit-price-without-vat').val('');
126 $('#edit-price-with-vat').val('');
127 $('#edit-vat').val(data['activevat']);
128 $('#button-save-item').val(data['actionvalue']);
129
130 // set new totals
131 $('.invoice-items .extotal').html(data['extotal']);
132 $('.invoice-items .inctotal').html(data['inctotal']);
133 }
134 },
135 "json"
136 );
137 }
138
139 function invoice_edit_item(value) {
140 $.get("http://"+Drupal.settings['invoice']['host']+Drupal.settings['basePath']+"invoice/edit/item",
141 { iid: value,
142 invoice_number: $("#edit-invoice-number").val()
143 },
144 function(data) {
145 if (data['error'] != undefined && data['error'] != '') {
146 alert(data['error']);
147 }
148 else {
149 $('#edit-iid').val(value);
150 $('#edit-description').val(data['description']);
151 $('#edit-vat').val(data['vat']);
152 $('#edit-quantity').val(data['quantity']);
153 $('#edit-price-without-vat').val(data['exunitcost']);
154 $('#edit-price-with-vat').val(data['incunitcost']);
155 $('#button-save-item').val(data['actionvalue']);
156 }
157 },
158 "json"
159 );
160 }
161
162 function invoice_delete_item(value) {
163 $.get("http://"+Drupal.settings['invoice']['host']+Drupal.settings['basePath']+"invoice/delete/item",
164 { iid: value,
165 invoice_number: $("#edit-invoice-number").val()
166 },
167 function(data) {
168 if (data['error'] != undefined && data['error'] != '') {
169 alert(data['error']);
170 }
171 else {
172 $('.invoice-items .item-'+value).remove();
173 $('.invoice-items .extotal').html(data['extotal']);
174 $('.invoice-items .inctotal').html(data['inctotal']);
175 }
176 },
177 "json"
178 );
179 }
180 EOD;
181 }
182
183 /**
184 * Set the chosen invoice when creating a node
185 */
186 function invoice_set_template() {
187 $template = check_plain($_GET['value']);
188 $_SESSION['invoice_template'] = $template;
189 $a_items['vat'] = _invoice_get_variable($template, 'vat');
190 drupal_json($a_items);
191 exit();
192 }
193
194 /**
195 * Search if the customer already exists
196 */
197 function invoice_search_customer($value) {
198 $a_items = array();
199 $customer_value = check_plain($value);
200
201 $result = db_query("SELECT * FROM {invoice_customers} ic
202 LEFT JOIN {invoice_invoices} ii ON ic.invoice_id=ii.iid
203 WHERE ii.uid=%d AND (company_name LIKE '%%". $customer_value ."%' OR lastname LIKE '%%". $customer_value ."%' OR firstname LIKE '%%". $customer_value ."%')
204 GROUP BY vat_number,coc_number,company_name,country,city,zipcode,building_number,lastname,firstname
205 ORDER BY company_name, lastname, firstname, invoice_id DESC",
206 $GLOBALS['user']->uid
207 );
208 while ($row = db_fetch_object($result)) {
209 $key = $row->cid;
210 $value = NULL;
211 if (!empty($row->company_name)) {
212 $value = $row->company_name;
213 $value = !empty($row->zipcode) ? $value ." - ". $row->zipcode : $value;
214 $value = !empty($row->building_number) ? $value ." - ". $row->building_number : $value;
215 $value = !empty($row->city) ? $value ." - ". $row->city : $value;
216 $value = !empty($row->country) ? $value ." - ". $row->country : $value;
217 $value = !empty($row->vat_number) ? $value ." - ". $row->vat_number : $value;
218 $value = !empty($row->coc_number) ? $value ." - ". $row->coc_number : $value;
219 $value = !empty($row->lastname) ? $value ."\n ". $row->lastname : $value;
220 $value = !empty($row->firstname) ? $value ."\n ". $row->firstname : $value;
221 }
222 else {
223 $value = $row->lastname . (!empty($row->firstname) ? ', '. $row->firstname : '');
224 }
225 $a_items[$key] = check_plain($value);
226 }
227
228 drupal_json($a_items);
229 exit();
230 }
231
232 /**
233 * Get customer info
234 */
235 function invoice_get_customer_info() {
236 // Create alias
237 $fv =& $_GET;
238
239 $a_data = db_fetch_array(db_query("SELECT company_name,firstname,lastname,street,building_number,zipcode,city,country,coc_number,vat_number,ic.description
240 FROM {invoice_customers} ic
241 LEFT JOIN {invoice_invoices} ii ON ic.invoice_id=ii.iid
242 WHERE ii.uid=%d AND ic.cid=%d
243 ORDER BY company_name DESC, lastname DESC, firstname DESC, ic.invoice_id DESC
244 LIMIT 1",
245 $GLOBALS['user']->uid,
246 $fv['value']
247 ));
248
249 if (count($a_data) == 0) {
250 $a_data['set_empty'] = TRUE;
251 }
252 else {
253 $a_data['search_customer'] = !empty($a_data['company_name']) ? $a_data['company_name'] : $a_data['lastname'] . (!empty($a_data['firstname']) ? ', '. $a_data['firstname'] : '');
254 }
255
256 drupal_json($a_data);
257 exit;
258 }
259
260 /**
261 * Add an invoice item
262 */
263 function invoice_save_item() {
264 // Create alias
265 $fv =& $_POST;
266
267 $a_data = array();
268
269 // Set locale so money has the right format for the preferred culture
270 if (intval($fv['invoice_number']) == 0) {
271 if ($locale = _invoice_get_variable(_invoice_get_chosen_template(), 'locale')) {
272 setlocale(LC_MONETARY, $locale);
273 }
274 $active_template = _invoice_get_chosen_template();
275 }
276 else {
277 if ($template = db_result(db_query("SELECT it.name FROM {invoice_invoices} ii LEFT JOIN {invoice_templates} it ON ii.tid=it.tid WHERE ii.iid=%d", $fv['invoice_number']))) {
278 if ($locale = _invoice_get_variable($template, 'locale')) {
279 setlocale(LC_MONETARY, $locale);
280 }
281 $active_template = $template;
282 }
283 }
284
285 // Display error if price_wihtout_vat and price_with_vat are both not filled in
286 if (empty($fv['price_without_vat']) && empty($fv['price_with_vat'])) {
287 $a_data['error'] = t('Error') .': '. t('You have to fill in either "Price without VAT" or "Price with VAT"!');
288 }
289
290 if (!empty($a_data['error'])) {
291 drupal_json($a_data);
292 exit;
293 }
294
295 // Typecast strings to doubles and replace comma with a dot
296 $fv['quantity'] = (double) str_replace(',', '.', $fv['quantity']);
297 $fv['price_without_vat'] = (double) str_replace(',', '.', $fv['price_without_vat']);
298 $fv['price_with_vat'] = (double) str_replace(',', '.', $fv['price_with_vat']);
299
300 // Get the price without VAT
301 if (!empty($fv['price_without_vat'])) {
302 $unitcost = $fv['price_without_vat'];
303 }
304 else {
305 $unitcost = $fv['price_with_vat'] / _invoice_vat_percent_to_decimal(variable_get('invoice_vat', 0));
306 }
307
308 // Round the price to 3 decimals
309 $unitcost = round($unitcost, 3);
310
311 // Round quantity to 2 decimals
312 $fv['quantity'] = round($fv['quantity'], 2);
313
314 if (intval($fv['iid']) > 0) {
315 // item id is greater than zero, so we are saving an existing invoice item
316 db_query("UPDATE {invoice_items}
317 SET description='%s', vat='%f', quantity='%f', unitcost='%f' WHERE iid=%d AND uid=%d AND invoice_id=%d",
318 $fv['description'],
319 $fv['vat'],
320 $fv['quantity'],
321 $unitcost,
322 $fv['iid'],
323 $GLOBALS['user']->uid,
324 $fv['invoice_number']
325 );
326 }
327 else {
328 // Insert invoice item into the invoice items table
329 db_query("INSERT INTO {invoice_items}
330 (description,vat,quantity,unitcost,invoice_id,uid,created) VALUES ('%s',%f,%f,%f,%d,%d,'%s')",
331 $fv['description'],
332 $fv['vat'],
333 $fv['quantity'],
334 $unitcost,
335 $fv['invoice_number'],
336 $GLOBALS['user']->uid,
337 date('Y-m-d H:i:s')
338 );
339 }
340
341 // Count the added items and calculate invoice totals
342 $count = db_result(db_query("SELECT COUNT(*) as count FROM {invoice_items} WHERE uid=%d AND invoice_id=%d",
343 $GLOBALS['user']->uid,
344 $fv['invoice_number']
345 ));
346
347 if (intval($fv['iid']) > 0) {
348 // item id is greater than zero, so we are dealing with an existing invoice item
349 $a_data['iid'] = check_plain($fv['iid']);
350 $a_data['description'] = nl2br(check_plain($fv['description']));
351 $a_data['vat'] = check_plain($fv['vat']) .'%';
352 $a_data['quantity'] = check_plain($fv['quantity']);
353 $a_data['exunitcost'] = money_format('%.3n', _invoice_round($unitcost, 3));
354 $a_data['incunitcost'] = money_format('%.2n', _invoice_round($unitcost * _invoice_vat_percent_to_decimal($fv['vat']), 2));
355 $a_data['exsubtotal'] = money_format('%.2n', _invoice_round($fv['quantity'] * $unitcost, 2));
356 $a_data['incsubtotal'] = money_format('%.2n', _invoice_round($fv['quantity'] * $unitcost * _invoice_vat_percent_to_decimal($fv['vat']), 2));
357 $a_data['actionvalue'] = t('Add item');
358 }
359 else {
360 // Set row class name
361 $class = 'item-'. db_last_insert_id('invoice_item', 'iid');
362
363 // Compose content to send back to the browser
364 $a_data['content'] = sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td class="actions">%s</td></tr>',
365 $count & 1 ? $class .' odd' : $class .' even',
366 nl2br(check_plain($fv['description'])),
367 check_plain($fv['vat']) .'%',
368 check_plain($fv['quantity']),
369 money_format('%.3n', _invoice_round($unitcost, 3)),
370 money_format('%.2n', _invoice_round($unitcost * _invoice_vat_percent_to_decimal($fv['vat']), 2)),
371 money_format('%.2n', _invoice_round($fv['quantity'] * $unitcost, 2)),
372 money_format('%.2n', _invoice_round($fv['quantity'] * $unitcost * _invoice_vat_percent_to_decimal($fv['vat']), 2)),
373 _invoice_get_icon('edit', NULL, array(
374 'onclick' => sprintf("invoice_edit_item('%d')", db_last_insert_id('invoice_item', 'iid')),
375 'class' => 'mouse-pointer',
376 'title' => t('Edit'),
377 ))
378 .
379 _invoice_get_icon('delete', NULL, array(
380 'onclick' => sprintf("invoice_delete_item('%d')", db_last_insert_id('invoice_item', 'iid')),
381 'class' => 'mouse-pointer',
382 'title' => t('Delete'),
383 ))
384 );
385
386 // Remove the empty from the page
387 $a_data['remove_empty_row'] = TRUE;
388 }
389
390 // Define active vat value to put back on the resetted item form
391 $a_data['activevat'] = _invoice_get_variable($active_template, 'vat');
392
393 // Get invoice totals
394 $a_totals = _invoice_get_invoice_totals($fv['invoice_number'], $GLOBALS['user']->uid);
395
396 // Set total
397 $a_data['extotal'] = money_format('%.2n', _invoice_round($a_totals['extotal'], 2));
398 $a_data['inctotal'] = money_format('%.2n', _invoice_round($a_totals['inctotal'], 2));
399
400 drupal_json($a_data);
401 exit;
402 }
403
404 /**
405 * Edit an invoice item
406 */
407 function invoice_edit_item() {
408 $fv =& $_GET;
409 $a_data = array();
410
411 // Check if the item to delete exists and is owned by this owner
412 $a_invoice = db_fetch_object(db_query("SELECT *, COUNT(*) AS count
413 FROM {invoice_items}
414 WHERE iid=%d AND uid=%d AND invoice_id=%d GROUP BY iid",
415 $fv['iid'],
416 $GLOBALS['user']->uid,
417 $fv['invoice_number']
418 ));
419
420 if ($a_invoice->count == 0) {
421 $a_data['error'] = t('This item id does not exist or you are not the owner!');
422 }
423 else {
424 $a_data['description'] = $a_invoice->description;
425 $a_data['vat'] = $a_invoice->vat;
426 $a_data['quantity'] = $a_invoice->quantity;
427 $a_data['exunitcost'] = $a_invoice->unitcost;
428 $a_data['incunitcost'] = $a_invoice->unitcost * _invoice_vat_percent_to_decimal(variable_get('invoice_vat', 0));
429 $a_data['actionvalue'] = t('Save item');
430 }
431
432 drupal_json($a_data);
433 exit;
434 }
435
436 /**
437 * Delete an invoice item
438 */
439 function invoice_delete_item() {
440 $fv =& $_GET;
441 $a_data = array();
442
443 // Set locale so money has the right format for the preferred culture
444 if (intval($fv['invoice_number']) == 0) {
445 if ($locale = _invoice_get_variable(_invoice_get_chosen_template(), 'locale')) {
446 setlocale(LC_MONETARY, $locale);
447 }
448 }
449 elseif ($template = db_result(db_query("SELECT it.name FROM {invoice_invoices} ii LEFT JOIN {invoice_templates} it ON ii.tid=it.tid WHERE ii.iid=%d", $fv['invoice_number']))) {
450 if ($locale = _invoice_get_variable($template, 'locale')) {
451 setlocale(LC_MONETARY, $locale);
452 }
453 }
454
455 // Check if the item to delete exists and is owned by this owner
456 $a_invoice = db_fetch_object(db_query("SELECT COUNT(*) AS count FROM {invoice_items} WHERE iid=%d AND uid=%d AND invoice_id=%d GROUP BY iid",
457 $fv['iid'],
458 $GLOBALS['user']->uid,
459 $fv['invoice_number']
460 ));
461
462 if ($a_invoice->count == 0) {
463 $a_data['error'] = t('This item id does not exist, does not belong to this invoice or you are not the owner!');
464 }
465 else {
466 db_query("DELETE FROM {invoice_items} WHERE iid=%d AND uid=%d AND invoice_id=%d",
467 $fv['iid'],
468 $GLOBALS['user']->uid,
469 $fv['invoice_number']
470 );
471
472 // Get invoice totals
473 $a_totals = _invoice_get_invoice_totals($fv['invoice_number'], $GLOBALS['user']->uid);
474
475 // Set total
476 $a_data['extotal'] = money_format('%.2n', _invoice_round($a_totals['extotal'], 2));
477 $a_data['inctotal'] = money_format('%.2n', _invoice_round($a_totals['inctotal'], 2));
478 }
479
480 drupal_json($a_data);
481 exit;
482 }

  ViewVC Help
Powered by ViewVC 1.1.2