2 //---------------------------------------------------------------------------
4 // Entry/Modify Sales Invoice against single delivery
5 // Entry/Modify Batch Sales Invoice against batch of deliveries
9 include_once($path_to_root . "/sales/includes/cart_class.inc");
10 include_once($path_to_root . "/includes/session.inc");
11 include_once($path_to_root . "/includes/data_checks.inc");
12 include_once($path_to_root . "/includes/manufacturing.inc");
13 include_once($path_to_root . "/sales/includes/sales_db.inc");
14 include_once($path_to_root . "/sales/includes/sales_ui.inc");
15 include_once($path_to_root . "/reporting/includes/reporting.inc");
16 include_once($path_to_root . "/taxes/tax_calc.inc");
19 if ($use_popup_windows) {
20 $js .= get_js_open_window(900, 500);
22 if ($use_date_picker) {
23 $js .= get_js_date_picker();
26 if (isset($_GET['ModifyInvoice'])) {
27 $_SESSION['page_title'] = sprintf(_("Modifying Sales Invoice # %d.") ,$_GET['ModifyInvoice']);
28 $help_page_title = _("Modifying Sales Invoice");
29 } elseif (isset($_GET['DeliveryNumber'])) {
30 $_SESSION['page_title'] = _("Issue an Invoice for Delivery Note");
31 } elseif (isset($_GET['BatchInvoice'])) {
32 $_SESSION['page_title'] = _("Issue Batch Invoice for Delivery Notes");
35 page($_SESSION['page_title'], false, false, "", $js);
37 //-----------------------------------------------------------------------------
39 if (isset($_GET['AddedID'])) {
41 $invoice_no = $_GET['AddedID'];
43 print_hidden_script(10);
45 display_notification(_("Selected deliveries has been processed"), true);
47 display_note(get_customer_trans_view_str($trans_type, $invoice_no, _("View This Invoice")), 0, 1);
49 display_note(print_document_link($invoice_no, _("Print This Invoice"), true, 10));
51 display_note(get_gl_view_str($trans_type, $invoice_no, _("View the GL Journal Entries for this Invoice")),1);
53 hyperlink_params("$path_to_root/sales/inquiry/sales_deliveries_view.php", _("Select Another Delivery For Invoicing"), "OutstandingOnly=1");
55 display_footer_exit();
57 } elseif (isset($_GET['UpdatedID'])) {
59 $invoice_no = $_GET['UpdatedID'];
60 print_hidden_script(10);
62 display_notification_centered(sprintf(_('Sales Invoice # %d has been updated.'),$invoice_no));
64 display_note(get_trans_view_str(10, $invoice_no, _("View This Invoice")));
66 display_note(print_document_link($invoice_no, _("Print This Invoice"), true, 10));
68 hyperlink_no_params($path_to_root . "/sales/inquiry/customer_inquiry.php", _("Select A Different Invoice to Modify"));
70 display_footer_exit();
72 } elseif (isset($_GET['RemoveDN'])) {
74 for($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
75 $line = &$_SESSION['Items']->line_items[$line_no];
76 if ($line->src_no == $_GET['RemoveDN']) {
77 $line->quantity = $line->qty_done;
78 $line->qty_dispatched=0;
84 //-----------------------------------------------------------------------------
86 if ( (isset($_GET['DeliveryNumber']) && ($_GET['DeliveryNumber'] > 0) )
87 || isset($_GET['BatchInvoice'])) {
91 if (isset($_GET['BatchInvoice'])) {
92 $src = $_SESSION['DeliveryBatch'];
93 unset($_SESSION['DeliveryBatch']);
95 $src = array($_GET['DeliveryNumber']);
97 /*read in all the selected deliveries into the Items cart */
98 $dn = new Cart(13, $src, true);
100 if ($dn->count_items() == 0) {
101 hyperlink_params($path_to_root . "/sales/inquiry/sales_deliveries_view.php",
102 _("Select a different delivery to invoice"), "OutstandingOnly=1");
103 die ("<br><b>" . _("There are no delivered items with a quantity left to invoice. There is nothing left to invoice.") . "</b>");
106 $dn->trans_type = 10;
107 $dn->src_docs = $dn->trans_no;
109 $dn->reference = references::get_next(10);
110 $dn->due_date = get_invoice_duedate($dn->customer_id, $dn->document_date);
112 $_SESSION['Items'] = $dn;
115 } elseif (isset($_GET['ModifyInvoice']) && $_GET['ModifyInvoice'] > 0) {
117 if ( get_parent_trans(10, $_GET['ModifyInvoice']) == 0) { // 1.xx compatibility hack
118 echo"<center><br><b>" . _("There in no delivery notes for this invoice.<br>
119 Most likely this invoice was created in Front Accounting version prior to 2.0
120 and therefore can not be modified.") . "</b></center>";
121 display_footer_exit();
124 $_SESSION['Items'] = new Cart(10, $_GET['ModifyInvoice']);
126 if ($_SESSION['Items']->count_items() == 0) {
127 echo"<center><br><b>" . _("All quantities on this invoice has been credited. There is nothing to modify on this invoice") . "</b></center>";
128 display_footer_exit();
131 } elseif (!processing_active()) {
132 /* This page can only be called with a delivery for invoicing or invoice no for edit */
133 display_error(_("This page can only be opened after delivery selection. Please select delivery to invoicing first."));
135 hyperlink_no_params("$path_to_root/sales/inquiry/sales_deliveries_view.php", _("Select Delivery to Invoice"));
140 foreach ($_SESSION['Items']->line_items as $line_no=>$itm) {
141 if (isset($_POST['Line'.$line_no])) {
142 if (!check_num('Line'.$line_no, 0, ($itm->quantity - $itm->qty_done))) {
143 $_SESSION['Items']->line_items[$line_no]->qty_dispatched =
144 input_num('Line'.$line_no);
148 if (isset($_POST['Line'.$line_no.'Desc'])) {
149 $line_desc = $_POST['Line'.$line_no.'Desc'];
150 if (strlen($line_desc) > 0) {
151 $_SESSION['Items']->line_items[$line_no]->item_description = $line_desc;
156 //-----------------------------------------------------------------------------
158 function copy_to_cart()
160 $cart = &$_SESSION['Items'];
161 $cart->ship_via = $_POST['ship_via'];
162 $cart->freight_cost = input_num('ChargeFreightCost');
163 $cart->document_date = $_POST['InvoiceDate'];
164 $cart->due_date = $_POST['due_date'];
165 $cart->Comments = $_POST['Comments'];
167 //-----------------------------------------------------------------------------
169 function copy_from_cart()
171 $cart = &$_SESSION['Items'];
172 $_POST['ship_via'] = $cart->ship_via;
173 $_POST['ChargeFreightCost'] = price_format($cart->freight_cost);
174 $_POST['InvoiceDate']= $cart->document_date;
175 $_POST['due_date'] = $cart->due_date;
176 $_POST['Comments']= $cart->Comments;
179 //-----------------------------------------------------------------------------
181 function check_data()
183 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
184 display_error(_("The entered invoice date is invalid."));
185 set_focus('InvoiceDate');
189 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
190 display_error(_("The entered invoice date is not in fiscal year."));
191 set_focus('InvoiceDate');
195 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
196 display_error(_("The entered invoice due date is invalid."));
197 set_focus('due_date');
201 if ($_SESSION['Items']->trans_no == 0) {
202 if (!references::is_valid($_POST['ref'])) {
203 display_error(_("You must enter a reference."));
208 if (!is_new_reference($_POST['ref'], 10)) {
209 display_error(_("The entered reference is already in use."));
215 if ($_POST['ChargeFreightCost'] == "") {
216 $_POST['ChargeFreightCost'] = price_format(0);
219 if (!check_num('ChargeFreightCost', 0)) {
220 display_error(_("The entered shipping value is not numeric."));
221 set_focus('ChargeFreightCost');
225 if ($_SESSION['Items']->has_items_dispatch() == 0 && input_num('ChargeFreightCost') == 0) {
226 display_error(_("There are no item quantities on this invoice."));
233 //-----------------------------------------------------------------------------
234 if (isset($_POST['process_invoice']) && check_data()) {
236 $newinvoice= $_SESSION['Items']->trans_no == 0;
238 $invoice_no = $_SESSION['Items']->write();
242 meta_forward($_SERVER['PHP_SELF'], "AddedID=$invoice_no");
244 meta_forward($_SERVER['PHP_SELF'], "UpdatedID=$invoice_no");
248 // find delivery spans for batch invoice display
250 $lastdn = ''; $spanlen=1;
252 for ($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
253 $line = $_SESSION['Items']->line_items[$line_no];
254 if ($line->quantity == $line->qty_done) {
257 if ($line->src_no == $lastdn) {
261 $dspans[] = $spanlen;
265 $lastdn = $line->src_no;
267 $dspans[] = $spanlen;
269 //-----------------------------------------------------------------------------
271 $is_batch_invoice = count($_SESSION['Items']->src_docs) > 1;
272 $is_edition = $_SESSION['Items']->trans_type == 10 && $_SESSION['Items']->trans_no != 0;
273 start_form(false, true);
275 start_table("$table_style2 width=80%", 5);
278 label_cells(_("Customer"), $_SESSION['Items']->customer_name, "class='tableheader2'");
279 label_cells(_("Branch"), get_branch_name($_SESSION['Items']->Branch), "class='tableheader2'");
280 label_cells(_("Currency"), $_SESSION['Items']->customer_currency, "class='tableheader2'");
284 if ($_SESSION['Items']->trans_no == 0) {
285 ref_cells(_("Reference"), 'ref', '', $_SESSION['Items']->reference, "class='tableheader2'");
287 label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'");
290 label_cells(_("Delivery Notes:"),
291 get_customer_trans_view_str(systypes::cust_dispatch(), array_keys($_SESSION['Items']->src_docs)), "class='tableheader2'");
293 label_cells(_("Sales Type"), $_SESSION['Items']->sales_type_name, "class='tableheader2'");
298 if (!isset($_POST['ship_via'])) {
299 $_POST['ship_via'] = $_SESSION['Items']->ship_via;
301 label_cell(_("Shipping Company"), "class='tableheader2'");
302 shippers_list_cells(null, 'ship_via', $_POST['ship_via']);
304 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
305 $_POST['InvoiceDate'] = Today();
306 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
307 $_POST['InvoiceDate'] = end_fiscalyear();
311 date_cells(_("Date"), 'InvoiceDate', '', $_POST['InvoiceDate'], 0, 0, 0, "class='tableheader2'");
313 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
314 $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->customer_id, $_POST['InvoiceDate']);
317 date_cells(_("Due Date"), 'due_date', '', $_POST['due_date'], 0, 0, 0, "class='tableheader2'");
322 display_heading(_("Invoice Items"));
324 start_table("$table_style width=80%");
325 $th = array(_("Item Code"), _("Item Description"), _("Delivered"), _("Units"), _("Invoiced"),
326 _("This Invoice"), _("Price"), _("Tax Type"), _("Discount"), _("Total"));
328 if ($is_batch_invoice) {
334 $th[4] = _("Credited");
344 foreach ($_SESSION['Items']->line_items as $line=>$ln_itm) {
345 if ($ln_itm->quantity == $ln_itm->qty_done) {
346 continue; // this line was fully invoiced
348 alt_table_row_color($k);
349 view_stock_status_cell($ln_itm->stock_id);
351 text_cells(null, 'Line'.$line.'Desc', $ln_itm->item_description, 30, 50);
352 qty_cell($ln_itm->quantity);
353 label_cell($ln_itm->units);
354 qty_cell($ln_itm->qty_done);
356 if ($is_batch_invoice) {
357 // for batch invoices we can only remove whole deliveries
358 echo '<td nowrap align=right>';
359 hidden('Line' . $line, $ln_itm->qty_dispatched );
360 echo qty_format($ln_itm->qty_dispatched).'</td>';
362 small_qty_cells(null, 'Line'.$line, qty_format($ln_itm->qty_dispatched));
364 $display_discount_percent = percent_format($ln_itm->discount_percent*100) . " %";
366 $line_total = ($ln_itm->qty_dispatched * $ln_itm->price * (1 - $ln_itm->discount_percent));
368 amount_cell($ln_itm->price);
369 label_cell($ln_itm->tax_type_name);
370 label_cell($display_discount_percent, "nowrap align=right");
371 amount_cell($line_total);
373 if ($is_batch_invoice) {
374 if ($dn_line_cnt == 0) {
375 $dn_line_cnt = $dspans[0];
376 $dspans = array_slice($dspans, 1);
377 label_cell($ln_itm->src_no, "rowspan=$dn_line_cnt class=oddrow");
378 label_cell("<a href='" . $_SERVER['PHP_SELF'] . "?RemoveDN=".
379 $ln_itm->src_no."'>" . _("Remove") . "</a>", "rowspan=$dn_line_cnt class=oddrow");
386 /*Don't re-calculate freight if some of the order has already been delivered -
387 depending on the business logic required this condition may not be required.
388 It seems unfair to charge the customer twice for freight if the order
389 was not fully delivered the first time ?? */
391 if (!isset($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] == "") {
392 if ($_SESSION['Items']->any_already_delivered() == 1) {
393 $_POST['ChargeFreightCost'] = price_format(0);
395 $_POST['ChargeFreightCost'] = price_format($_SESSION['Items']->freight_cost);
398 if (!check_num('ChargeFreightCost')) {
399 $_POST['ChargeFreightCost'] = price_format(0);
405 small_amount_cells(_("Shipping Cost"), 'ChargeFreightCost', null, "colspan=9 align=right");
406 if ($is_batch_invoice) {
407 label_cell('', 'colspan=2');
411 $inv_items_total = $_SESSION['Items']->get_items_total_dispatch();
413 $display_sub_total = price_format($inv_items_total + input_num('ChargeFreightCost'));
415 label_row(_("Sub-total"), $display_sub_total, "colspan=9 align=right","align=right", $is_batch_invoice ? 2 : 0);
417 $taxes = $_SESSION['Items']->get_taxes(input_num('ChargeFreightCost'));
418 $tax_total = display_edit_tax_items($taxes, 9, $_SESSION['Items']->tax_included, $is_batch_invoice ? 2:0);
420 $display_total = price_format(($inv_items_total + input_num('ChargeFreightCost') + $tax_total));
422 label_row(_("Invoice Total"), $display_total, "colspan=9 align=right","align=right", $is_batch_invoice ? 2 : 0);
426 start_table($table_style2);
428 textarea_row(_("Memo"), 'Comments', null, 50, 4);
432 submit_center_first('Update', _("Update"));
433 submit_center_last('process_invoice', _("Process Invoice"));