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 $line_qty = $_POST['Line'.$line_no];
137 if (is_numeric($line_qty) && $_POST['Line'.$line_no] <= ($itm->quantity - $itm->qty_done)) {
138 $_SESSION['Items']->line_items[$line_no]->qty_dispatched = $line_qty;
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 = $_POST['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'] = $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."));
182 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
183 display_error(_("The entered invoice date is not in fiscal year."));
187 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
188 display_error(_("The entered invoice due date is invalid."));
192 if ($_SESSION['Items']->trans_no == 0) {
193 if (!references::is_valid($_POST['ref'])) {
194 display_error(_("You must enter a reference."));
198 if (!is_new_reference($_POST['ref'], 10)) {
199 display_error(_("The entered reference is already in use."));
204 if ($_POST['ChargeFreightCost'] == "") {
205 $_POST['ChargeFreightCost'] = 0;
208 if (!is_numeric($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] < 0) {
209 display_error(_("The entered shipping value is not numeric."));
213 if ($_SESSION['Items']->has_items_dispatch() == 0 && $_POST['ChargeFreightCost'] == 0) {
214 display_error(_("There are no item quantities on this invoice."));
221 //-----------------------------------------------------------------------------
222 if (isset($_POST['process_invoice']) && check_data()) {
224 $newinvoice= $_SESSION['Items']->trans_no == 0;
226 $invoice_no = $_SESSION['Items']->write();
230 meta_forward($_SERVER['PHP_SELF'], "AddedID=$invoice_no");
232 meta_forward($_SERVER['PHP_SELF'], "UpdatedID=$invoice_no");
236 // find delivery spans for batch invoice display
238 $lastdn = ''; $spanlen=1;
240 for ($line_no = 0; $line_no < count($_SESSION['Items']->line_items); $line_no++) {
241 $line = $_SESSION['Items']->line_items[$line_no];
242 if ($line->quantity == $line->qty_done) {
245 if ($line->src_no == $lastdn) {
249 $dspans[] = $spanlen;
253 $lastdn = $line->src_no;
255 $dspans[] = $spanlen;
257 //-----------------------------------------------------------------------------
259 $is_batch_invoice = count($_SESSION['Items']->src_docs) > 1;
260 $is_edition = $_SESSION['Items']->trans_type == 10 && $_SESSION['Items']->trans_no != 0;
261 start_form(false, true);
263 start_table("$table_style2 width=80%", 5);
266 label_cells(_("Customer"), $_SESSION['Items']->customer_name, "class='tableheader2'");
267 label_cells(_("Branch"), get_branch_name($_SESSION['Items']->Branch), "class='tableheader2'");
268 label_cells(_("Currency"), $_SESSION['Items']->customer_currency, "class='tableheader2'");
272 if ($_SESSION['Items']->trans_no == 0) {
273 ref_cells(_("Reference"), 'ref', $_SESSION['Items']->reference, "class='tableheader2'");
275 label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'");
278 label_cells(_("Delivery Notes:"),
279 get_customer_trans_view_str(systypes::cust_dispatch(), array_keys($_SESSION['Items']->src_docs)), "class='tableheader2'");
281 label_cells(_("Sales Type"), $_SESSION['Items']->sales_type_name, "class='tableheader2'");
286 if (!isset($_POST['ship_via'])) {
287 $_POST['ship_via'] = $_SESSION['Items']->ship_via;
289 label_cell(_("Shipping Company"), "class='tableheader2'");
290 shippers_list_cells(null, 'ship_via', $_POST['ship_via']);
292 if (!isset($_POST['InvoiceDate']) || !is_date($_POST['InvoiceDate'])) {
293 $_POST['InvoiceDate'] = Today();
294 if (!is_date_in_fiscalyear($_POST['InvoiceDate'])) {
295 $_POST['InvoiceDate'] = end_fiscalyear();
299 date_cells(_("Date"), 'InvoiceDate', $_POST['InvoiceDate'], 0, 0, 0, "class='tableheader'");
301 if (!isset($_POST['due_date']) || !is_date($_POST['due_date'])) {
302 $_POST['due_date'] = get_invoice_duedate($_SESSION['Items']->customer_id, $_POST['InvoiceDate']);
305 date_cells(_("Due Date"), 'due_date', $_POST['due_date'], 0, 0, 0, "class='tableheader'");
310 display_heading(_("Invoice Items"));
312 start_table("$table_style width=80%");
313 $th = array(_("Item Code"), _("Item Description"), _("Delivered"), _("Units"), _("Invoiced"),
314 _("This Invoice"), _("Price"), _("Tax Type"), _("Discount"), _("Total"));
316 if ($is_batch_invoice) {
322 $th[4] = _("Credited");
332 foreach ($_SESSION['Items']->line_items as $line=>$ln_itm) {
333 if ($ln_itm->quantity == $ln_itm->qty_done) {
334 continue; // this line was fully invoiced
336 alt_table_row_color($k);
337 view_stock_status_cell($ln_itm->stock_id);
339 text_cells(null, 'Line'.$line.'Desc', $ln_itm->item_description, 30, 50);
340 qty_cell($ln_itm->quantity);
341 label_cell($ln_itm->units);
342 qty_cell($ln_itm->qty_done);
344 if ($is_batch_invoice) {
345 // for batch invoices we can only remove whole deliveries
346 echo '<td nowrap align=right>';
347 hidden('Line' . $line, $ln_itm->qty_dispatched );
348 echo number_format2($ln_itm->qty_dispatched, user_qty_dec()).'</td>';
350 text_cells(null, 'Line'.$line, $ln_itm->qty_dispatched, 10, 10);
352 $display_discount_percent = number_format2($ln_itm->discount_percent*100, user_percent_dec()) . "%";
354 $line_total = ($ln_itm->qty_dispatched * $ln_itm->price * (1 - $ln_itm->discount_percent));
356 amount_cell($ln_itm->price);
357 label_cell($ln_itm->tax_type_name);
358 label_cell($display_discount_percent, "nowrap align=right");
359 amount_cell($line_total);
361 if ($is_batch_invoice) {
362 if ($dn_line_cnt == 0) {
363 $dn_line_cnt = $dspans[0];
364 $dspans = array_slice($dspans, 1);
365 label_cell($ln_itm->src_no, "rowspan=$dn_line_cnt class=oddrow");
366 label_cell("<a href='" . $_SERVER['PHP_SELF'] . "?RemoveDN=".
367 $ln_itm->src_no."'>" . _("Remove") . "</a>", "rowspan=$dn_line_cnt class=oddrow");
374 /*Don't re-calculate freight if some of the order has already been delivered -
375 depending on the business logic required this condition may not be required.
376 It seems unfair to charge the customer twice for freight if the order
377 was not fully delivered the first time ?? */
379 if (!isset($_POST['ChargeFreightCost']) || $_POST['ChargeFreightCost'] == "") {
380 if ($_SESSION['Items']->any_already_delivered() == 1) {
381 $_POST['ChargeFreightCost'] = 0;
383 $_POST['ChargeFreightCost'] = $_SESSION['Items']->freight_cost;
386 if (!is_numeric($_POST['ChargeFreightCost'])) {
387 $_POST['ChargeFreightCost'] = 0;
393 small_amount_cells(_("Shipping Cost"), 'ChargeFreightCost', null, "colspan=9 align=right");
394 if ($is_batch_invoice) {
395 label_cell('', 'colspan=2');
399 $inv_items_total = $_SESSION['Items']->get_items_total_dispatch();
401 $display_sub_total = number_format2($inv_items_total + $_POST['ChargeFreightCost'],user_price_dec());
403 label_row(_("Sub-total"), $display_sub_total, "colspan=9 align=right","align=right", $is_batch_invoice ? 2 : 0);
405 $taxes = $_SESSION['Items']->get_taxes($_POST['ChargeFreightCost']);
406 $tax_total = display_edit_tax_items($taxes, 9, $_SESSION['Items']->tax_included, $is_batch_invoice ? 2:0);
408 $display_total = number_format2(($inv_items_total + $_POST['ChargeFreightCost'] + $tax_total), user_price_dec());
410 label_row(_("Invoice Total"), $display_total, "colspan=9 align=right","align=right", $is_batch_invoice ? 2 : 0);
414 start_table($table_style2);
416 textarea_row(_("Memo"), 'Comments', null, 50, 4);
420 submit_center_first('Update', _("Update"));
421 submit_center_last('process_invoice', _("Process Invoice"));