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) {
118 $_SESSION['Items'] = new Cart(10, $_GET['ModifyInvoice']);
120 if ($_SESSION['Items']->count_items() == 0) {
121 echo"<center><br><b>" . _("All quantities on this invoice has been credited. There is nothing to modify on this invoice") . "</b></center>";
122 display_footer_exit();
125 } elseif (!processing_active()) {
126 /* This page can only be called with a delivery for invoicing or invoice no for edit */
127 display_error(_("This page can only be opened after delivery selection. Please select delivery to invoicing first."));
129 hyperlink_no_params("$path_to_root/sales/inquiry/sales_deliveries_view.php", _("Select Delivery to Invoice"));
134 foreach ($_SESSION['Items']->line_items as $line_no=>$itm) {
135 if (isset($_POST['Line'.$line_no])) {
136 if (!check_num('Line'.$line_no, 0, ($itm->quantity - $itm->qty_done))) {
137 $_SESSION['Items']->line_items[$line_no]->qty_dispatched =
138 input_num('Line'.$line_no);
142 if (isset($_POST['Line'.$line_no.'Desc'])) {
143 $line_desc = $_POST['Line'.$line_no.'Desc'];
144 if (strlen($line_desc) > 0) {
145 $_SESSION['Items']->line_items[$line_no]->item_description = $line_desc;
150 //-----------------------------------------------------------------------------
152 function copy_to_cart()
154 $cart = &$_SESSION['Items'];
155 $cart->ship_via = $_POST['ship_via'];
156 $cart->freight_cost = input_num('ChargeFreightCost');
157 $cart->document_date = $_POST['InvoiceDate'];
158 $cart->due_date = $_POST['due_date'];
159 $cart->Comments = $_POST['Comments'];
161 //-----------------------------------------------------------------------------
163 function copy_from_cart()
165 $cart = &$_SESSION['Items'];
166 $_POST['ship_via'] = $cart->ship_via;
167 $_POST['ChargeFreightCost'] = price_format($cart->freight_cost);
168 $_POST['InvoiceDate']= $cart->document_date;
169 $_POST['due_date'] = $cart->due_date;
170 $_POST['Comments']= $cart->Comments;
173 //-----------------------------------------------------------------------------
175 function check_data()
177 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
178 display_error(_("The entered invoice date is invalid."));
179 set_focus('InvoiceDate');
183 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
184 display_error(_("The entered invoice date is not in fiscal year."));
185 set_focus('InvoiceDate');
189 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
190 display_error(_("The entered invoice due date is invalid."));
191 set_focus('due_date');
195 if ($_SESSION['Items']->trans_no == 0) {
196 if (!references::is_valid($_POST['ref'])) {
197 display_error(_("You must enter a reference."));
202 if (!is_new_reference($_POST['ref'], 10)) {
203 display_error(_("The entered reference is already in use."));
209 if ($_POST['ChargeFreightCost'] == "") {
210 $_POST['ChargeFreightCost'] = price_format(0);
213 if (!check_num('ChargeFreightCost', 0)) {
214 display_error(_("The entered shipping value is not numeric."));
215 set_focus('ChargeFreightCost');
219 if ($_SESSION['Items']->has_items_dispatch() == 0 && input_num('ChargeFreightCost') == 0) {
220 display_error(_("There are no item quantities on this invoice."));
227 //-----------------------------------------------------------------------------
228 if (isset($_POST['process_invoice']) && check_data()) {
230 $newinvoice= $_SESSION['Items']->trans_no == 0;
232 $invoice_no = $_SESSION['Items']->write();
236 meta_forward($_SERVER['PHP_SELF'], "AddedID=$invoice_no");
238 meta_forward($_SERVER['PHP_SELF'], "UpdatedID=$invoice_no");
242 // find delivery spans for batch invoice display
244 $lastdn = ''; $spanlen=1;
246 for ($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
247 $line = $_SESSION['Items']->line_items[$line_no];
248 if ($line->quantity == $line->qty_done) {
251 if ($line->src_no == $lastdn) {
255 $dspans[] = $spanlen;
259 $lastdn = $line->src_no;
261 $dspans[] = $spanlen;
263 //-----------------------------------------------------------------------------
265 $is_batch_invoice = count($_SESSION['Items']->src_docs) > 1;
266 $is_edition = $_SESSION['Items']->trans_type == 10 && $_SESSION['Items']->trans_no != 0;
267 start_form(false, true);
269 start_table("$table_style2 width=80%", 5);
272 label_cells(_("Customer"), $_SESSION['Items']->customer_name, "class='tableheader2'");
273 label_cells(_("Branch"), get_branch_name($_SESSION['Items']->Branch), "class='tableheader2'");
274 label_cells(_("Currency"), $_SESSION['Items']->customer_currency, "class='tableheader2'");
278 if ($_SESSION['Items']->trans_no == 0) {
279 ref_cells(_("Reference"), 'ref', $_SESSION['Items']->reference, "class='tableheader2'");
281 label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'");
284 label_cells(_("Delivery Notes:"),
285 get_customer_trans_view_str(systypes::cust_dispatch(), array_keys($_SESSION['Items']->src_docs)), "class='tableheader2'");
287 label_cells(_("Sales Type"), $_SESSION['Items']->sales_type_name, "class='tableheader2'");
292 if (!isset($_POST['ship_via'])) {
293 $_POST['ship_via'] = $_SESSION['Items']->ship_via;
295 label_cell(_("Shipping Company"), "class='tableheader2'");
296 shippers_list_cells(null, 'ship_via', $_POST['ship_via']);
298 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
299 $_POST['InvoiceDate'] = Today();
300 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
301 $_POST['InvoiceDate'] = end_fiscalyear();
305 date_cells(_("Date"), 'InvoiceDate', $_POST['InvoiceDate'], 0, 0, 0, "class='tableheader2'");
307 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
308 $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->customer_id, $_POST['InvoiceDate']);
311 date_cells(_("Due Date"), 'due_date', $_POST['due_date'], 0, 0, 0, "class='tableheader2'");
316 display_heading(_("Invoice Items"));
318 start_table("$table_style width=80%");
319 $th = array(_("Item Code"), _("Item Description"), _("Delivered"), _("Units"), _("Invoiced"),
320 _("This Invoice"), _("Price"), _("Tax Type"), _("Discount"), _("Total"));
322 if ($is_batch_invoice) {
328 $th[4] = _("Credited");
338 foreach ($_SESSION['Items']->line_items as $line=>$ln_itm) {
339 if ($ln_itm->quantity == $ln_itm->qty_done) {
340 continue; // this line was fully invoiced
342 alt_table_row_color($k);
343 view_stock_status_cell($ln_itm->stock_id);
345 text_cells(null, 'Line'.$line.'Desc', $ln_itm->item_description, 30, 50);
346 qty_cell($ln_itm->quantity);
347 label_cell($ln_itm->units);
348 qty_cell($ln_itm->qty_done);
350 if ($is_batch_invoice) {
351 // for batch invoices we can only remove whole deliveries
352 echo '<td nowrap align=right>';
353 hidden('Line' . $line, $ln_itm->qty_dispatched );
354 echo qty_format($ln_itm->qty_dispatched).'</td>';
356 small_qty_cells(null, 'Line'.$line, qty_format($ln_itm->qty_dispatched));
358 $display_discount_percent = percent_format($ln_itm->discount_percent*100) . " %";
360 $line_total = ($ln_itm->qty_dispatched * $ln_itm->price * (1 - $ln_itm->discount_percent));
362 amount_cell($ln_itm->price);
363 label_cell($ln_itm->tax_type_name);
364 label_cell($display_discount_percent, "nowrap align=right");
365 amount_cell($line_total);
367 if ($is_batch_invoice) {
368 if ($dn_line_cnt == 0) {
369 $dn_line_cnt = $dspans[0];
370 $dspans = array_slice($dspans, 1);
371 label_cell($ln_itm->src_no, "rowspan=$dn_line_cnt class=oddrow");
372 label_cell("<a href='" . $_SERVER['PHP_SELF'] . "?RemoveDN=".
373 $ln_itm->src_no."'>" . _("Remove") . "</a>", "rowspan=$dn_line_cnt class=oddrow");
380 /*Don't re-calculate freight if some of the order has already been delivered -
381 depending on the business logic required this condition may not be required.
382 It seems unfair to charge the customer twice for freight if the order
383 was not fully delivered the first time ?? */
385 if (!isset($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] == "") {
386 if ($_SESSION['Items']->any_already_delivered() == 1) {
387 $_POST['ChargeFreightCost'] = price_format(0);
389 $_POST['ChargeFreightCost'] = price_format($_SESSION['Items']->freight_cost);
392 if (!check_num('ChargeFreightCost')) {
393 $_POST['ChargeFreightCost'] = price_format(0);
399 small_amount_cells(_("Shipping Cost"), 'ChargeFreightCost', null, "colspan=9 align=right");
400 if ($is_batch_invoice) {
401 label_cell('', 'colspan=2');
405 $inv_items_total = $_SESSION['Items']->get_items_total_dispatch();
407 $display_sub_total = price_format($inv_items_total + input_num('ChargeFreightCost'));
409 label_row(_("Sub-total"), $display_sub_total, "colspan=9 align=right","align=right", $is_batch_invoice ? 2 : 0);
411 $taxes = $_SESSION['Items']->get_taxes(input_num('ChargeFreightCost'));
412 $tax_total = display_edit_tax_items($taxes, 9, $_SESSION['Items']->tax_included, $is_batch_invoice ? 2:0);
414 $display_total = price_format(($inv_items_total + input_num('ChargeFreightCost') + $tax_total));
416 label_row(_("Invoice Total"), $display_total, "colspan=9 align=right","align=right", $is_batch_invoice ? 2 : 0);
420 start_table($table_style2);
422 textarea_row(_("Memo"), 'Comments', null, 50, 4);
426 submit_center_first('Update', _("Update"));
427 submit_center_last('process_invoice', _("Process Invoice"));