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