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