10993cc040cd73cf76e91f54e3f59c8abf97f2d9
[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'], ST_SALESINVOICE)) {
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'", false, ST_SALESINVOICE,
464                 array('customer' => $_SESSION['Items']->customer_id,
465                         'branch' => $_SESSION['Items']->Branch,
466                         'date' => get_post('InvoiceDate')));
467 } else {
468         label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'");
469 }
470
471 //label_cells(_("Delivery Notes:"),
472 //get_customer_trans_view_str(ST_CUSTDELIVERY, array_keys($_SESSION['Items']->src_docs)), "class='tableheader2'");
473
474 label_cells(_("Sales Type"), $_SESSION['Items']->sales_type_name, "class='tableheader2'");
475
476 label_cells(_("Currency"), $_SESSION['Items']->customer_currency, "class='tableheader2'");
477 // 2010-09-03 Joe Hunt
478 //if ($dim > 0) 
479 //      label_cells(_("Dimension"), get_dimension_string($_SESSION['Items']->dimension_id), "class='tableheader2'");
480 if ($dim > 0) {
481         label_cell(_("Dimension").":", "class='tableheader2'");
482         $_POST['dimension_id'] = $_SESSION['Items']->dimension_id;
483         dimensions_list_cells(null, 'dimension_id', null, true, ' ', false, 1, false);
484 }               
485 else
486         hidden('dimension_id', 0);
487
488 end_row();
489 start_row();
490
491 if (!isset($_POST['ship_via'])) {
492         $_POST['ship_via'] = $_SESSION['Items']->ship_via;
493 }
494 label_cell(_("Shipping Company"), "class='tableheader2'");
495 if ($prepaid)
496 {
497         $shipper = get_shipper($_SESSION['Items']->ship_via);
498         label_cells(null, $shipper['shipper_name']);
499 } else
500         shippers_list_cells(null, 'ship_via', $_POST['ship_via']);
501
502 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
503         $_POST['InvoiceDate'] = new_doc_date();
504         if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
505                 $_POST['InvoiceDate'] = end_fiscalyear();
506         }
507 }
508
509 date_cells(_("Date"), 'InvoiceDate', '', $_SESSION['Items']->trans_no == 0, 
510         0, 0, 0, "class='tableheader2'", true);
511
512 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
513         $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->payment, $_POST['InvoiceDate']);
514 }
515
516 date_cells(_("Due Date"), 'due_date', '', null, 0, 0, 0, "class='tableheader2'");
517 /*
518 if ($dim > 1) 
519         label_cells(_("Dimension"). " 2", get_dimension_string($_SESSION['Items']->dimension2_id), "class='tableheader2'");
520 else if ($dim > 0)
521         label_cell("&nbsp;", "colspan=2");
522 */
523 if ($dim > 1) {
524         label_cell(_("Dimension")." 2:", "class='tableheader2'");
525         $_POST['dimension2_id'] = $_SESSION['Items']->dimension2_id;
526         dimensions_list_cells(null, 'dimension2_id', null, true, ' ', false, 2, false);
527 }               
528 else
529         hidden('dimension2_id', 0);
530 end_row();
531 end_table();
532
533 $row = get_customer_to_order($_SESSION['Items']->customer_id);
534 if ($row['dissallow_invoices'] == 1)
535 {
536         display_error(_("The selected customer account is currently on hold. Please contact the credit control personnel to discuss."));
537         end_form();
538         end_page();
539         exit();
540 }       
541
542 display_heading($prepaid ? _("Sales Order Items") : _("Invoice Items"));
543
544 div_start('Items');
545
546 start_table(TABLESTYLE, "width='80%'");
547 if ($prepaid)
548         $th = array(_("Item Code"), _("Item Description"), _("Units"), _("Quantity"),
549                 _("Price"), _("Tax Type"), _("Discount"), _("Total"));
550 else
551         $th = array(_("Item Code"), _("Item Description"), _("Delivered"), _("Units"), _("Invoiced"),
552                 _("This Invoice"), _("Price"), _("Tax Type"), _("Discount"), _("Total"));
553
554 if ($is_batch_invoice) {
555     $th[] = _("DN");
556     $th[] = "";
557 }
558
559 if ($is_edition) {
560     $th[4] = _("Credited");
561 }
562
563 table_header($th);
564 $k = 0;
565 $has_marked = false;
566 $show_qoh = true;
567
568 $dn_line_cnt = 0;
569
570 foreach ($_SESSION['Items']->line_items as $line=>$ln_itm) {
571         if (!$prepaid && ($ln_itm->quantity == $ln_itm->qty_done)) {
572                 continue; // this line was fully invoiced
573         }
574         alt_table_row_color($k);
575         view_stock_status_cell($ln_itm->stock_id);
576
577         if ($prepaid)
578                 label_cell($ln_itm->item_description);
579         else
580                 text_cells(null, 'Line'.$line.'Desc', $ln_itm->item_description, 30, 50);
581         $dec = get_qty_dec($ln_itm->stock_id);
582         if (!$prepaid)
583                 qty_cell($ln_itm->quantity, false, $dec);
584         label_cell($ln_itm->units);
585         if (!$prepaid)
586                 qty_cell($ln_itm->qty_done, false, $dec);
587
588         if ($is_batch_invoice || $prepaid) {
589                 // for batch invoices we can only remove whole deliveries
590                 echo '<td nowrap align=right>';
591                 hidden('Line' . $line, $ln_itm->qty_dispatched );
592                 echo number_format2($ln_itm->qty_dispatched, $dec).'</td>';
593         } else {
594                 small_qty_cells(null, 'Line'.$line, qty_format($ln_itm->qty_dispatched, $ln_itm->stock_id, $dec), null, null, $dec);
595         }
596         $display_discount_percent = percent_format($ln_itm->discount_percent*100) . " %";
597
598         $line_total = ($ln_itm->qty_dispatched * $ln_itm->price * (1 - $ln_itm->discount_percent));
599
600         amount_cell($ln_itm->price);
601         label_cell($ln_itm->tax_type_name);
602         label_cell($display_discount_percent, "nowrap align=right");
603         amount_cell($line_total);
604
605         if ($is_batch_invoice) {
606                 if ($dn_line_cnt == 0) {
607                         $dn_line_cnt = $dspans[0];
608                         $dspans = array_slice($dspans, 1);
609                         label_cell($ln_itm->src_no, "rowspan=$dn_line_cnt class='oddrow'");
610                         label_cell("<a href='" . $_SERVER['PHP_SELF'] . "?RemoveDN=".
611                                 $ln_itm->src_no."'>" . _("Remove") . "</a>", "rowspan=$dn_line_cnt class='oddrow'");
612                 }
613                 $dn_line_cnt--;
614         }
615         end_row();
616 }
617
618 /*Don't re-calculate freight if some of the order has already been delivered -
619 depending on the business logic required this condition may not be required.
620 It seems unfair to charge the customer twice for freight if the order
621 was not fully delivered the first time ?? */
622
623 if (!isset($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] == "") {
624         if ($_SESSION['Items']->any_already_delivered() == 1) {
625                 $_POST['ChargeFreightCost'] = price_format(0);
626         } else {
627                 $_POST['ChargeFreightCost'] = price_format($_SESSION['Items']->freight_cost);
628         }
629
630         if (!check_num('ChargeFreightCost')) {
631                 $_POST['ChargeFreightCost'] = price_format(0);
632         }
633 }
634
635 $accumulate_shipping = get_company_pref('accumulate_shipping');
636 if ($is_batch_invoice && $accumulate_shipping)
637         set_delivery_shipping_sum(array_keys($_SESSION['Items']->src_docs));
638
639 $colspan = $prepaid ? 7:9;
640 start_row();
641 label_cell(_("Shipping Cost"), "colspan=$colspan align=right");
642 if ($prepaid)
643         label_cell($_POST['ChargeFreightCost'], 'align=right');
644 else
645         small_amount_cells(null, 'ChargeFreightCost', null);
646 if ($is_batch_invoice) {
647 label_cell('', 'colspan=2');
648 }
649
650 end_row();
651 $inv_items_total = $_SESSION['Items']->get_items_total_dispatch();
652
653 $display_sub_total = price_format($inv_items_total + input_num('ChargeFreightCost'));
654
655 label_row(_("Sub-total"), $display_sub_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
656
657 $taxes = $_SESSION['Items']->get_taxes(input_num('ChargeFreightCost'));
658 $tax_total = display_edit_tax_items($taxes, $colspan, $_SESSION['Items']->tax_included, $is_batch_invoice ? 2 : 0);
659
660 $display_total = price_format(($inv_items_total + input_num('ChargeFreightCost') + $tax_total));
661
662 label_row(_("Invoice Total"), $display_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
663
664 end_table(1);
665 div_end();
666 div_start('options');
667 start_table(TABLESTYLE2);
668 if ($prepaid)
669 {
670
671         label_row(_("Sales order:"), get_trans_view_str(ST_SALESORDER, $_SESSION['Items']->order_no, get_reference(ST_SALESORDER, $_SESSION['Items']->order_no)));
672
673         $list = array(); $allocs = 0;
674         if (count($_SESSION['Items']->prepayments))
675         {
676                 foreach($_SESSION['Items']->prepayments as $pmt)
677                 {
678                         $list[] = get_trans_view_str($pmt['trans_type_from'], $pmt['trans_no_from'], get_reference($pmt['trans_type_from'], $pmt['trans_no_from']));
679                         $allocs += $pmt['amt'];
680                 }
681         }
682
683         label_row(_("Payments received:"), implode(',', $list));
684         label_row(_("Invoiced here:"), price_format($_SESSION['Items']->prep_amount), 'class=label');
685         label_row(_("Left to be invoiced:"), price_format($_SESSION['Items']->get_trans_total()-max($_SESSION['Items']->prep_amount, $allocs)), 'class=label');
686 }
687
688 textarea_row(_("Memo:"), 'Comments', null, 50, 4);
689
690 end_table(1);
691 div_end();
692 submit_center_first('Update', _("Update"),
693   _('Refresh document page'), true);
694 submit_center_last('process_invoice', _("Process Invoice"),
695   _('Check entered data and save document'), 'default');
696
697 end_form();
698
699 end_page();
700