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