Replaced the global variables for table styles to defined CSS classes.
[fa-stable.git] / purchasing / po_receive_items.php
1 <?php
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';
13 $path_to_root = "..";
14 include_once($path_to_root . "/purchasing/includes/po_class.inc");
15
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");
19
20 $js = "";
21 if ($use_popup_windows)
22         $js .= get_js_open_window(900, 500);
23 if ($use_date_picker)
24         $js .= get_js_date_picker();
25 page(_($help_context = "Receive Purchase Order Items"), false, false, "", $js);
26
27 //---------------------------------------------------------------------------------------------------------------
28
29 if (isset($_GET['AddedID']))
30 {
31         $grn = $_GET['AddedID'];
32         $trans_type = ST_SUPPRECEIVE;
33
34         display_notification_centered(_("Purchase Order Delivery has been processed"));
35
36         display_note(get_trans_view_str($trans_type, $grn, _("&View this Delivery")));
37
38         hyperlink_params("$path_to_root/purchasing/supplier_invoice.php", _("Entry purchase &invoice for this receival"), "New=1");
39
40         hyperlink_no_params("$path_to_root/purchasing/inquiry/po_search.php", _("Select a different &purchase order for receiving items against"));
41
42         display_footer_exit();
43 }
44
45 //--------------------------------------------------------------------------------------------------
46
47 if ((!isset($_GET['PONumber']) || $_GET['PONumber'] == 0) && !isset($_SESSION['PO']))
48 {
49         die (_("This page can only be opened if a purchase order has been selected. Please select a purchase order first."));
50 }
51
52 //--------------------------------------------------------------------------------------------------
53
54 function display_po_receive_items()
55 {
56         div_start('grn_items');
57     start_table(TABLESTYLE, "colspan=7 width=90%");
58     $th = array(_("Item Code"), _("Description"), _("Ordered"), _("Units"), _("Received"),
59         _("Outstanding"), _("This Delivery"), _("Price"), _("Total"));
60     table_header($th);
61
62     /*show the line items on the order with the quantity being received for modification */
63
64     $total = 0;
65     $k = 0; //row colour counter
66
67     if (count($_SESSION['PO']->line_items)> 0 )
68     {
69         foreach ($_SESSION['PO']->line_items as $ln_itm)
70         {
71
72                         alt_table_row_color($k);
73
74                 $qty_outstanding = $ln_itm->quantity - $ln_itm->qty_received;
75
76                         if (!isset($_POST['Update']) && !isset($_POST['ProcessGoodsReceived']) && $ln_itm->receive_qty == 0)
77                 {   //If no quantites yet input default the balance to be received
78                 $ln_itm->receive_qty = $qty_outstanding;
79                 }
80
81                 $line_total = ($ln_itm->receive_qty * $ln_itm->price);
82                 $total += $line_total;
83
84                         label_cell($ln_itm->stock_id);
85                         if ($qty_outstanding > 0)
86                                 text_cells(null, $ln_itm->stock_id . "Desc", $ln_itm->item_description, 30, 50);
87                         else
88                                 label_cell($ln_itm->item_description);
89                         $dec = get_qty_dec($ln_itm->stock_id);
90                         qty_cell($ln_itm->quantity, false, $dec);
91                         label_cell($ln_itm->units);
92                         qty_cell($ln_itm->qty_received, false, $dec);
93                         qty_cell($qty_outstanding, false, $dec);
94
95                         if ($qty_outstanding > 0)
96                                 qty_cells(null, $ln_itm->line_no, number_format2($ln_itm->receive_qty, $dec), "align=right", null, $dec);
97                         else
98                                 label_cell(number_format2($ln_itm->receive_qty, $dec), "align=right");
99
100                         amount_decimal_cell($ln_itm->price);
101                         amount_cell($line_total);
102                         end_row();
103         }
104     }
105
106     $display_total = number_format2($total,user_price_dec());
107     label_row(_("Total value of items received"), $display_total, "colspan=8 align=right",
108         "nowrap align=right");
109     end_table();
110         div_end();
111 }
112
113 //--------------------------------------------------------------------------------------------------
114
115 function check_po_changed()
116 {
117         /*Now need to check that the order details are the same as they were when they were read
118         into the Items array. If they've changed then someone else must have altered them */
119         // Sherifoz 22.06.03 Compare against COMPLETED items only !!
120         // Otherwise if you try to fullfill item quantities separately will give error.
121         $result = get_po_items($_SESSION['PO']->order_no);
122
123         $line_no = 1;
124         while ($myrow = db_fetch($result))
125         {
126                 $ln_item = $_SESSION['PO']->line_items[$line_no];
127                 // only compare against items that are outstanding
128                 $qty_outstanding = $ln_item->quantity - $ln_item->qty_received;
129                 if ($qty_outstanding > 0)
130                 {
131                 if ($ln_item->qty_inv != $myrow["qty_invoiced"] ||
132                         $ln_item->stock_id != $myrow["item_code"] ||
133                         $ln_item->quantity != $myrow["quantity_ordered"] ||
134                         $ln_item->qty_received != $myrow["quantity_received"])
135                 {
136                         return true;
137                 }
138                 }
139                 $line_no++;
140         } /*loop through all line items of the order to ensure none have been invoiced */
141
142         return false;
143 }
144
145 //--------------------------------------------------------------------------------------------------
146
147 function can_process()
148 {
149         global $SysPrefs, $Refs;
150         
151         if (count($_SESSION['PO']->line_items) <= 0)
152         {
153         display_error(_("There is nothing to process. Please enter valid quantities greater than zero."));
154         return false;
155         }
156
157         if (!is_date($_POST['DefaultReceivedDate']))
158         {
159                 display_error(_("The entered date is invalid."));
160                 set_focus('DefaultReceivedDate');
161                 return false;
162         }
163
164     if (!$Refs->is_valid($_POST['ref']))
165     {
166                 display_error(_("You must enter a reference."));
167                 set_focus('ref');
168                 return false;
169         }
170
171         if (!is_new_reference($_POST['ref'], ST_SUPPRECEIVE))
172         {
173                 display_error(_("The entered reference is already in use."));
174                 set_focus('ref');
175                 return false;
176         }
177
178         $something_received = 0;
179         foreach ($_SESSION['PO']->line_items as $order_line)
180         {
181                 if ($order_line->receive_qty > 0)
182                 {
183                         $something_received = 1;
184                         break;
185                 }
186         }
187
188     // Check whether trying to deliver more items than are recorded on the actual purchase order (+ overreceive allowance)
189     $delivery_qty_too_large = 0;
190         foreach ($_SESSION['PO']->line_items as $order_line)
191         {
192                 if ($order_line->receive_qty+$order_line->qty_received >
193                         $order_line->quantity * (1+ ($SysPrefs->over_receive_allowance() / 100)))
194                 {
195                         $delivery_qty_too_large = 1;
196                         break;
197                 }
198         }
199
200     if ($something_received == 0)
201     {   /*Then dont bother proceeding cos nothing to do ! */
202         display_error(_("There is nothing to process. Please enter valid quantities greater than zero."));
203         return false;
204     }
205     elseif ($delivery_qty_too_large == 1)
206     {
207         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() ."%)."
208                 . "<br>" .
209                 _("Modify the ordered items on the purchase order if you wish to increase the quantities."));
210         return false;
211     }
212
213         return true;
214 }
215
216 //--------------------------------------------------------------------------------------------------
217
218 function process_receive_po()
219 {
220         global $path_to_root, $Ajax;
221
222         if (!can_process())
223                 return;
224
225         if (check_po_changed())
226         {
227                 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."));
228
229                 hyperlink_no_params("$path_to_root/purchasing/inquiry/po_search.php",
230                  _("Select a different purchase order for receiving goods against"));
231
232                 hyperlink_params("$path_to_root/purchasing/po_receive_items.php", 
233                          _("Re-Read the updated purchase order for receiving goods against"),
234                          "PONumber=" . $_SESSION['PO']->order_no);
235
236                 unset($_SESSION['PO']->line_items);
237                 unset($_SESSION['PO']);
238                 unset($_POST['ProcessGoodsReceived']);
239                 $Ajax->activate('_page_body');
240                 display_footer_exit();
241         }
242         
243         $grn = &$_SESSION['PO'];
244         $grn->orig_order_date = $_POST['DefaultReceivedDate'];
245         $grn->reference = $_POST['ref'];
246         $grn->Location = $_POST['Location'];
247
248         $grn_no = add_grn($grn);
249
250         new_doc_date($_POST['DefaultReceivedDate']);
251         unset($_SESSION['PO']->line_items);
252         unset($_SESSION['PO']);
253
254         meta_forward($_SERVER['PHP_SELF'], "AddedID=$grn_no");
255 }
256
257 //--------------------------------------------------------------------------------------------------
258
259 if (isset($_GET['PONumber']) && $_GET['PONumber'] > 0 && !isset($_POST['Update']))
260 {
261         create_new_po(ST_PURCHORDER, $_GET['PONumber']);
262         $_SESSION['PO']->trans_type = ST_SUPPRECEIVE;
263         $_SESSION['PO']->reference = $Refs->get_next(ST_SUPPRECEIVE);
264         copy_from_cart();
265 }
266
267 //--------------------------------------------------------------------------------------------------
268
269 if (isset($_POST['Update']) || isset($_POST['ProcessGoodsReceived']))
270 {
271
272         /* if update quantities button is hit page has been called and ${$line->line_no} would have be
273         set from the post to the quantity to be received in this receival*/
274         foreach ($_SESSION['PO']->line_items as $line)
275         {
276          if( ($line->quantity - $line->qty_received)>0) {
277                 $_POST[$line->line_no] = max($_POST[$line->line_no], 0);
278                 if (!check_num($line->line_no))
279                         $_POST[$line->line_no] = number_format2(0, get_qty_dec($line->stock_id));
280
281                 if (!isset($_POST['DefaultReceivedDate']) || $_POST['DefaultReceivedDate'] == "")
282                         $_POST['DefaultReceivedDate'] = new_doc_date();
283
284                 $_SESSION['PO']->line_items[$line->line_no]->receive_qty = input_num($line->line_no);
285
286                 if (isset($_POST[$line->stock_id . "Desc"]) && strlen($_POST[$line->stock_id . "Desc"]) > 0)
287                 {
288                         $_SESSION['PO']->line_items[$line->line_no]->item_description = $_POST[$line->stock_id . "Desc"];
289                 }
290          }
291         }
292         $Ajax->activate('grn_items');
293 }
294
295 //--------------------------------------------------------------------------------------------------
296
297 if (isset($_POST['ProcessGoodsReceived']))
298 {
299         process_receive_po();
300 }
301
302 //--------------------------------------------------------------------------------------------------
303
304 start_form();
305
306 display_grn_summary($_SESSION['PO'], true);
307 display_heading(_("Items to Receive"));
308 display_po_receive_items();
309
310 echo '<br>';
311 submit_center_first('Update', _("Update"), '', true);
312 submit_center_last('ProcessGoodsReceived', _("Process Receive Items"), _("Clear all GL entry fields"), 'default');
313
314 end_form();
315
316 //--------------------------------------------------------------------------------------------------
317
318 end_page();
319 ?>
320