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