Incorrect Journal Balance (sales invoice) when many decimals in tax and price.
[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         }
164         processing_start();
165
166         $_SESSION['Items'] = new cart(ST_SALESORDER, $order_no, ST_SALESINVOICE);
167         $_SESSION['Items']->order_no = $order_no;
168         $_SESSION['Items']->src_docs = array($order_no);
169         $_SESSION['Items']->trans_no = 0;
170         $_SESSION['Items']->trans_type = ST_SALESINVOICE;
171
172         $_SESSION['Items']->update_payments();
173
174         copy_from_cart();
175 }
176 elseif (!processing_active()) {
177         /* This page can only be called with a delivery for invoicing or invoice no for edit */
178         display_error(_("This page can only be opened after delivery selection. Please select delivery to invoicing first."));
179
180         hyperlink_no_params("$path_to_root/sales/inquiry/sales_deliveries_view.php", _("Select Delivery to Invoice"));
181
182         end_page();
183         exit;
184 } elseif (!isset($_POST['process_invoice']) && (!$_SESSION['Items']->is_prepaid() && !check_quantities())) {
185         display_error(_("Selected quantity cannot be less than quantity credited nor more than quantity not invoiced yet."));
186 }
187
188 if (isset($_POST['Update'])) {
189         $Ajax->activate('Items');
190 }
191 if (isset($_POST['_InvoiceDate_changed'])) {
192         $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->payment, $_POST['InvoiceDate']);
193         $Ajax->activate('due_date');
194 }
195
196 //-----------------------------------------------------------------------------
197 function check_quantities()
198 {
199         $ok =1;
200         foreach ($_SESSION['Items']->line_items as $line_no=>$itm) {
201                 if (isset($_POST['Line'.$line_no])) {
202                         if($_SESSION['Items']->trans_no) {
203                                 $min = $itm->qty_done;
204                                 $max = $itm->quantity;
205                         } else {
206                                 $min = 0;
207                                 // Fixing floating point problem in PHP.
208                                 $max = round2($itm->quantity - $itm->qty_done, get_unit_dec($itm->stock_id));
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'] == -1) && !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
359         if ($newinvoice) 
360                 new_doc_date($_SESSION['Items']->document_date);
361
362         $invoice_no = $_SESSION['Items']->write();
363         if ($invoice_no == -1)
364         {
365                 display_error(_("The entered reference is already in use."));
366                 set_focus('ref');
367         }
368         else
369         {
370                 processing_end();
371
372                 if ($newinvoice) {
373                         meta_forward($_SERVER['PHP_SELF'], "AddedID=$invoice_no");
374                 } else {
375                         meta_forward($_SERVER['PHP_SELF'], "UpdatedID=$invoice_no");
376                 }
377         }       
378 }
379
380 if(list_updated('payment')) {
381         $order = &$_SESSION['Items']; 
382         copy_to_cart();
383         $order->payment = get_post('payment');
384         $order->payment_terms = get_payment_terms($order->payment);
385         $_POST['due_date'] = $order->due_date = get_invoice_duedate($order->payment, $order->document_date);
386         $_POST['Comments'] = '';
387         $Ajax->activate('due_date');
388         $Ajax->activate('options');
389         if ($order->payment_terms['cash_sale']) {
390                 $_POST['Location'] = $order->Location = $order->pos['pos_location'];
391                 $order->location_name = $order->pos['location_name'];
392         }
393 }
394
395 // find delivery spans for batch invoice display
396 $dspans = array();
397 $lastdn = ''; $spanlen=1;
398
399 for ($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
400         $line = $_SESSION['Items']->line_items[$line_no];
401         if ($line->quantity == $line->qty_done) {
402                 continue;
403         }
404         if ($line->src_no == $lastdn) {
405                 $spanlen++;
406         } else {
407                 if ($lastdn != '') {
408                         $dspans[] = $spanlen;
409                         $spanlen = 1;
410                 }
411         }
412         $lastdn = $line->src_no;
413 }
414 $dspans[] = $spanlen;
415
416 //-----------------------------------------------------------------------------
417
418 $is_batch_invoice = count($_SESSION['Items']->src_docs) > 1;
419 $prepaid = $_SESSION['Items']->is_prepaid();
420
421 $is_edition = $_SESSION['Items']->trans_type == ST_SALESINVOICE && $_SESSION['Items']->trans_no != 0;
422 start_form();
423 hidden('cart_id');
424
425 start_table(TABLESTYLE2, "width='80%'", 5);
426
427 start_row();
428 $colspan = 1;
429 $dim = get_company_pref('use_dimension');
430 if ($dim > 0) 
431         $colspan = 3;
432 label_cells(_("Customer"), $_SESSION['Items']->customer_name, "class='tableheader2'");
433 label_cells(_("Branch"), get_branch_name($_SESSION['Items']->Branch), "class='tableheader2'");
434 if (($_SESSION['Items']->pos['credit_sale'] || $_SESSION['Items']->pos['cash_sale'])) {
435         $paymcat = !$_SESSION['Items']->pos['cash_sale'] ? PM_CREDIT :
436                 (!$_SESSION['Items']->pos['credit_sale'] ? PM_CASH : PM_ANY);
437         label_cells(_("Payment terms:"), sale_payment_list('payment', $paymcat),
438                 "class='tableheader2'", "colspan=$colspan");
439 } else
440         label_cells(_('Payment:'), $_SESSION['Items']->payment_terms['terms'], "class='tableheader2'", "colspan=$colspan");
441
442 end_row();
443 start_row();
444
445 if ($_SESSION['Items']->trans_no == 0) {
446         ref_cells(_("Reference"), 'ref', '', null, "class='tableheader2'", false, ST_SALESINVOICE,
447                 array('customer' => $_SESSION['Items']->customer_id,
448                         'branch' => $_SESSION['Items']->Branch,
449                         'date' => get_post('InvoiceDate')));
450 } else {
451         label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'");
452 }
453
454 label_cells(_("Sales Type"), $_SESSION['Items']->sales_type_name, "class='tableheader2'");
455
456 label_cells(_("Currency"), $_SESSION['Items']->customer_currency, "class='tableheader2'");
457 if ($dim > 0) {
458         label_cell(_("Dimension").":", "class='tableheader2'");
459         $_POST['dimension_id'] = $_SESSION['Items']->dimension_id;
460         dimensions_list_cells(null, 'dimension_id', null, true, ' ', false, 1, false);
461 }               
462 else
463         hidden('dimension_id', 0);
464
465 end_row();
466 start_row();
467
468 if (!isset($_POST['ship_via'])) {
469         $_POST['ship_via'] = $_SESSION['Items']->ship_via;
470 }
471 label_cell(_("Shipping Company"), "class='tableheader2'");
472 if ($prepaid)
473 {
474         $shipper = get_shipper($_SESSION['Items']->ship_via);
475         label_cells(null, $shipper['shipper_name']);
476 } else
477         shippers_list_cells(null, 'ship_via', $_POST['ship_via']);
478
479 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
480         $_POST['InvoiceDate'] = new_doc_date();
481         if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
482                 $_POST['InvoiceDate'] = end_fiscalyear();
483         }
484 }
485
486 date_cells(_("Date"), 'InvoiceDate', '', $_SESSION['Items']->trans_no == 0, 
487         0, 0, 0, "class='tableheader2'", true);
488
489 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
490         $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->payment, $_POST['InvoiceDate']);
491 }
492
493 date_cells(_("Due Date"), 'due_date', '', null, 0, 0, 0, "class='tableheader2'");
494 if ($dim > 1) {
495         label_cell(_("Dimension")." 2:", "class='tableheader2'");
496         $_POST['dimension2_id'] = $_SESSION['Items']->dimension2_id;
497         dimensions_list_cells(null, 'dimension2_id', null, true, ' ', false, 2, false);
498 }               
499 else
500         hidden('dimension2_id', 0);
501 end_row();
502 end_table();
503
504 $row = get_customer_to_order($_SESSION['Items']->customer_id);
505 if ($row['dissallow_invoices'] == 1)
506 {
507         display_error(_("The selected customer account is currently on hold. Please contact the credit control personnel to discuss."));
508         end_form();
509         end_page();
510         exit();
511 }       
512
513 display_heading($prepaid ? _("Sales Order Items") : _("Invoice Items"));
514
515 div_start('Items');
516
517 start_table(TABLESTYLE, "width='80%'");
518 if ($prepaid)
519         $th = array(_("Item Code"), _("Item Description"), _("Units"), _("Quantity"),
520                 _("Price"), _("Tax Type"), _("Discount"), _("Total"));
521 else
522         $th = array(_("Item Code"), _("Item Description"), _("Delivered"), _("Units"), _("Invoiced"),
523                 _("This Invoice"), _("Price"), _("Tax Type"), _("Discount"), _("Total"));
524
525 if ($is_batch_invoice) {
526     $th[] = _("DN");
527     $th[] = "";
528 }
529
530 if ($is_edition) {
531     $th[4] = _("Credited");
532 }
533
534 table_header($th);
535 $k = 0;
536 $has_marked = false;
537 $show_qoh = true;
538
539 $dn_line_cnt = 0;
540
541 foreach ($_SESSION['Items']->line_items as $line=>$ln_itm) {
542         if (!$prepaid && ($ln_itm->quantity == $ln_itm->qty_done)) {
543                 continue; // this line was fully invoiced
544         }
545         alt_table_row_color($k);
546         view_stock_status_cell($ln_itm->stock_id);
547
548         if ($prepaid)
549                 label_cell($ln_itm->item_description);
550         else
551                 text_cells(null, 'Line'.$line.'Desc', $ln_itm->item_description, 30, 50);
552         $dec = get_qty_dec($ln_itm->stock_id);
553         if (!$prepaid)
554                 qty_cell($ln_itm->quantity, false, $dec);
555         label_cell($ln_itm->units);
556         if (!$prepaid)
557                 qty_cell($ln_itm->qty_done, false, $dec);
558
559         if ($is_batch_invoice || $prepaid) {
560                 // for batch invoices we can only remove whole deliveries
561                 echo '<td nowrap align=right>';
562                 hidden('Line' . $line, $ln_itm->qty_dispatched );
563                 echo number_format2($ln_itm->qty_dispatched, $dec).'</td>';
564         } else {
565                 small_qty_cells(null, 'Line'.$line, qty_format($ln_itm->qty_dispatched, $ln_itm->stock_id, $dec), null, null, $dec);
566         }
567         $display_discount_percent = percent_format($ln_itm->discount_percent*100) . " %";
568
569         $line_total = ($ln_itm->qty_dispatched * $ln_itm->price * (1 - $ln_itm->discount_percent));
570
571         amount_cell($ln_itm->price);
572         label_cell($ln_itm->tax_type_name);
573         label_cell($display_discount_percent, "nowrap align=right");
574         amount_cell($line_total);
575
576         if ($is_batch_invoice) {
577                 if ($dn_line_cnt == 0) {
578                         $dn_line_cnt = $dspans[0];
579                         $dspans = array_slice($dspans, 1);
580                         label_cell($ln_itm->src_no, "rowspan=$dn_line_cnt class='oddrow'");
581                         label_cell("<a href='" . $_SERVER['PHP_SELF'] . "?RemoveDN=".
582                                 $ln_itm->src_no."'>" . _("Remove") . "</a>", "rowspan=$dn_line_cnt class='oddrow'");
583                 }
584                 $dn_line_cnt--;
585         }
586         end_row();
587 }
588
589 /*Don't re-calculate freight if some of the order has already been delivered -
590 depending on the business logic required this condition may not be required.
591 It seems unfair to charge the customer twice for freight if the order
592 was not fully delivered the first time ?? */
593
594 if (!isset($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] == "") {
595         if ($_SESSION['Items']->any_already_delivered() == 1) {
596                 $_POST['ChargeFreightCost'] = price_format(0);
597         } else {
598                 $_POST['ChargeFreightCost'] = price_format($_SESSION['Items']->freight_cost);
599         }
600
601         if (!check_num('ChargeFreightCost')) {
602                 $_POST['ChargeFreightCost'] = price_format(0);
603         }
604 }
605
606 $accumulate_shipping = get_company_pref('accumulate_shipping');
607 if ($is_batch_invoice && $accumulate_shipping)
608         set_delivery_shipping_sum(array_keys($_SESSION['Items']->src_docs));
609
610 $colspan = $prepaid ? 7:9;
611 start_row();
612 label_cell(_("Shipping Cost"), "colspan=$colspan align=right");
613 if ($prepaid)
614         label_cell($_POST['ChargeFreightCost'], 'align=right');
615 else
616         small_amount_cells(null, 'ChargeFreightCost', null);
617 if ($is_batch_invoice) {
618 label_cell('', 'colspan=2');
619 }
620
621 end_row();
622 $inv_items_total = $_SESSION['Items']->get_items_total_dispatch();
623
624 $display_sub_total = price_format($inv_items_total + input_num('ChargeFreightCost'));
625
626 label_row(_("Sub-total"), $display_sub_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
627
628 $taxes = $_SESSION['Items']->get_taxes(input_num('ChargeFreightCost'));
629 $tax_total = display_edit_tax_items($taxes, $colspan, $_SESSION['Items']->tax_included, $is_batch_invoice ? 2 : 0);
630
631 $display_total = price_format(($inv_items_total + input_num('ChargeFreightCost') + $tax_total));
632
633 label_row(_("Invoice Total"), $display_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
634
635 end_table(1);
636 div_end();
637 div_start('options');
638 start_table(TABLESTYLE2);
639 if ($prepaid)
640 {
641
642         label_row(_("Sales order:"), get_trans_view_str(ST_SALESORDER, $_SESSION['Items']->order_no, get_reference(ST_SALESORDER, $_SESSION['Items']->order_no)));
643
644         $list = array(); $allocs = 0;
645         if (count($_SESSION['Items']->prepayments))
646         {
647                 foreach($_SESSION['Items']->prepayments as $pmt)
648                 {
649                         $list[] = get_trans_view_str($pmt['trans_type_from'], $pmt['trans_no_from'], get_reference($pmt['trans_type_from'], $pmt['trans_no_from']));
650                         $allocs += $pmt['amt'];
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($_SESSION['Items']->payment_terms['days_before_due'] == -1 ? _("Left to be invoiced:") : _("Invoiced so far:"),
656                 price_format($_SESSION['Items']->get_trans_total()-max($_SESSION['Items']->prep_amount, $allocs)), 'class=label');
657 }
658
659 textarea_row(_("Memo:"), 'Comments', null, 50, 4);
660
661 end_table(1);
662 div_end();
663 submit_center_first('Update', _("Update"),
664   _('Refresh document page'), true);
665 submit_center_last('process_invoice', _("Process Invoice"),
666   _('Check entered data and save document'), 'default');
667
668 end_form();
669
670 end_page();
671