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);
111 $_SESSION['Items'] = $dn;
114 } elseif (isset($_GET['ModifyInvoice']) && $_GET['ModifyInvoice'] > 0) {
117 $_SESSION['Items'] = new Cart(10, $_GET['ModifyInvoice']);
119 if ($_SESSION['Items']->count_items() == 0) {
120 echo"<center><br><b>" . _("All quantities on this invoice has been credited. There is nothing to modify on this invoice") . "</b></center>";
121 display_footer_exit();
124 } elseif (!processing_active()) {
125 /* This page can only be called with a delivery for invoicing or invoice no for edit */
126 display_error(_("This page can only be opened after delivery selection. Please select delivery to invoicing first."));
128 hyperlink_no_params("$path_to_root/sales/inquiry/sales_deliveries_view.php", _("Select Delivery to Invoice"));
133 foreach ($_SESSION['Items']->line_items as $line_no=>$itm) {
134 if (isset($_POST['Line'.$line_no])) {
135 $line_qty = $_POST['Line'.$line_no];
136 if (is_numeric($line_qty) && $_POST['Line'.$line_no] <= ($itm->quantity - $itm->qty_done)) {
137 $_SESSION['Items']->line_items[$line_no]->qty_dispatched = $line_qty;
141 if (isset($_POST['Line'.$line_no.'Desc'])) {
142 $line_desc = $_POST['Line'.$line_no.'Desc'];
143 if (strlen($line_desc) > 0) {
144 $_SESSION['Items']->line_items[$line_no]->item_description = $line_desc;
149 //-----------------------------------------------------------------------------
151 function copy_to_cart()
153 $cart = &$_SESSION['Items'];
154 $cart->ship_via = $_POST['ship_via'];
155 $cart->freight_cost = $_POST['ChargeFreightCost'];
156 $cart->document_date = $_POST['InvoiceDate'];
157 $cart->due_date = $_POST['due_date'];
158 $cart->Comments = $_POST['Comments'];
160 //-----------------------------------------------------------------------------
162 function copy_from_cart()
164 $cart = &$_SESSION['Items'];
165 $_POST['ship_via'] = $cart->ship_via;
166 $_POST['ChargeFreightCost'] = $cart->freight_cost;
167 $_POST['InvoiceDate']= $cart->document_date;
168 $_POST['due_date'] = $cart->due_date;
169 $_POST['Comments']= $cart->Comments;
172 //-----------------------------------------------------------------------------
174 function check_data()
176 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
177 display_error(_("The entered invoice date is invalid."));
181 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
182 display_error(_("The entered invoice date is not in fiscal year."));
186 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
187 display_error(_("The entered invoice due date is invalid."));
191 if ($_SESSION['Items']->trans_no == 0) {
192 if (!references::is_valid($_POST['ref'])) {
193 display_error(_("You must enter a reference."));
197 if (!is_new_reference($_POST['ref'], 10)) {
198 display_error(_("The entered reference is already in use."));
203 if ($_POST['ChargeFreightCost'] == "") {
204 $_POST['ChargeFreightCost'] = 0;
207 if (!is_numeric($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] < 0) {
208 display_error(_("The entered shipping value is not numeric."));
212 if ($_SESSION['Items']->has_items_dispatch() == 0 && $_POST['ChargeFreightCost'] == 0) {
213 display_error(_("There are no item quantities on this invoice."));
220 //-----------------------------------------------------------------------------
221 if (isset($_POST['process_invoice']) && check_data()) {
223 $newinvoice= $_SESSION['Items']->trans_no == 0;
225 $invoice_no = $_SESSION['Items']->write();
229 meta_forward($_SERVER['PHP_SELF'], "AddedID=$invoice_no");
231 meta_forward($_SERVER['PHP_SELF'], "UpdatedID=$invoice_no");
235 // find delivery spans for batch invoice display
237 $lastdn = ''; $spanlen=1;
239 for ($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
240 $line = $_SESSION['Items']->line_items[$line_no];
241 if ($line->quantity == $line->qty_done) {
244 if ($line->src_no == $lastdn) {
248 $dspans[] = $spanlen;
252 $lastdn = $line->src_no;
254 $dspans[] = $spanlen;
256 //-----------------------------------------------------------------------------
258 $is_batch_invoice = count($_SESSION['Items']->src_docs) > 1;
259 $is_edition = $_SESSION['Items']->trans_type == 10 && $_SESSION['Items']->trans_no != 0;
260 start_form(false, true);
262 start_table("$table_style2 width=80%", 5);
265 label_cells(_("Customer"), $_SESSION['Items']->customer_name, "class='tableheader2'");
266 label_cells(_("Branch"), get_branch_name($_SESSION['Items']->Branch), "class='tableheader2'");
267 label_cells(_("Currency"), $_SESSION['Items']->customer_currency, "class='tableheader2'");
271 if ($_SESSION['Items']->trans_no == 0) {
272 ref_cells(_("Reference"), 'ref', $_SESSION['Items']->reference, "class='tableheader2'");
274 label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'");
277 label_cells(_("Delivery Notes:"),
278 get_customer_trans_view_str(systypes::cust_dispatch(), array_keys($_SESSION['Items']->src_docs)), "class='tableheader2'");
280 if (!isset($_POST['sales_type_id'])) {
281 $_POST['sales_type_id'] = $_SESSION['Items']->default_sales_type;
284 label_cell(_("Sales Type"), "class='tableheader2'");
285 sales_types_list_cells(null, 'sales_type_id', $_POST['sales_type_id']);
290 if (!isset($_POST['ship_via'])) {
291 $_POST['ship_via'] = $_SESSION['Items']->ship_via;
293 label_cell(_("Shipping Company"), "class='tableheader2'");
294 shippers_list_cells(null, 'ship_via', $_POST['ship_via']);
296 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
297 $_POST['InvoiceDate'] = Today();
298 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
299 $_POST['InvoiceDate'] = end_fiscalyear();
303 date_cells(_("Date"), 'InvoiceDate', $_POST['InvoiceDate'], 0, 0, 0, "class='tableheader'");
305 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
306 $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->customer_id, $_POST['InvoiceDate']);
309 date_cells(_("Due Date"), 'due_date', $_POST['due_date'], 0, 0, 0, "class='tableheader'");
314 display_heading(_("Invoice Items"));
316 start_table("$table_style width=80%");
317 $th = array(_("Item Code"), _("Item Description"), _("Delivered"), _("Units"), _("Invoiced"),
318 _("This Invoice"), _("Price"), _("Tax Type"), _("Discount"), _("Total"));
320 if ($is_batch_invoice) {
326 $th[4] = _("Credited");
336 foreach ($_SESSION['Items']->line_items as $line=>$ln_itm) {
337 if ($ln_itm->quantity == $ln_itm->qty_done) {
338 continue; // this line was fully invoiced
340 alt_table_row_color($k);
341 view_stock_status_cell($ln_itm->stock_id);
343 text_cells(null, 'Line'.$line.'Desc', $ln_itm->item_description, 30, 50);
344 qty_cell($ln_itm->quantity);
345 label_cell($ln_itm->units);
346 qty_cell($ln_itm->qty_done);
348 if ($is_batch_invoice) {
349 // for batch invoices we can only remove whole deliveries
350 echo '<td nowrap align=right>';
351 hidden('Line' . $line, $ln_itm->qty_dispatched );
352 echo number_format2($ln_itm->qty_dispatched, user_qty_dec()).'</td>';
354 text_cells(null, 'Line'.$line, $ln_itm->qty_dispatched, 10, 10);
356 $display_discount_percent = number_format2($ln_itm->discount_percent*100, user_percent_dec()) . "%";
358 $line_total = ($ln_itm->qty_dispatched * $ln_itm->price * (1 - $ln_itm->discount_percent));
360 amount_cell($ln_itm->price);
361 label_cell($ln_itm->tax_type_name);
362 label_cell($display_discount_percent, "nowrap align=right");
363 amount_cell($line_total);
365 if ($is_batch_invoice) {
366 if ($dn_line_cnt == 0) {
367 $dn_line_cnt = $dspans[0];
368 $dspans = array_slice($dspans, 1);
369 label_cell($ln_itm->src_no, "rowspan=$dn_line_cnt class=oddrow");
370 label_cell("<a href='" . $_SERVER['PHP_SELF'] . "?RemoveDN=".
371 $ln_itm->src_no."'>" . _("Remove") . "</a>", "rowspan=$dn_line_cnt class=oddrow");
378 /*Don't re-calculate freight if some of the order has already been delivered -
379 depending on the business logic required this condition may not be required.
380 It seems unfair to charge the customer twice for freight if the order
381 was not fully delivered the first time ?? */
383 if (!isset($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] == "") {
384 if ($_SESSION['Items']->any_already_delivered() == 1) {
385 $_POST['ChargeFreightCost'] = 0;
387 $_POST['ChargeFreightCost'] = $_SESSION['Items']->freight_cost;
390 if (!is_numeric($_POST['ChargeFreightCost'])) {
391 $_POST['ChargeFreightCost'] = 0;
397 small_amount_cells(_("Shipping Cost"), 'ChargeFreightCost', null, "colspan=9 align=right");
398 if ($is_batch_invoice) {
399 label_cell('', 'colspan=2');
403 $inv_items_total = $_SESSION['Items']->get_items_total_dispatch();
405 $display_sub_total = number_format2($inv_items_total + $_POST['ChargeFreightCost'],user_price_dec());
407 label_row(_("Sub-total"), $display_sub_total, "colspan=9 align=right","align=right", $is_batch_invoice ? 2 : 0);
409 $taxes = $_SESSION['Items']->get_taxes($_POST['ChargeFreightCost']);
410 $tax_total = display_edit_tax_items($taxes, 9, $_SESSION['Items']->tax_included, $is_batch_invoice ? 2:0);
412 $display_total = number_format2(($inv_items_total + $_POST['ChargeFreightCost'] + $tax_total), user_price_dec());
414 label_row(_("Invoice Total"), $display_total, "colspan=9 align=right","align=right", $is_batch_invoice ? 2 : 0);
418 start_table($table_style2);
420 textarea_row(_("Memo"), 'Comments', null, 50, 4);
424 submit_center_first('Update', _("Update"));
425 submit_center_last('process_invoice', _("Process Invoice"));