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 //---------------------------------------------------------------------------
14 // Entry/Modify Sales Invoice against single delivery
15 // Entry/Modify Batch Sales Invoice against batch of deliveries
17 $page_security = 'SA_SALESINVOICE';
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");
30 if ($use_popup_windows) {
31 $js .= get_js_open_window(900, 500);
33 if ($use_date_picker) {
34 $js .= get_js_date_picker();
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");
47 page($_SESSION['page_title'], false, false, "", $js);
49 //-----------------------------------------------------------------------------
51 check_edit_conflicts();
53 if (isset($_GET['AddedID'])) {
55 $invoice_no = $_GET['AddedID'];
56 $trans_type = ST_SALESINVOICE;
58 display_notification(_("Selected deliveries has been processed"), true);
60 display_note(get_customer_trans_view_str($trans_type, $invoice_no, _("&View This Invoice")), 0, 1);
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);
65 display_note(get_gl_view_str($trans_type, $invoice_no, _("View the GL &Journal Entries for this Invoice")),1);
67 hyperlink_params("$path_to_root/sales/inquiry/sales_deliveries_view.php", _("Select Another &Delivery For Invoicing"), "OutstandingOnly=1");
69 hyperlink_params("$path_to_root/admin/attachments.php", _("Add an Attachment"), "filterType=$trans_type&trans_no=$invoice_no");
71 display_footer_exit();
73 } elseif (isset($_GET['UpdatedID'])) {
75 $invoice_no = $_GET['UpdatedID'];
76 $trans_type = ST_SALESINVOICE;
78 display_notification_centered(sprintf(_('Sales Invoice # %d has been updated.'),$invoice_no));
80 display_note(get_trans_view_str(ST_SALESINVOICE, $invoice_no, _("&View This Invoice")));
82 display_note(print_document_link($invoice_no."-".$trans_type, _("&Print This Invoice"), true, ST_SALESINVOICE));
83 display_note(print_document_link($invoice_no."-".$trans_type, _("&Email This Invoice"), true, ST_SALESINVOICE, false, "printlink", "", 1),1);
85 hyperlink_no_params($path_to_root . "/sales/inquiry/customer_inquiry.php", _("Select Another &Invoice to Modify"));
87 display_footer_exit();
89 } elseif (isset($_GET['RemoveDN'])) {
91 for($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
92 $line = &$_SESSION['Items']->line_items[$line_no];
93 if ($line->src_no == $_GET['RemoveDN']) {
94 $line->quantity = $line->qty_done;
95 $line->qty_dispatched=0;
100 // Remove also src_doc delivery note
101 $sources = &$_SESSION['Items']->src_docs;
102 unset($sources[$_GET['RemoveDN']]);
105 //-----------------------------------------------------------------------------
107 if ( (isset($_GET['DeliveryNumber']) && ($_GET['DeliveryNumber'] > 0) )
108 || isset($_GET['BatchInvoice'])) {
112 if (isset($_GET['BatchInvoice'])) {
113 $src = $_SESSION['DeliveryBatch'];
114 unset($_SESSION['DeliveryBatch']);
116 $src = array($_GET['DeliveryNumber']);
119 /*read in all the selected deliveries into the Items cart */
120 $dn = new Cart(ST_CUSTDELIVERY, $src, true);
122 if ($dn->count_items() == 0) {
123 hyperlink_params($path_to_root . "/sales/inquiry/sales_deliveries_view.php",
124 _("Select a different delivery to invoice"), "OutstandingOnly=1");
125 die ("<br><b>" . _("There are no delivered items with a quantity left to invoice. There is nothing left to invoice.") . "</b>");
128 $_SESSION['Items'] = $dn;
131 } elseif (isset($_GET['ModifyInvoice']) && $_GET['ModifyInvoice'] > 0) {
133 check_is_editable(ST_SALESINVOICE, $_GET['ModifyInvoice']);
135 if ( get_sales_parent_numbers(ST_SALESINVOICE, $_GET['ModifyInvoice']) == 0) { // 1.xx compatibility hack
136 echo"<center><br><b>" . _("There are no delivery notes for this invoice.<br>
137 Most likely this invoice was created in Front Accounting version prior to 2.0
138 and therefore can not be modified.") . "</b></center>";
139 display_footer_exit();
143 $_SESSION['Items'] = new Cart(ST_SALESINVOICE, $_GET['ModifyInvoice']);
145 if ($_SESSION['Items']->count_items() == 0) {
146 echo"<center><br><b>" . _("All quantities on this invoice has been credited. There is nothing to modify on this invoice") . "</b></center>";
147 display_footer_exit();
150 } elseif (isset($_GET['AllocationNumber']) || isset($_GET['InvoicePrepayments'])) {
152 check_deferred_income_act(_("You have to set Deferred Income Account in GL Setup to entry prepayment invoices."));
154 if (isset($_GET['AllocationNumber']))
156 $payments = array(get_cust_allocation($_GET['AllocationNumber']));
158 if (!$payments || ($payments[0]['trans_type_to'] != ST_SALESORDER))
160 display_error(_("Please select correct Sales Order Prepayment to be invoiced and try again."));
161 display_footer_exit();
163 $order_no = $payments[0]['trans_no_to'];
166 $order_no = $_GET['InvoicePrepayments'];
167 $payments = get_payments_for($_GET['InvoicePrepayments'], ST_SALESORDER);
171 $_SESSION['Items'] = new Cart(ST_SALESORDER, $order_no, ST_SALESINVOICE);
172 $_SESSION['Items']->order_no = $order_no;
173 $_SESSION['Items']->src_docs = array($order_no);
174 $_SESSION['Items']->trans_no = 0;
175 $_SESSION['Items']->trans_type = ST_SALESINVOICE;
176 $_SESSION['Items']->prepayments = $payments;
177 // prepayment invoice has all line quantities as stated on order.
178 // foreach($_SESSION['Items']->line_items as &$line)
180 // $line->src_id = $line_id;
181 // $line->qty_dispatched = $line->quantity;
184 $_SESSION['Items']->update_payments();
186 // $_SESSION['Items']->alloc = $this_amount;
189 elseif (!processing_active()) {
190 /* This page can only be called with a delivery for invoicing or invoice no for edit */
191 display_error(_("This page can only be opened after delivery selection. Please select delivery to invoicing first."));
193 hyperlink_no_params("$path_to_root/sales/inquiry/sales_deliveries_view.php", _("Select Delivery to Invoice"));
197 } elseif (!isset($_POST['process_invoice']) && (!$_SESSION['Items']->is_prepaid() && !check_quantities())) {
198 display_error(_("Selected quantity cannot be less than quantity credited nor more than quantity not invoiced yet."));
201 if (isset($_POST['Update'])) {
202 $Ajax->activate('Items');
204 if (isset($_POST['_InvoiceDate_changed'])) {
205 $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->payment, $_POST['InvoiceDate']);
206 $Ajax->activate('due_date');
209 //-----------------------------------------------------------------------------
210 function check_quantities()
213 foreach ($_SESSION['Items']->line_items as $line_no=>$itm) {
214 if (isset($_POST['Line'.$line_no])) {
215 if($_SESSION['Items']->trans_no) {
216 $min = $itm->qty_done;
217 $max = $itm->quantity;
220 $max = $itm->quantity - $itm->qty_done;
222 if (check_num('Line'.$line_no, $min, $max)) {
223 $_SESSION['Items']->line_items[$line_no]->qty_dispatched =
224 input_num('Line'.$line_no);
232 if (isset($_POST['Line'.$line_no.'Desc'])) {
233 $line_desc = $_POST['Line'.$line_no.'Desc'];
234 if (strlen($line_desc) > 0) {
235 $_SESSION['Items']->line_items[$line_no]->item_description = $line_desc;
242 function set_delivery_shipping_sum($delivery_notes)
247 foreach($delivery_notes as $delivery_num)
249 $myrow = get_customer_trans($delivery_num, 13);
250 //$branch = get_branch($myrow["branch_code"]);
251 //$sales_order = get_sales_order_header($myrow["order_"]);
253 //$shipping += $sales_order['freight_cost'];
254 $shipping += $myrow['ov_freight'];
256 $_POST['ChargeFreightCost'] = price_format($shipping);
260 function copy_to_cart()
262 $cart = &$_SESSION['Items'];
263 $cart->due_date = $cart->document_date = $_POST['InvoiceDate'];
264 $cart->Comments = $_POST['Comments'];
265 $cart->due_date = $_POST['due_date'];
266 if (($cart->pos['cash_sale'] || $cart->pos['credit_sale']) && isset($_POST['payment'])) {
267 $cart->payment = $_POST['payment'];
268 $cart->payment_terms = get_payment_terms($_POST['payment']);
270 if ($_SESSION['Items']->trans_no == 0)
271 $cart->reference = $_POST['ref'];
272 if (!$cart->is_prepaid())
274 $cart->ship_via = $_POST['ship_via'];
275 $cart->freight_cost = input_num('ChargeFreightCost');
278 $cart->update_payments();
280 $cart->dimension_id = $_POST['dimension_id'];
281 $cart->dimension2_id = $_POST['dimension2_id'];
283 //-----------------------------------------------------------------------------
285 function copy_from_cart()
287 $cart = &$_SESSION['Items'];
288 $_POST['Comments']= $cart->Comments;
289 $_POST['InvoiceDate']= $cart->document_date;
290 $_POST['ref'] = $cart->reference;
291 $_POST['cart_id'] = $cart->cart_id;
292 $_POST['due_date'] = $cart->due_date;
293 $_POST['payment'] = $cart->payment;
294 if (!$_SESSION['Items']->is_prepaid())
296 $_POST['ship_via'] = $cart->ship_via;
297 $_POST['ChargeFreightCost'] = price_format($cart->freight_cost);
299 $_POST['dimension_id'] = $cart->dimension_id;
300 $_POST['dimension2_id'] = $cart->dimension2_id;
303 //-----------------------------------------------------------------------------
305 function check_data()
309 $prepaid = $_SESSION['Items']->is_prepaid();
311 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
312 display_error(_("The entered invoice date is invalid."));
313 set_focus('InvoiceDate');
317 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
318 display_error(_("The entered date is out of fiscal year or is closed for further data entry."));
319 set_focus('InvoiceDate');
324 if (!$prepaid &&(!isset($_POST['due_date']) || !is_date($_POST['due_date']))) {
325 display_error(_("The entered invoice due date is invalid."));
326 set_focus('due_date');
330 if ($_SESSION['Items']->trans_no == 0) {
331 if (!$Refs->is_valid($_POST['ref'])) {
332 display_error(_("You must enter a reference."));
340 if ($_POST['ChargeFreightCost'] == "") {
341 $_POST['ChargeFreightCost'] = price_format(0);
344 if (!check_num('ChargeFreightCost', 0)) {
345 display_error(_("The entered shipping value is not numeric."));
346 set_focus('ChargeFreightCost');
350 if ($_SESSION['Items']->has_items_dispatch() == 0 && input_num('ChargeFreightCost') == 0) {
351 display_error(_("There are no item quantities on this invoice."));
355 if (!check_quantities()) {
356 display_error(_("Selected quantity cannot be less than quantity credited nor more than quantity not invoiced yet."));
360 if (($_SESSION['Items']->payment_terms['days_before_due'] < 0) && !count($_SESSION['Items']->prepayments)) {
361 display_error(_("There is no non-invoiced payments for this order. If you want to issue final invoice, select delayed or cash payment terms."));
369 //-----------------------------------------------------------------------------
370 if (isset($_POST['process_invoice']) && check_data()) {
371 $newinvoice= $_SESSION['Items']->trans_no == 0;
374 new_doc_date($_SESSION['Items']->document_date);
376 $invoice_no = $_SESSION['Items']->write();
377 if ($invoice_no == -1)
379 display_error(_("The entered reference is already in use."));
387 meta_forward($_SERVER['PHP_SELF'], "AddedID=$invoice_no");
389 meta_forward($_SERVER['PHP_SELF'], "UpdatedID=$invoice_no");
394 if(list_updated('payment')) {
395 $order = &$_SESSION['Items'];
397 $order->payment = get_post('payment');
398 $order->payment_terms = get_payment_terms($order->payment);
399 $_POST['due_date'] = $order->due_date = get_invoice_duedate($order->payment, $order->document_date);
400 $_POST['Comments'] = '';
401 $Ajax->activate('due_date');
402 $Ajax->activate('options');
403 if ($order->payment_terms['cash_sale']) {
404 $_POST['Location'] = $order->Location = $order->pos['pos_location'];
405 $order->location_name = $order->pos['location_name'];
409 // find delivery spans for batch invoice display
411 $lastdn = ''; $spanlen=1;
413 for ($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
414 $line = $_SESSION['Items']->line_items[$line_no];
415 if ($line->quantity == $line->qty_done) {
418 if ($line->src_no == $lastdn) {
422 $dspans[] = $spanlen;
426 $lastdn = $line->src_no;
428 $dspans[] = $spanlen;
430 //-----------------------------------------------------------------------------
432 $is_batch_invoice = count($_SESSION['Items']->src_docs) > 1;
433 $prepaid = $_SESSION['Items']->is_prepaid();
435 $is_edition = $_SESSION['Items']->trans_type == ST_SALESINVOICE && $_SESSION['Items']->trans_no != 0;
439 start_table(TABLESTYLE2, "width=80%", 5);
443 $dim = get_company_pref('use_dimension');
446 label_cells(_("Customer"), $_SESSION['Items']->customer_name, "class='tableheader2'");
447 label_cells(_("Branch"), get_branch_name($_SESSION['Items']->Branch), "class='tableheader2'");
448 if (($_SESSION['Items']->pos['credit_sale'] || $_SESSION['Items']->pos['cash_sale'])) {
449 $paymcat = !$_SESSION['Items']->pos['cash_sale'] ? PM_CREDIT :
450 (!$_SESSION['Items']->pos['credit_sale'] ? PM_CASH : PM_ANY);
451 label_cells(_("Payment terms:"), sale_payment_list('payment', $paymcat),
452 "class='tableheader2'", "colspan=$colspan");
454 label_cells(_('Payment:'), $_SESSION['Items']->payment_terms['terms'], "class='tableheader2'", "colspan=$colspan");
459 if ($_SESSION['Items']->trans_no == 0) {
460 ref_cells(_("Reference"), 'ref', '', null, "class='tableheader2'");
462 label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'");
465 //label_cells(_("Delivery Notes:"),
466 //get_customer_trans_view_str(ST_CUSTDELIVERY, array_keys($_SESSION['Items']->src_docs)), "class='tableheader2'");
468 label_cells(_("Sales Type"), $_SESSION['Items']->sales_type_name, "class='tableheader2'");
470 label_cells(_("Currency"), $_SESSION['Items']->customer_currency, "class='tableheader2'");
471 // 2010-09-03 Joe Hunt
473 // label_cells(_("Dimension"), get_dimension_string($_SESSION['Items']->dimension_id), "class='tableheader2'");
475 label_cell(_("Dimension").":", "class='tableheader2'");
476 $_POST['dimension_id'] = $_SESSION['Items']->dimension_id;
477 dimensions_list_cells(null, 'dimension_id', null, true, ' ', false, 1, false);
480 hidden('dimension_id', 0);
485 if (!isset($_POST['ship_via'])) {
486 $_POST['ship_via'] = $_SESSION['Items']->ship_via;
488 label_cell(_("Shipping Company"), "class='tableheader2'");
491 $shipper = get_shipper($_SESSION['Items']->ship_via);
492 label_cells(null, $shipper['shipper_name']);
494 shippers_list_cells(null, 'ship_via', $_POST['ship_via']);
496 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
497 $_POST['InvoiceDate'] = new_doc_date();
498 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
499 $_POST['InvoiceDate'] = end_fiscalyear();
503 date_cells(_("Date"), 'InvoiceDate', '', $_SESSION['Items']->trans_no == 0,
504 0, 0, 0, "class='tableheader2'", true);
506 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
507 $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->payment, $_POST['InvoiceDate']);
510 date_cells(_("Due Date"), 'due_date', '', null, 0, 0, 0, "class='tableheader2'");
513 label_cells(_("Dimension"). " 2", get_dimension_string($_SESSION['Items']->dimension2_id), "class='tableheader2'");
515 label_cell(" ", "colspan=2");
518 label_cell(_("Dimension")." 2:", "class='tableheader2'");
519 $_POST['dimension2_id'] = $_SESSION['Items']->dimension2_id;
520 dimensions_list_cells(null, 'dimension2_id', null, true, ' ', false, 2, false);
523 hidden('dimension2_id', 0);
527 $row = get_customer_to_order($_SESSION['Items']->customer_id);
528 if ($row['dissallow_invoices'] == 1)
530 display_error(_("The selected customer account is currently on hold. Please contact the credit control personnel to discuss."));
536 display_heading($prepaid ? _("Sales Order Items") : _("Invoice Items"));
539 start_table(TABLESTYLE, "width=80%");
541 $th = array(_("Item Code"), _("Item Description"), _("Units"), _("Quantity"),
542 _("Price"), _("Tax Type"), _("Discount"), _("Total"));
544 $th = array(_("Item Code"), _("Item Description"), _("Delivered"), _("Units"), _("Invoiced"),
545 _("This Invoice"), _("Price"), _("Tax Type"), _("Discount"), _("Total"));
546 if ($is_batch_invoice) {
552 $th[4] = _("Credited");
562 foreach ($_SESSION['Items']->line_items as $line=>$ln_itm) {
563 if (!$prepaid && ($ln_itm->quantity == $ln_itm->qty_done)) {
564 continue; // this line was fully invoiced
566 alt_table_row_color($k);
567 view_stock_status_cell($ln_itm->stock_id);
570 label_cell($ln_itm->item_description);
572 text_cells(null, 'Line'.$line.'Desc', $ln_itm->item_description, 30, 50);
573 $dec = get_qty_dec($ln_itm->stock_id);
575 qty_cell($ln_itm->quantity, false, $dec);
576 label_cell($ln_itm->units);
578 qty_cell($ln_itm->qty_done, false, $dec);
580 if ($is_batch_invoice || $prepaid) {
581 // for batch invoices we can only remove whole deliveries
582 echo '<td nowrap align=right>';
583 hidden('Line' . $line, $ln_itm->qty_dispatched );
584 echo number_format2($ln_itm->qty_dispatched, $dec).'</td>';
586 small_qty_cells(null, 'Line'.$line, qty_format($ln_itm->qty_dispatched, $ln_itm->stock_id, $dec), null, null, $dec);
588 $display_discount_percent = percent_format($ln_itm->discount_percent*100) . " %";
590 $line_total = ($ln_itm->qty_dispatched * $ln_itm->price * (1 - $ln_itm->discount_percent));
592 amount_cell($ln_itm->price);
593 label_cell($ln_itm->tax_type_name);
594 label_cell($display_discount_percent, "nowrap align=right");
595 amount_cell($line_total);
597 if ($is_batch_invoice) {
598 if ($dn_line_cnt == 0) {
599 $dn_line_cnt = $dspans[0];
600 $dspans = array_slice($dspans, 1);
601 label_cell($ln_itm->src_no, "rowspan=$dn_line_cnt class=oddrow");
602 label_cell("<a href='" . $_SERVER['PHP_SELF'] . "?RemoveDN=".
603 $ln_itm->src_no."'>" . _("Remove") . "</a>", "rowspan=$dn_line_cnt class=oddrow");
610 /*Don't re-calculate freight if some of the order has already been delivered -
611 depending on the business logic required this condition may not be required.
612 It seems unfair to charge the customer twice for freight if the order
613 was not fully delivered the first time ?? */
615 if (!isset($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] == "") {
616 if ($_SESSION['Items']->any_already_delivered() == 1) {
617 $_POST['ChargeFreightCost'] = price_format(0);
619 $_POST['ChargeFreightCost'] = price_format($_SESSION['Items']->freight_cost);
622 if (!check_num('ChargeFreightCost')) {
623 $_POST['ChargeFreightCost'] = price_format(0);
627 $accumulate_shipping = get_company_pref('accumulate_shipping');
628 if ($is_batch_invoice && $accumulate_shipping)
629 set_delivery_shipping_sum(array_keys($_SESSION['Items']->src_docs));
631 $colspan = $prepaid ? 7:9;
633 label_cell(_("Shipping Cost"), "colspan=$colspan align=right");
635 label_cell($_POST['ChargeFreightCost'], 'align=right');
637 small_amount_cells(null, 'ChargeFreightCost', null);
638 if ($is_batch_invoice) {
639 label_cell('', 'colspan=2');
643 $inv_items_total = $_SESSION['Items']->get_items_total_dispatch();
645 $display_sub_total = price_format($inv_items_total + input_num('ChargeFreightCost'));
647 label_row(_("Sub-total"), $display_sub_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
649 $taxes = $_SESSION['Items']->get_taxes(input_num('ChargeFreightCost'));
650 $tax_total = display_edit_tax_items($taxes, $colspan, $_SESSION['Items']->tax_included, $is_batch_invoice ? 2 : 0);
652 $display_total = price_format(($inv_items_total + input_num('ChargeFreightCost') + $tax_total));
654 label_row(_("Invoice Total"), $display_total, "colspan=$colspan align=right","align=right", $is_batch_invoice ? 2 : 0);
658 div_start('options');
659 start_table(TABLESTYLE2);
663 label_row(_("Sales order:"), get_trans_view_str(ST_SALESORDER, $_SESSION['Items']->order_no, get_reference(ST_SALESORDER, $_SESSION['Items']->order_no)));
665 $list = array(); $allocs = 0;
666 if (count($_SESSION['Items']->prepayments))
668 foreach($_SESSION['Items']->prepayments as $pmt)
670 $list[] = get_trans_view_str($pmt['trans_type_from'], $pmt['trans_no_from'], get_reference($pmt['trans_type_from'], $pmt['trans_no_from']));
671 $allocs += $pmt['amt'];
675 label_row(_("Payments received:"), implode(',', $list));
676 label_row(_("Invoiced here:"), price_format($_SESSION['Items']->prep_amount), 'class=label');
677 label_row(_("Left to be invoiced:"), price_format($_SESSION['Items']->get_trans_total()-max($_SESSION['Items']->prep_amount, $allocs)), 'class=label');
680 textarea_row(_("Memo:"), 'Comments', null, 50, 4);
684 submit_center_first('Update', _("Update"),
685 _('Refresh document page'), true);
686 submit_center_last('process_invoice', _("Process Invoice"),
687 _('Check entered data and save document'), 'default');