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 $page_security = 'SA_GRN';
14 include_once($path_to_root . "/purchasing/includes/po_class.inc");
16 include_once($path_to_root . "/includes/session.inc");
17 include_once($path_to_root . "/purchasing/includes/purchasing_db.inc");
18 include_once($path_to_root . "/purchasing/includes/purchasing_ui.inc");
21 if ($SysPrefs->use_popup_windows)
22 $js .= get_js_open_window(900, 500);
23 if (user_use_date_picker())
24 $js .= get_js_date_picker();
26 //--------------------------------------------------------------------------------------------------
28 if (isset($_GET['PONumber']) && $_GET['PONumber'] > 0 && !isset($_POST['Update']))
30 $_SESSION['page_title'] = _($help_context = "Receive Purchase Order Items");
31 create_cart(ST_PURCHORDER, $_GET['PONumber']);
32 $_SESSION['PO']->trans_type = ST_SUPPRECEIVE;
33 $_SESSION['PO']->reference = $Refs->get_next(ST_SUPPRECEIVE,
34 array('date' => Today(), 'supplier' => $_SESSION['PO']->supplier_id));
35 foreach ($_SESSION['PO']->line_items as $line)
36 $line->quantity = $line->qty_ordered - $line->qty_received;
39 elseif (isset($_GET['ModifyGRN']) && $_GET['ModifyGRN'] > 0 && !isset($_POST['Update']))
41 $_SESSION['page_title'] = _($help_context = "Modify GRN #") . $_GET['ModifyGRN'];
42 create_cart(ST_SUPPRECEIVE, $_GET['ModifyGRN']);
46 page($_SESSION['page_title'], false, false, "", $js);
48 //---------------------------------------------------------------------------------------------------------------
50 if (isset($_GET['AddedID']) || isset($_GET['UpdatedID']))
52 $new = isset($_GET['AddedID']);
53 $grn = $_GET[$new ? 'AddedID' : 'UpdatedID'];
54 $trans_type = ST_SUPPRECEIVE;
56 display_notification_centered(_("Purchase Order Delivery has been processed"));
58 display_note(get_trans_view_str($trans_type, $grn, _("&View this Delivery")));
60 $clearing_act = get_company_pref('grn_clearing_act');
62 display_note(get_gl_view_str($trans_type, $grn, _("View the GL Journal Entries for this Delivery")), 1);
64 hyperlink_params("$path_to_root/purchasing/supplier_invoice.php", _("Entry purchase &invoice for this receival"), "New=1");
67 hyperlink_no_params("$path_to_root/purchasing/inquiry/po_search.php", _("Select another &purchase order for receiving items against"));
69 hyperlink_no_params("$path_to_root/purchasing/inquiry/supplier_inquiry.php", _("Select another &document for edition"));
71 display_footer_exit();
74 //--------------------------------------------------------------------------------------------------
76 if ((!isset($_GET['PONumber']) || $_GET['PONumber'] == 0) && (!isset($_GET['ModifyGRN']) || $_GET['ModifyGRN'] == 0) && !isset($_SESSION['PO']))
78 die (_("This page can only be opened with valid Purchase Order or GRN number."));
81 //--------------------------------------------------------------------------------------------------
83 function display_po_receive_items()
85 div_start('grn_items');
86 start_table(TABLESTYLE, "colspan=7 width='90%'");
87 $mod_grn = $_SESSION['PO']->grn_id;
89 if ($mod_grn) // modify GRN
90 $th = array(_("Item Code"), _("Description"), _("Ordered"), _("Units"), _("Received"), _("Invoiced"), _("This Delivery"), _("Price"), _("Total"));
92 $th = array(_("Item Code"), _("Description"), _("Ordered"), _("Units"), _("Received"), _("Outstanding"), _("This Delivery"), _("Price"), _("Total"));
95 /* show the line items on the order with the quantity being received for modification */
98 $k = 0; //row colour counter
100 if (count($_SESSION['PO']->line_items) > 0 )
102 foreach ($_SESSION['PO']->line_items as $line_no => $ln_itm)
105 alt_table_row_color($k);
107 $qty_outstanding = $ln_itm->qty_ordered - $ln_itm->qty_received;
109 if (!isset($_POST['Update']) && !isset($_POST['ProcessGoodsReceived']) && $ln_itm->quantity == 0)
110 { //If no quantites yet input default the balance to be received
111 $ln_itm->quantity = $qty_outstanding;
114 $line_total = ($ln_itm->quantity * $ln_itm->price);
115 $total += $line_total;
117 label_cell($ln_itm->stock_id);
118 if ($mod_grn || $qty_outstanding > 0)
119 text_cells(null, $ln_itm->stock_id . "Desc", $ln_itm->item_description, 30, 50);
121 label_cell($ln_itm->item_description);
123 $dec = get_qty_dec($ln_itm->stock_id);
124 qty_cell($ln_itm->qty_ordered, false, $dec);
125 label_cell($ln_itm->units);
126 qty_cell($ln_itm->qty_received, false, $dec);
128 qty_cell($ln_itm->qty_inv, false, $dec);
130 qty_cell($qty_outstanding, false, $dec);
132 if ($mod_grn || $qty_outstanding > 0)
133 qty_cells(null, $line_no, number_format2($ln_itm->quantity, $dec), "align=right", null, $dec);
135 label_cell(number_format2($ln_itm->quantity, $dec), "align=right");
137 amount_decimal_cell($ln_itm->price);
138 amount_cell($line_total);
143 $colspan = count($th)-1;
145 $display_sub_total = price_format($total);
147 label_row(_("Sub-total"), $display_sub_total, "colspan=$colspan align=right","align=right");
148 $taxes = $_SESSION['PO']->get_taxes();
150 $tax_total = display_edit_tax_items($taxes, $colspan, $_SESSION['PO']->tax_included);
152 $display_total = price_format(($total + $tax_total));
155 label_cells(_("Amount Total"), $display_total, "colspan=$colspan align='right'","align='right'");
161 //--------------------------------------------------------------------------------------------------
163 function check_po_changed()
165 /*Now need to check that the order details are the same as they were when they were read
166 into the Items array. If they've changed then someone else must have altered them */
167 // Compare against COMPLETED items only !!
168 // Otherwise if you try to fullfill item quantities separately will give error.
169 $result = get_po_items($_SESSION['PO']->order_no);
172 while ($myrow = db_fetch($result))
174 $ln_item = $_SESSION['PO']->line_items[$line_no];
175 // only compare against items that are outstanding
176 $qty_outstanding = $ln_item->qty_ordered - $ln_item->qty_received;
177 if ($qty_outstanding > 0)
179 if ($ln_item->qty_inv != $myrow["qty_invoiced"] ||
180 $ln_item->stock_id != $myrow["item_code"] ||
181 $ln_item->qty_ordered != $myrow["quantity_ordered"] ||
182 $ln_item->qty_received + @$ln_item->qty_old != $myrow["quantity_received"])
188 } /*loop through all line items of the order to ensure none have been invoiced */
193 //--------------------------------------------------------------------------------------------------
195 function can_process()
199 if (count($_SESSION['PO']->line_items) <= 0)
201 display_error(_("There is nothing to process. Please enter valid quantities greater than zero."));
205 if (!is_date($_POST['tran_date']))
207 display_error(_("The entered date is invalid."));
208 set_focus('tran_date');
211 if (!is_date_in_fiscalyear($_POST['tran_date'])) {
212 display_error(_("The entered date is out of fiscal year or is closed for further data entry."));
213 set_focus('tran_date');
217 if (!check_reference($_POST['ref'], ST_SUPPRECEIVE, $_SESSION['PO']->grn_id))
223 $something_received = 0;
224 foreach ($_SESSION['PO']->line_items as $order_line)
226 if ($order_line->quantity > 0)
228 $something_received = 1;
233 // Check whether trying to deliver more items than are recorded on the actual purchase order (+ overreceive allowance)
234 $delivery_qty_too_large = 0;
235 foreach ($_SESSION['PO']->line_items as $order_line)
237 if ($order_line->quantity+$order_line->qty_received >
238 $order_line->qty_ordered * (1+ ($SysPrefs->over_receive_allowance() / 100)))
240 $delivery_qty_too_large = 1;
245 if ($something_received == 0)
246 { /*Then dont bother proceeding cos nothing to do ! */
247 display_error(_("There is nothing to process. Please enter valid quantities greater than zero."));
250 elseif ($delivery_qty_too_large == 1)
252 display_error(_("Entered quantities cannot be greater than the quantity entered on the purchase order including the allowed over-receive percentage") . " (" . $SysPrefs->over_receive_allowance() ."%)."
254 _("Modify the ordered items on the purchase order if you wish to increase the quantities."));
261 //--------------------------------------------------------------------------------------------------
263 function process_receive_po()
265 global $path_to_root, $Ajax;
270 if (check_po_changed())
272 display_error(_("This order has been changed or invoiced since this delivery was started to be actioned. Processing halted. To enter a delivery against this purchase order, it must be re-selected and re-read again to update the changes made by the other user."));
274 hyperlink_no_params("$path_to_root/purchasing/inquiry/po_search.php",
275 _("Select a different purchase order for receiving goods against"));
277 if (!$_SESSION['PO']->grn_id)
278 hyperlink_params("$path_to_root/purchasing/po_receive_items.php",
279 _("Re-Read the updated purchase order for receiving goods against"),
280 "PONumber=" . $_SESSION['PO']->order_no);
282 hyperlink_params("$path_to_root/purchasing/po_receive_items.php",
283 _("Re-Read the GRN for reedition"),
284 "ModifyGRN=" . $_SESSION['PO']->grn_id);
286 unset($_SESSION['PO']->line_items);
287 unset($_SESSION['PO']);
288 unset($_POST['ProcessGoodsReceived']);
289 $Ajax->activate('_page_body');
290 display_footer_exit();
293 $grn = &$_SESSION['PO'];
294 $grn->tran_date = $_POST['tran_date'];
295 $grn->reference = $_POST['ref'];
296 $grn->Location = $_POST['Location'];
297 $grn->ex_rate = input_num('_ex_rate', null);
299 $trans_no = write_grn($grn);
300 $new = $grn->grn_id == 0;
302 new_doc_date($_POST['tran_date']);
303 unset($_SESSION['PO']->line_items);
304 unset($_SESSION['PO']);
307 meta_forward($_SERVER['PHP_SELF'], "AddedID=$trans_no");
309 meta_forward($_SERVER['PHP_SELF'], "UpdatedID=$trans_no");
312 //--------------------------------------------------------------------------------------------------
314 if (isset($_POST['Update']) || isset($_POST['ProcessGoodsReceived']))
316 /* if update quantities button is hit page has been called and ${$line_no} would have be
317 set from the post to the quantity to be received in this receival*/
318 foreach ($_SESSION['PO']->line_items as $line_no => $line)
320 if( ($line->qty_ordered - $line->qty_received) > 0) {
321 $_POST[$line_no] = max($_POST[$line_no], 0);
322 if (!check_num($line_no))
323 $_POST[$line_no] = number_format2(0, get_qty_dec($line->stock_id));
325 if (!isset($_POST['tran_date']) || $_POST['tran_date'] == "")
326 $_POST['tran_date'] = new_doc_date();
328 $_SESSION['PO']->line_items[$line_no]->quantity = input_num($line_no);
330 if (isset($_POST[$line->stock_id . "Desc"]) && strlen($_POST[$line->stock_id . "Desc"]) > 0)
332 $_SESSION['PO']->line_items[$line_no]->item_description = $_POST[$line->stock_id . "Desc"];
336 $Ajax->activate('grn_items');
339 //--------------------------------------------------------------------------------------------------
341 if (isset($_POST['ProcessGoodsReceived']))
343 process_receive_po();
346 //--------------------------------------------------------------------------------------------------
350 edit_grn_summary($_SESSION['PO'], true);
351 display_heading(_("Items to Receive"));
352 display_po_receive_items();
355 submit_center_first('Update', _("Update"), '', true);
356 submit_center_last('ProcessGoodsReceived', _("Process Receive Items"), _("Clear all GL entry fields"), 'default');
360 //--------------------------------------------------------------------------------------------------