Cleanup: removed all closing tags in php files.
[fa-stable.git] / sales / customer_invoice.php
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 //---------------------------------------------------------------------------
13 //
14 //      Entry/Modify Sales Invoice against single delivery
15 //      Entry/Modify Batch Sales Invoice against batch of deliveries
16 //
17 $page_security = 'SA_SALESINVOICE';
18 $path_to_root = "..";
19 include_once($path_to_root . "/sales/includes/cart_class.inc");
20 include_once($path_to_root . "/includes/session.inc");
21 include_once($path_to_root . "/includes/data_checks.inc");
22 include_once($path_to_root . "/includes/manufacturing.inc");
23 include_once($path_to_root . "/sales/includes/sales_db.inc");
24 include_once($path_to_root . "/sales/includes/sales_ui.inc");
25 include_once($path_to_root . "/reporting/includes/reporting.inc");
26 include_once($path_to_root . "/taxes/tax_calc.inc");
27 include_once($path_to_root . "/admin/db/shipping_db.inc");
28
29 $js = "";
30 if ($use_popup_windows) {
31         $js .= get_js_open_window(900, 500);
32 }
33 if (user_use_date_picker()) {
34         $js .= get_js_date_picker();
35 }
36
37 if (isset($_GET['ModifyInvoice'])) {
38         $_SESSION['page_title'] = sprintf(_("Modifying Sales Invoice # %d.") ,$_GET['ModifyInvoice']);
39         $help_context = "Modifying Sales Invoice";
40 } elseif (isset($_GET['DeliveryNumber'])) {
41         $_SESSION['page_title'] = _($help_context = "Issue an Invoice for Delivery Note");
42 } elseif (isset($_GET['BatchInvoice'])) {
43         $_SESSION['page_title'] = _($help_context = "Issue Batch Invoice for Delivery Notes");
44 } elseif (isset($_GET['AllocationNumber']) || isset($_GET['InvoicePrepayments'])) {
45         $_SESSION['page_title'] = _($help_context = "Prepayment or Final Invoice Entry");
46 }
47 page($_SESSION['page_title'], false, false, "", $js);
48
49 //-----------------------------------------------------------------------------
50
51 check_edit_conflicts(get_post('cart_id'));
52
53 if (isset($_GET['AddedID'])) {
54
55         $invoice_no = $_GET['AddedID'];
56         $trans_type = ST_SALESINVOICE;
57
58         display_notification(_("Selected deliveries has been processed"), true);
59
60         display_note(get_customer_trans_view_str($trans_type, $invoice_no, _("&View This Invoice")), 0, 1);
61
62         display_note(print_document_link($invoice_no."-".$trans_type, _("&Print This Invoice"), true, ST_SALESINVOICE));
63         display_note(print_document_link($invoice_no."-".$trans_type, _("&Email This Invoice"), true, ST_SALESINVOICE, false, "printlink", "", 1),1);
64
65         display_note(get_gl_view_str($trans_type, $invoice_no, _("View the GL &Journal Entries for this Invoice")),1);
66
67         hyperlink_params("$path_to_root/sales/inquiry/sales_deliveries_view.php", _("Select Another &Delivery For Invoicing"), "OutstandingOnly=1");
68
69         if (!db_num_rows(get_allocatable_from_cust_transactions(null, $invoice_no, $trans_type)))
70                 hyperlink_params("$path_to_root/sales/customer_payments.php", _("Entry &customer payment for this invoice"),
71                 "SInvoice=".$invoice_no);
72
73         hyperlink_params("$path_to_root/admin/attachments.php", _("Add an Attachment"), "filterType=$trans_type&trans_no=$invoice_no");
74
75         display_footer_exit();
76
77 } elseif (isset($_GET['UpdatedID']))  {
78
79         $invoice_no = $_GET['UpdatedID'];
80         $trans_type = ST_SALESINVOICE;
81
82         display_notification_centered(sprintf(_('Sales Invoice # %d has been updated.'),$invoice_no));
83
84         display_note(get_trans_view_str(ST_SALESINVOICE, $invoice_no, _("&View This Invoice")));
85         echo '<br>';
86         display_note(print_document_link($invoice_no."-".$trans_type, _("&Print This Invoice"), true, ST_SALESINVOICE));
87         display_note(print_document_link($invoice_no."-".$trans_type, _("&Email This Invoice"), true, ST_SALESINVOICE, false, "printlink", "", 1),1);
88
89         hyperlink_no_params($path_to_root . "/sales/inquiry/customer_inquiry.php", _("Select Another &Invoice to Modify"));
90
91         display_footer_exit();
92
93 } elseif (isset($_GET['RemoveDN'])) {
94
95         for($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
96                 $line = &$_SESSION['Items']->line_items[$line_no];
97                 if ($line->src_no == $_GET['RemoveDN']) {
98                         $line->quantity = $line->qty_done;
99                         $line->qty_dispatched=0;
100                 }
101         }
102         unset($line);
103
104     // Remove also src_doc delivery note
105     $sources = &$_SESSION['Items']->src_docs;
106     unset($sources[$_GET['RemoveDN']]);
107 }
108
109 //-----------------------------------------------------------------------------
110
111 if ( (isset($_GET['DeliveryNumber']) && ($_GET['DeliveryNumber'] > 0) )
112 || isset($_GET['BatchInvoice'])) {
113
114         processing_start();
115
116         if (isset($_GET['BatchInvoice'])) {
117                 $src = $_SESSION['DeliveryBatch'];
118                 unset($_SESSION['DeliveryBatch']);
119         } else {
120                 $src = array($_GET['DeliveryNumber']);
121         }
122
123         /*read in all the selected deliveries into the Items cart  */
124         $dn = new Cart(ST_CUSTDELIVERY, $src, true);
125
126         if ($dn->count_items() == 0) {
127                 hyperlink_params($path_to_root . "/sales/inquiry/sales_deliveries_view.php",
128                         _("Select a different delivery to invoice"), "OutstandingOnly=1");
129                 die ("<br><b>" . _("There are no delivered items with a quantity left to invoice. There is nothing left to invoice.") . "</b>");
130         }
131
132         $_SESSION['Items'] = $dn;
133         copy_from_cart();
134
135 } elseif (isset($_GET['ModifyInvoice']) && $_GET['ModifyInvoice'] > 0) {
136
137         check_is_editable(ST_SALESINVOICE, $_GET['ModifyInvoice']);
138 /*
139         if ( get_sales_parent_numbers(ST_SALESINVOICE, $_GET['ModifyInvoice']) == 0) { // 1.xx compatibility hack
140                 echo"<center><br><b>" . _("There are no delivery notes for this invoice.<br>
141                 Most likely this invoice was created in Front Accounting version prior to 2.0
142                 and therefore can not be modified.") . "</b></center>";
143                 display_footer_exit();
144         }
145 */
146         processing_start();
147         $_SESSION['Items'] = new Cart(ST_SALESINVOICE, $_GET['ModifyInvoice']);
148
149         if ($_SESSION['Items']->count_items() == 0) {
150                 echo"<center><br><b>" . _("All quantities on this invoice has been credited. There is nothing to modify on this invoice") . "</b></center>";
151                 display_footer_exit();
152         }
153         copy_from_cart();
154 } elseif (isset($_GET['AllocationNumber']) || isset($_GET['InvoicePrepayments'])) {
155
156                 check_deferred_income_act(_("You have to set Deferred Income Account in GL Setup to entry prepayment invoices."));
157
158                 if (isset($_GET['AllocationNumber']))
159                 {
160                         $payments = array(get_cust_allocation($_GET['AllocationNumber']));
161
162                         if (!$payments || ($payments[0]['trans_type_to'] != ST_SALESORDER))
163                         {
164                                 display_error(_("Please select correct Sales Order Prepayment to be invoiced and try again."));
165                                 display_footer_exit();
166                         }
167                         $order_no = $payments[0]['trans_no_to'];
168                 }
169                 else {
170                         $order_no = $_GET['InvoicePrepayments'];
171                         $payments =  get_payments_for($_GET['InvoicePrepayments'], ST_SALESORDER);
172                 }
173                 processing_start();
174
175                 $_SESSION['Items'] = new Cart(ST_SALESORDER, $order_no, ST_SALESINVOICE);
176                 $_SESSION['Items']->order_no = $order_no;
177                 $_SESSION['Items']->src_docs = array($order_no);
178                 $_SESSION['Items']->trans_no = 0;
179                 $_SESSION['Items']->trans_type = ST_SALESINVOICE;
180                 $_SESSION['Items']->prepayments = $payments;
181                 // prepayment invoice has all line quantities as stated on order.
182 //              foreach($_SESSION['Items']->line_items as &$line)
183 //              {
184 //                      $line->src_id = $line_id;
185 //                      $line->qty_dispatched = $line->quantity;
186 //              }
187 //              unset($line);
188                 $_SESSION['Items']->update_payments();
189
190 //              $_SESSION['Items']->alloc = $this_amount;
191                 copy_from_cart();
192 }
193  elseif (!processing_active()) {
194         /* This page can only be called with a delivery for invoicing or invoice no for edit */
195         display_error(_("This page can only be opened after delivery selection. Please select delivery to invoicing first."));
196
197         hyperlink_no_params("$path_to_root/sales/inquiry/sales_deliveries_view.php", _("Select Delivery to Invoice"));
198
199         end_page();
200         exit;
201 } elseif (!isset($_POST['process_invoice']) && (!$_SESSION['Items']->is_prepaid() && !check_quantities())) {
202         display_error(_("Selected quantity cannot be less than quantity credited nor more than quantity not invoiced yet."));
203 }
204
205 if (isset($_POST['Update'])) {
206         $Ajax->activate('Items');
207 }
208 if (isset($_POST['_InvoiceDate_changed'])) {
209         $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->payment, $_POST['InvoiceDate']);
210         $Ajax->activate('due_date');
211 }
212
213 //-----------------------------------------------------------------------------
214 function check_quantities()
215 {
216         $ok =1;
217         foreach ($_SESSION['Items']->line_items as $line_no=>$itm) {
218                 if (isset($_POST['Line'.$line_no])) {
219                         if($_SESSION['Items']->trans_no) {
220                                 $min = $itm->qty_done;
221                                 $max = $itm->quantity;
222                         } else {
223                                 $min = 0;
224                                 $max = $itm->quantity - $itm->qty_done;
225                         }
226                         if (check_num('Line'.$line_no, $min, $max)) {
227                                 $_SESSION['Items']->line_items[$line_no]->qty_dispatched =
228                                     input_num('Line'.$line_no);
229                         }
230                         else {
231                                 $ok = 0;
232                         }
233                                 
234                 }
235
236                 if (isset($_POST['Line'.$line_no.'Desc'])) {
237                         $line_desc = $_POST['Line'.$line_no.'Desc'];
238                         if (strlen($line_desc) > 0) {
239                                 $_SESSION['Items']->line_items[$line_no]->item_description = $line_desc;
240                         }
241                 }
242         }
243  return $ok;
244 }
245
246 function set_delivery_shipping_sum($delivery_notes) 
247 {
248     
249     $shipping = 0;
250     
251     foreach($delivery_notes as $delivery_num) 
252     {
253         $myrow = get_customer_trans($delivery_num, 13);
254         //$branch = get_branch($myrow["branch_code"]);
255         //$sales_order = get_sales_order_header($myrow["order_"]);
256         
257         //$shipping += $sales_order['freight_cost'];
258         $shipping += $myrow['ov_freight'];
259     }
260     $_POST['ChargeFreightCost'] = price_format($shipping);
261 }
262
263
264 function copy_to_cart()
265 {
266         $cart = &$_SESSION['Items'];
267         $cart->due_date = $cart->document_date =  $_POST['InvoiceDate'];
268         $cart->Comments = $_POST['Comments'];
269         $cart->due_date =  $_POST['due_date'];
270         if (($cart->pos['cash_sale'] || $cart->pos['credit_sale']) && isset($_POST['payment'])) {
271                 $cart->payment = $_POST['payment'];
272                 $cart->payment_terms = get_payment_terms($_POST['payment']);
273         }
274         if ($_SESSION['Items']->trans_no == 0)
275                 $cart->reference = $_POST['ref'];
276         if (!$cart->is_prepaid())
277         {
278                 $cart->ship_via = $_POST['ship_via'];
279                 $cart->freight_cost = input_num('ChargeFreightCost');
280         }
281
282         $cart->update_payments();
283
284         $cart->dimension_id =  $_POST['dimension_id'];
285         $cart->dimension2_id =  $_POST['dimension2_id'];
286 }
287 //-----------------------------------------------------------------------------
288
289 function copy_from_cart()
290 {
291         $cart = &$_SESSION['Items'];
292         $_POST['Comments']= $cart->Comments;
293         $_POST['InvoiceDate']= $cart->document_date;
294         $_POST['ref'] = $cart->reference;
295         $_POST['cart_id'] = $cart->cart_id;
296         $_POST['due_date'] = $cart->due_date;
297         $_POST['payment'] = $cart->payment;
298         if (!$_SESSION['Items']->is_prepaid())
299         {
300                 $_POST['ship_via'] = $cart->ship_via;
301                 $_POST['ChargeFreightCost'] = price_format($cart->freight_cost);
302         }
303         $_POST['dimension_id'] = $cart->dimension_id;
304         $_POST['dimension2_id'] = $cart->dimension2_id;
305 }
306
307 //-----------------------------------------------------------------------------
308
309 function check_data()
310 {
311         global $Refs;
312
313         $prepaid = $_SESSION['Items']->is_prepaid();
314
315         if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
316                 display_error(_("The entered invoice date is invalid."));
317                 set_focus('InvoiceDate');
318                 return false;
319         }
320
321         if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
322                 display_error(_("The entered date is out of fiscal year or is closed for further data entry."));
323                 set_focus('InvoiceDate');
324                 return false;
325         }
326
327
328         if (!$prepaid &&(!isset($_POST['due_date']) || !is_date($_POST['due_date'])))   {
329                 display_error(_("The entered invoice due date is invalid."));
330                 set_focus('due_date');
331                 return false;
332         }
333
334         if ($_SESSION['Items']->trans_no == 0) {
335                 if (!$Refs->is_valid($_POST['ref'])) {
336                         display_error(_("You must enter a reference."));
337                         set_focus('ref');
338                         return false;
339                 }
340         }
341
342         if(!$prepaid) 
343         {
344                 if ($_POST['ChargeFreightCost'] == "") {
345                         $_POST['ChargeFreightCost'] = price_format(0);
346                 }
347
348                 if (!check_num('ChargeFreightCost', 0)) {
349                         display_error(_("The entered shipping value is not numeric."));
350                         set_focus('ChargeFreightCost');
351                         return false;
352                 }
353
354                 if ($_SESSION['Items']->has_items_dispatch() == 0 && input_num('ChargeFreightCost') == 0) {
355                         display_error(_("There are no item quantities on this invoice."));
356                         return false;
357                 }
358
359                 if (!check_quantities()) {
360                         display_error(_("Selected quantity cannot be less than quantity credited nor more than quantity not invoiced yet."));
361                         return false;
362                 }
363         } else {
364                 if (($_SESSION['Items']->payment_terms['days_before_due'] < 0) && !count($_SESSION['Items']->prepayments)) {
365                         display_error(_("There is no non-invoiced payments for this order. If you want to issue final invoice, select delayed or cash payment terms."));
366                         return false;
367                 }
368         }
369
370         return true;
371 }
372
373 //-----------------------------------------------------------------------------
374 if (isset($_POST['process_invoice']) && check_data()) {
375         $newinvoice=  $_SESSION['Items']->trans_no == 0;
376         copy_to_cart();
377         if ($newinvoice) 
378                 new_doc_date($_SESSION['Items']->document_date);
379
380         $invoice_no = $_SESSION['Items']->write();
381         if ($invoice_no == -1)
382         {
383                 display_error(_("The entered reference is already in use."));
384                 set_focus('ref');
385         }
386         else
387         {
388                 processing_end();
389
390                 if ($newinvoice) {
391                         meta_forward($_SERVER['PHP_SELF'], "AddedID=$invoice_no");
392                 } else {
393                         meta_forward($_SERVER['PHP_SELF'], "UpdatedID=$invoice_no");
394                 }
395         }       
396 }
397
398 if(list_updated('payment')) {
399         $order = &$_SESSION['Items']; 
400         copy_to_cart();
401         $order->payment = get_post('payment');
402         $order->payment_terms = get_payment_terms($order->payment);
403         $_POST['due_date'] = $order->due_date = get_invoice_duedate($order->payment, $order->document_date);
404         $_POST['Comments'] = '';
405         $Ajax->activate('due_date');
406         $Ajax->activate('options');
407         if ($order->payment_terms['cash_sale']) {
408                 $_POST['Location'] = $order->Location = $order->pos['pos_location'];
409                 $order->location_name = $order->pos['location_name'];
410         }
411 }
412
413 // find delivery spans for batch invoice display
414 $dspans = array();
415 $lastdn = ''; $spanlen=1;
416
417 for ($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
418         $line = $_SESSION['Items']->line_items[$line_no];
419         if ($line->quantity == $line->qty_done) {
420                 continue;
421         }
422         if ($line->src_no == $lastdn) {
423                 $spanlen++;
424         } else {
425                 if ($lastdn != '') {
426                         $dspans[] = $spanlen;
427                         $spanlen = 1;
428                 }
429         }
430         $lastdn = $line->src_no;
431 }
432 $dspans[] = $spanlen;
433
434 //-----------------------------------------------------------------------------
435
436 $is_batch_invoice = count($_SESSION['Items']->src_docs) > 1;
437 $prepaid = $_SESSION['Items']->is_prepaid();
438
439 $is_edition = $_SESSION['Items']->trans_type == ST_SALESINVOICE && $_SESSION['Items']->trans_no != 0;
440 start_form();
441 hidden('cart_id');
442
443 start_table(TABLESTYLE2, "width=80%", 5);
444
445 start_row();
446 $colspan = 1;
447 $dim = get_company_pref('use_dimension');
448 if ($dim > 0) 
449         $colspan = 3;
450 label_cells(_("Customer"), $_SESSION['Items']->customer_name, "class='tableheader2'");
451 label_cells(_("Branch"), get_branch_name($_SESSION['Items']->Branch), "class='tableheader2'");
452 if (($_SESSION['Items']->pos['credit_sale'] || $_SESSION['Items']->pos['cash_sale'])) {
453         $paymcat = !$_SESSION['Items']->pos['cash_sale'] ? PM_CREDIT :
454                 (!$_SESSION['Items']->pos['credit_sale'] ? PM_CASH : PM_ANY);
455         label_cells(_("Payment terms:"), sale_payment_list('payment', $paymcat),
456                 "class='tableheader2'", "colspan=$colspan");
457 } else
458         label_cells(_('Payment:'), $_SESSION['Items']->payment_terms['terms'], "class='tableheader2'", "colspan=$colspan");
459
460 end_row();
461 start_row();
462
463 if ($_SESSION['Items']->trans_no == 0) {
464         ref_cells(_("Reference"), 'ref', '', null, "class='tableheader2'");
465 } else {
466         label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'");
467 }
468
469 //label_cells(_("Delivery Notes:"),
470 //get_customer_trans_view_str(ST_CUSTDELIVERY, array_keys($_SESSION['Items']->src_docs)), "class='tableheader2'");
471
472 label_cells(_("Sales Type"), $_SESSION['Items']->sales_type_name, "class='tableheader2'");
473
474 label_cells(_("Currency"), $_SESSION['Items']->customer_currency, "class='tableheader2'");
475 // 2010-09-03 Joe Hunt
476 //if ($dim > 0) 
477 //      label_cells(_("Dimension"), get_dimension_string($_SESSION['Items']->dimension_id), "class='tableheader2'");
478 if ($dim > 0) {
479         label_cell(_("Dimension").":", "class='tableheader2'");
480         $_POST['dimension_id'] = $_SESSION['Items']->dimension_id;
481         dimensions_list_cells(null, 'dimension_id', null, true, ' ', false, 1, false);
482 }               
483 else
484         hidden('dimension_id', 0);
485
486 end_row();
487 start_row();
488
489 if (!isset($_POST['ship_via'])) {
490         $_POST['ship_via'] = $_SESSION['Items']->ship_via;
491 }
492 label_cell(_("Shipping Company"), "class='tableheader2'");
493 if ($prepaid)
494 {
495         $shipper = get_shipper($_SESSION['Items']->ship_via);
496         label_cells(null, $shipper['shipper_name']);
497 } else
498         shippers_list_cells(null, 'ship_via', $_POST['ship_via']);
499
500 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
501         $_POST['InvoiceDate'] = new_doc_date();
502         if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
503                 $_POST['InvoiceDate'] = end_fiscalyear();
504         }
505 }
506
507 date_cells(_("Date"), 'InvoiceDate', '', $_SESSION['Items']->trans_no == 0, 
508         0, 0, 0, "class='tableheader2'", true);
509
510 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
511         $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->payment, $_POST['InvoiceDate']);
512 }
513
514 date_cells(_("Due Date"), 'due_date', '', null, 0, 0, 0, "class='tableheader2'");
515 /*
516 if ($dim > 1) 
517         label_cells(_("Dimension"). " 2", get_dimension_string($_SESSION['Items']->dimension2_id), "class='tableheader2'");
518 else if ($dim > 0)
519         label_cell("&nbsp;", "colspan=2");
520 */
521 if ($dim > 1) {
522         label_cell(_("Dimension")." 2:", "class='tableheader2'");
523         $_POST['dimension2_id'] = $_SESSION['Items']->dimension2_id;
524         dimensions_list_cells(null, 'dimension2_id', null, true, ' ', false, 2, false);
525 }               
526 else
527         hidden('dimension2_id', 0);
528 end_row();
529 end_table();
530
531 $row = get_customer_to_order($_SESSION['Items']->customer_id);
532 if ($row['dissallow_invoices'] == 1)
533 {
534         display_error(_("The selected customer account is currently on hold. Please contact the credit control personnel to discuss."));
535         end_form();
536         end_page();
537         exit();
538 }       
539
540 display_heading($prepaid ? _("Sales Order Items") : _("Invoice Items"));
541
542 div_start('Items');
543 start_table(TABLESTYLE, "width=80%");
544 if ($prepaid)
545         $th = array(_("Item Code"), _("Item Description"), _("Units"), _("Quantity"),
546                 _("Price"), _("Tax Type"), _("Discount"), _("Total"));
547 else
548         $th = array(_("Item Code"), _("Item Description"), _("Delivered"), _("Units"), _("Invoiced"),
549                 _("This Invoice"), _("Price"), _("Tax Type"), _("Discount"), _("Total"));
550 if ($is_batch_invoice) {
551     $th[] = _("DN");
552     $th[] = "";
553 }
554
555 if ($is_edition) {
556     $th[4] = _("Credited");
557 }
558
559 table_header($th);
560 $k = 0;
561 $has_marked = false;
562 $show_qoh = true;
563
564 $dn_line_cnt = 0;
565
566 foreach ($_SESSION['Items']->line_items as $line=>$ln_itm) {
567         if (!$prepaid && ($ln_itm->quantity == $ln_itm->qty_done)) {
568                 continue; // this line was fully invoiced
569         }
570         alt_table_row_color($k);
571         view_stock_status_cell($ln_itm->stock_id);
572
573         if ($prepaid)
574                 label_cell($ln_itm->item_description);
575         else
576                 text_cells(null, 'Line'.$line.'Desc', $ln_itm->item_description, 30, 50);
577         $dec = get_qty_dec($ln_itm->stock_id);
578         if (!$prepaid)
579                 qty_cell($ln_itm->quantity, false, $dec);
580         label_cell($ln_itm->units);
581         if (!$prepaid)
582                 qty_cell($ln_itm->qty_done, false, $dec);
583
584         if ($is_batch_invoice || $prepaid) {
585                 // for batch invoices we can only remove whole deliveries
586                 echo '<td nowrap align=right>';
587                 hidden('Line' . $line, $ln_itm->qty_dispatched );
588                 echo number_format2($ln_itm->qty_dispatched, $dec).'</td>';
589         } else {
590                 small_qty_cells(null, 'Line'.$line, qty_format($ln_itm->qty_dispatched, $ln_itm->stock_id, $dec), null, null, $dec);
591         }
592         $display_discount_percent = percent_format($ln_itm->discount_percent*100) . " %";
593
594         $line_total = ($ln_itm->qty_dispatched * $ln_itm->price * (1 - $ln_itm->discount_percent));
595
596         amount_cell($ln_itm->price);
597         label_cell($ln_itm->tax_type_name);
598         label_cell($display_discount_percent, "nowrap align=right");
599         amount_cell($line_total);
600
601         if ($is_batch_invoice) {
602                 if ($dn_line_cnt == 0) {
603                         $dn_line_cnt = $dspans[0];
604                         $dspans = array_slice($dspans, 1);
605                         label_cell($ln_itm->src_no, "rowspan=$dn_line_cnt class=oddrow");
606                         label_cell("<a href='" . $_SERVER['PHP_SELF'] . "?RemoveDN=".
607                                 $ln_itm->src_no."'>" . _("Remove") . "</a>", "rowspan=$dn_line_cnt class=oddrow");
608                 }
609                 $dn_line_cnt--;
610         }
611         end_row();
612 }
613
614 /*Don't re-calculate freight if some of the order has already been delivered -
615 depending on the business logic required this condition may not be required.
616 It seems unfair to charge the customer twice for freight if the order
617 was not fully delivered the first time ?? */
618
619 if (!isset($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] == "") {
620         if ($_SESSION['Items']->any_already_delivered() == 1) {
621                 $_POST['ChargeFreightCost'] = price_format(0);
622         } else {
623                 $_POST['ChargeFreightCost'] = price_format($_SESSION['Items']->freight_cost);
624         }
625
626         if (!check_num('ChargeFreightCost')) {
627                 $_POST['ChargeFreightCost'] = price_format(0);
628         }
629 }
630
631 $accumulate_shipping = get_company_pref('accumulate_shipping');
632 if ($is_batch_invoice && $accumulate_shipping)
633         set_delivery_shipping_sum(array_keys($_SESSION['Items']->src_docs));
634
635 $colspan = $prepaid ? 7:9;
636 start_row();
637 label_cell(_("Shipping Cost"), "colspan=$colspan align=right");
638 if ($prepaid)
639         label_cell($_POST['ChargeFreightCost'], 'align=right');
640 else
641         small_amount_cells(null, 'ChargeFreightCost', null);
642 if ($is_batch_invoice) {
643 label_cell('', 'colspan=2');
644 }
645
646 end_row();
647 $inv_items_total = $_SESSION['Items']->get_items_total_dispatch();
648
649 $display_sub_total = price_format($inv_items_total + input_num('ChargeFreightCost'));
650
651 label_row(_("Sub-total"), $display_sub_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
652
653 $taxes = $_SESSION['Items']->get_taxes(input_num('ChargeFreightCost'));
654 $tax_total = display_edit_tax_items($taxes, $colspan, $_SESSION['Items']->tax_included, $is_batch_invoice ? 2 : 0);
655
656 $display_total = price_format(($inv_items_total + input_num('ChargeFreightCost') + $tax_total));
657
658 label_row(_("Invoice Total"), $display_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
659
660 end_table(1);
661 div_end();
662 div_start('options');
663 start_table(TABLESTYLE2);
664 if ($prepaid)
665 {
666
667         label_row(_("Sales order:"), get_trans_view_str(ST_SALESORDER, $_SESSION['Items']->order_no, get_reference(ST_SALESORDER, $_SESSION['Items']->order_no)));
668
669         $list = array(); $allocs = 0;
670         if (count($_SESSION['Items']->prepayments))
671         {
672                 foreach($_SESSION['Items']->prepayments as $pmt)
673                 {
674                         $list[] = get_trans_view_str($pmt['trans_type_from'], $pmt['trans_no_from'], get_reference($pmt['trans_type_from'], $pmt['trans_no_from']));
675                         $allocs += $pmt['amt'];
676                 }
677         }
678
679         label_row(_("Payments received:"), implode(',', $list));
680         label_row(_("Invoiced here:"), price_format($_SESSION['Items']->prep_amount), 'class=label');
681         label_row(_("Left to be invoiced:"), price_format($_SESSION['Items']->get_trans_total()-max($_SESSION['Items']->prep_amount, $allocs)), 'class=label');
682 }
683
684 textarea_row(_("Memo:"), 'Comments', null, 50, 4);
685
686 end_table(1);
687 div_end();
688 submit_center_first('Update', _("Update"),
689   _('Refresh document page'), true);
690 submit_center_last('process_invoice', _("Process Invoice"),
691   _('Check entered data and save document'), 'default');
692
693 end_form();
694
695 end_page();
696