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