Merged changes from stable branch up to 2.3.23.
[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 ($SysPrefs->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
544 start_table(TABLESTYLE, "width='80%'");
545 if ($prepaid)
546         $th = array(_("Item Code"), _("Item Description"), _("Units"), _("Quantity"),
547                 _("Price"), _("Tax Type"), _("Discount"), _("Total"));
548 else
549         $th = array(_("Item Code"), _("Item Description"), _("Delivered"), _("Units"), _("Invoiced"),
550                 _("This Invoice"), _("Price"), _("Tax Type"), _("Discount"), _("Total"));
551
552 if ($is_batch_invoice) {
553     $th[] = _("DN");
554     $th[] = "";
555 }
556
557 if ($is_edition) {
558     $th[4] = _("Credited");
559 }
560
561 table_header($th);
562 $k = 0;
563 $has_marked = false;
564 $show_qoh = true;
565
566 $dn_line_cnt = 0;
567
568 foreach ($_SESSION['Items']->line_items as $line=>$ln_itm) {
569         if (!$prepaid && ($ln_itm->quantity == $ln_itm->qty_done)) {
570                 continue; // this line was fully invoiced
571         }
572         alt_table_row_color($k);
573         view_stock_status_cell($ln_itm->stock_id);
574
575         if ($prepaid)
576                 label_cell($ln_itm->item_description);
577         else
578                 text_cells(null, 'Line'.$line.'Desc', $ln_itm->item_description, 30, 50);
579         $dec = get_qty_dec($ln_itm->stock_id);
580         if (!$prepaid)
581                 qty_cell($ln_itm->quantity, false, $dec);
582         label_cell($ln_itm->units);
583         if (!$prepaid)
584                 qty_cell($ln_itm->qty_done, false, $dec);
585
586         if ($is_batch_invoice || $prepaid) {
587                 // for batch invoices we can only remove whole deliveries
588                 echo '<td nowrap align=right>';
589                 hidden('Line' . $line, $ln_itm->qty_dispatched );
590                 echo number_format2($ln_itm->qty_dispatched, $dec).'</td>';
591         } else {
592                 small_qty_cells(null, 'Line'.$line, qty_format($ln_itm->qty_dispatched, $ln_itm->stock_id, $dec), null, null, $dec);
593         }
594         $display_discount_percent = percent_format($ln_itm->discount_percent*100) . " %";
595
596         $line_total = ($ln_itm->qty_dispatched * $ln_itm->price * (1 - $ln_itm->discount_percent));
597
598         amount_cell($ln_itm->price);
599         label_cell($ln_itm->tax_type_name);
600         label_cell($display_discount_percent, "nowrap align=right");
601         amount_cell($line_total);
602
603         if ($is_batch_invoice) {
604                 if ($dn_line_cnt == 0) {
605                         $dn_line_cnt = $dspans[0];
606                         $dspans = array_slice($dspans, 1);
607                         label_cell($ln_itm->src_no, "rowspan=$dn_line_cnt class='oddrow'");
608                         label_cell("<a href='" . $_SERVER['PHP_SELF'] . "?RemoveDN=".
609                                 $ln_itm->src_no."'>" . _("Remove") . "</a>", "rowspan=$dn_line_cnt class='oddrow'");
610                 }
611                 $dn_line_cnt--;
612         }
613         end_row();
614 }
615
616 /*Don't re-calculate freight if some of the order has already been delivered -
617 depending on the business logic required this condition may not be required.
618 It seems unfair to charge the customer twice for freight if the order
619 was not fully delivered the first time ?? */
620
621 if (!isset($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] == "") {
622         if ($_SESSION['Items']->any_already_delivered() == 1) {
623                 $_POST['ChargeFreightCost'] = price_format(0);
624         } else {
625                 $_POST['ChargeFreightCost'] = price_format($_SESSION['Items']->freight_cost);
626         }
627
628         if (!check_num('ChargeFreightCost')) {
629                 $_POST['ChargeFreightCost'] = price_format(0);
630         }
631 }
632
633 $accumulate_shipping = get_company_pref('accumulate_shipping');
634 if ($is_batch_invoice && $accumulate_shipping)
635         set_delivery_shipping_sum(array_keys($_SESSION['Items']->src_docs));
636
637 $colspan = $prepaid ? 7:9;
638 start_row();
639 label_cell(_("Shipping Cost"), "colspan=$colspan align=right");
640 if ($prepaid)
641         label_cell($_POST['ChargeFreightCost'], 'align=right');
642 else
643         small_amount_cells(null, 'ChargeFreightCost', null);
644 if ($is_batch_invoice) {
645 label_cell('', 'colspan=2');
646 }
647
648 end_row();
649 $inv_items_total = $_SESSION['Items']->get_items_total_dispatch();
650
651 $display_sub_total = price_format($inv_items_total + input_num('ChargeFreightCost'));
652
653 label_row(_("Sub-total"), $display_sub_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
654
655 $taxes = $_SESSION['Items']->get_taxes(input_num('ChargeFreightCost'));
656 $tax_total = display_edit_tax_items($taxes, $colspan, $_SESSION['Items']->tax_included, $is_batch_invoice ? 2 : 0);
657
658 $display_total = price_format(($inv_items_total + input_num('ChargeFreightCost') + $tax_total));
659
660 label_row(_("Invoice Total"), $display_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
661
662 end_table(1);
663 div_end();
664 div_start('options');
665 start_table(TABLESTYLE2);
666 if ($prepaid)
667 {
668
669         label_row(_("Sales order:"), get_trans_view_str(ST_SALESORDER, $_SESSION['Items']->order_no, get_reference(ST_SALESORDER, $_SESSION['Items']->order_no)));
670
671         $list = array(); $allocs = 0;
672         if (count($_SESSION['Items']->prepayments))
673         {
674                 foreach($_SESSION['Items']->prepayments as $pmt)
675                 {
676                         $list[] = get_trans_view_str($pmt['trans_type_from'], $pmt['trans_no_from'], get_reference($pmt['trans_type_from'], $pmt['trans_no_from']));
677                         $allocs += $pmt['amt'];
678                 }
679         }
680
681         label_row(_("Payments received:"), implode(',', $list));
682         label_row(_("Invoiced here:"), price_format($_SESSION['Items']->prep_amount), 'class=label');
683         label_row(_("Left to be invoiced:"), price_format($_SESSION['Items']->get_trans_total()-max($_SESSION['Items']->prep_amount, $allocs)), 'class=label');
684 }
685
686 textarea_row(_("Memo:"), 'Comments', null, 50, 4);
687
688 end_table(1);
689 div_end();
690 submit_center_first('Update', _("Update"),
691   _('Refresh document page'), true);
692 submit_center_last('process_invoice', _("Process Invoice"),
693   _('Check entered data and save document'), 'default');
694
695 end_form();
696
697 end_page();
698