Cleanup comments. Small bugfixes. Third run
[fa-stable.git] / purchasing / po_entry_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 $path_to_root = "..";
13 $page_security = 'SA_PURCHASEORDER';
14 include_once($path_to_root . "/purchasing/includes/po_class.inc");
15 include_once($path_to_root . "/includes/session.inc");
16 include_once($path_to_root . "/purchasing/includes/purchasing_ui.inc");
17 include_once($path_to_root . "/purchasing/includes/db/suppliers_db.inc");
18 include_once($path_to_root . "/reporting/includes/reporting.inc");
19
20 set_page_security( @$_SESSION['PO']->trans_type,
21         array(  ST_PURCHORDER => 'SA_PURCHASEORDER',
22                         ST_SUPPRECEIVE => 'SA_GRN',
23                         ST_SUPPINVOICE => 'SA_SUPPLIERINVOICE'),
24         array(  'NewOrder' => 'SA_PURCHASEORDER',
25                         'ModifyOrderNumber' => 'SA_PURCHASEORDER',
26                         'AddedID' => 'SA_PURCHASEORDER',
27                         'NewGRN' => 'SA_GRN',
28                         'AddedGRN' => 'SA_GRN',
29                         'NewInvoice' => 'SA_SUPPLIERINVOICE',
30                         'AddedPI' => 'SA_SUPPLIERINVOICE')
31 );
32
33 $js = '';
34 if ($SysPrefs->use_popup_windows)
35         $js .= get_js_open_window(900, 500);
36 if (user_use_date_picker())
37         $js .= get_js_date_picker();
38
39 if (isset($_GET['ModifyOrderNumber']) && is_numeric($_GET['ModifyOrderNumber'])) {
40
41         $_SESSION['page_title'] = _($help_context = "Modify Purchase Order #") . $_GET['ModifyOrderNumber'];
42         create_new_po(ST_PURCHORDER, $_GET['ModifyOrderNumber']);
43         copy_from_cart();
44 } elseif (isset($_GET['NewOrder'])) {
45
46         $_SESSION['page_title'] = _($help_context = "Purchase Order Entry");
47         create_new_po(ST_PURCHORDER, 0);
48         copy_from_cart();
49 } elseif (isset($_GET['NewGRN'])) {
50
51         $_SESSION['page_title'] = _($help_context = "Direct GRN Entry");
52         create_new_po(ST_SUPPRECEIVE, 0);
53         copy_from_cart();
54 } elseif (isset($_GET['NewInvoice'])) {
55
56         $_SESSION['page_title'] = _($help_context = "Direct Purchase Invoice Entry");
57         create_new_po(ST_SUPPINVOICE, 0);
58         copy_from_cart();
59 }
60
61 page($_SESSION['page_title'], false, false, "", $js);
62
63 if (isset($_GET['ModifyOrderNumber']))
64         check_is_editable(ST_PURCHORDER, $_GET['ModifyOrderNumber']);
65
66 //---------------------------------------------------------------------------------------------------
67
68 check_db_has_suppliers(_("There are no suppliers defined in the system."));
69
70 check_db_has_purchasable_items(_("There are no purchasable inventory items defined in the system."));
71
72 //---------------------------------------------------------------------------------------------------------------
73
74 if (isset($_GET['AddedID'])) 
75 {
76         $order_no = $_GET['AddedID'];
77         $trans_type = ST_PURCHORDER;    
78
79         if (!isset($_GET['Updated']))
80                 display_notification_centered(_("Purchase Order has been entered"));
81         else
82                 display_notification_centered(_("Purchase Order has been updated") . " #$order_no");
83         display_note(get_trans_view_str($trans_type, $order_no, _("&View this order")), 0, 1);
84
85         display_note(print_document_link($order_no, _("&Print This Order"), true, $trans_type), 0, 1);
86
87         display_note(print_document_link($order_no, _("&Email This Order"), true, $trans_type, false, "printlink", "", 1));
88
89         hyperlink_params($path_to_root . "/purchasing/po_receive_items.php", _("&Receive Items on this Purchase Order"), "PONumber=$order_no");
90
91         hyperlink_params($_SERVER['PHP_SELF'], _("Enter &Another Purchase Order"), "NewOrder=yes");
92         
93         hyperlink_no_params($path_to_root."/purchasing/inquiry/po_search.php", _("Select An &Outstanding Purchase Order"));
94         
95         display_footer_exit();  
96
97 } elseif (isset($_GET['AddedGRN'])) {
98
99         $trans_no = $_GET['AddedGRN'];
100         $trans_type = ST_SUPPRECEIVE;
101
102         display_notification_centered(_("Direct GRN has been entered"));
103
104         display_note(get_trans_view_str($trans_type, $trans_no, _("&View this GRN")), 0);
105
106     $clearing_act = get_company_pref('grn_clearing_act');
107         if ($clearing_act)      
108                 display_note(get_gl_view_str($trans_type, $trans_no, _("View the GL Journal Entries for this Delivery")), 1);
109
110         hyperlink_params("$path_to_root/purchasing/supplier_invoice.php",
111                 _("Entry purchase &invoice for this receival"), "New=1");
112
113         hyperlink_params("$path_to_root/admin/attachments.php", _("Add an Attachment"), 
114                 "filterType=$trans_type&trans_no=$trans_no");
115
116         hyperlink_params($_SERVER['PHP_SELF'], _("Enter &Another GRN"), "NewGRN=Yes");
117         
118         display_footer_exit();  
119
120 } elseif (isset($_GET['AddedPI'])) {
121
122         $trans_no = $_GET['AddedPI'];
123         $trans_type = ST_SUPPINVOICE;
124
125         display_notification_centered(_("Direct Purchase Invoice has been entered"));
126
127         display_note(get_trans_view_str($trans_type, $trans_no, _("&View this Invoice")), 0);
128
129         display_note(get_gl_view_str($trans_type, $trans_no, _("View the GL Journal Entries for this Invoice")), 1);
130
131         hyperlink_params("$path_to_root/purchasing/supplier_payment.php", _("Entry supplier &payment for this invoice"),
132                 "trans_type=$trans_type&PInvoice=".$trans_no);
133
134         hyperlink_params("$path_to_root/admin/attachments.php", _("Add an Attachment"), 
135                 "filterType=$trans_type&trans_no=$trans_no");
136
137         hyperlink_params($_SERVER['PHP_SELF'], _("Enter &Another Direct Invoice"), "NewInvoice=Yes");
138         
139         display_footer_exit();  
140 }
141 //--------------------------------------------------------------------------------------------------
142
143 function line_start_focus() {
144   global        $Ajax;
145
146   $Ajax->activate('items_table');
147   set_focus('_stock_id_edit');
148 }
149 //--------------------------------------------------------------------------------------------------
150
151 function unset_form_variables() {
152         unset($_POST['stock_id']);
153     unset($_POST['qty']);
154     unset($_POST['price']);
155     unset($_POST['req_del_date']);
156 }
157
158 //---------------------------------------------------------------------------------------------------
159
160 function handle_delete_item($line_no)
161 {
162         if($_SESSION['PO']->some_already_received($line_no) == 0)
163         {
164                 $_SESSION['PO']->remove_from_order($line_no);
165                 unset_form_variables();
166         } 
167         else 
168         {
169                 display_error(_("This item cannot be deleted because some of it has already been received."));
170         }       
171     line_start_focus();
172 }
173
174 //---------------------------------------------------------------------------------------------------
175
176 function handle_cancel_po()
177 {
178         global $path_to_root;
179         
180         //need to check that not already dispatched or invoiced by the supplier
181         if(($_SESSION['PO']->order_no != 0) && 
182                 $_SESSION['PO']->any_already_received() == 1)
183         {
184                 display_error(_("This order cannot be cancelled because some of it has already been received.") 
185                         . "<br>" . _("The line item quantities may be modified to quantities more than already received. prices cannot be altered for lines that have already been received and quantities cannot be reduced below the quantity already received."));
186                 return;
187         }
188         
189         if($_SESSION['PO']->order_no != 0)
190         {
191                 delete_po($_SESSION['PO']->order_no);
192         } else {
193                 unset($_SESSION['PO']);
194                 meta_forward($path_to_root.'/index.php','application=AP');
195         }
196
197         $_SESSION['PO']->clear_items();
198         $_SESSION['PO'] = new purch_order;
199
200         display_notification(_("This purchase order has been cancelled."));
201
202         hyperlink_params($path_to_root . "/purchasing/po_entry_items.php", _("Enter a new purchase order"), "NewOrder=Yes");
203         echo "<br>";
204
205         end_page();
206         exit;
207 }
208
209 //---------------------------------------------------------------------------------------------------
210
211 function check_data()
212 {
213         if(!get_post('stock_id_text', true)) {
214                 display_error( _("Item description cannot be empty."));
215                 set_focus('stock_id_edit');
216                 return false;
217         }
218
219         $dec = get_qty_dec($_POST['stock_id']);
220         $min = 1 / pow(10, $dec);
221     if (!check_num('qty',$min))
222     {
223         $min = number_format2($min, $dec);
224                 display_error(_("The quantity of the order item must be numeric and not less than ").$min);
225                 set_focus('qty');
226                 return false;
227     }
228
229     if (!check_num('price', 0))
230     {
231                 display_error(_("The price entered must be numeric and not less than zero."));
232                 set_focus('price');
233                 return false;      
234     }
235     if ($_SESSION['PO']->trans_type == ST_PURCHORDER && !is_date($_POST['req_del_date'])){
236                 display_error(_("The date entered is in an invalid format."));
237                 set_focus('req_del_date');
238                 return false;            
239     }
240      
241     return true;        
242 }
243
244 //---------------------------------------------------------------------------------------------------
245
246 function handle_update_item()
247 {
248         $allow_update = check_data(); 
249
250         if ($allow_update)
251         {
252                 if ($_SESSION['PO']->line_items[$_POST['line_no']]->qty_inv > input_num('qty') ||
253                         $_SESSION['PO']->line_items[$_POST['line_no']]->qty_received > input_num('qty'))
254                 {
255                         display_error(_("You are attempting to make the quantity ordered a quantity less than has already been invoiced or received.  This is prohibited.") .
256                                 "<br>" . _("The quantity received can only be modified by entering a negative receipt and the quantity invoiced can only be reduced by entering a credit note against this item."));
257                         set_focus('qty');
258                         return;
259                 }
260         
261                 $_SESSION['PO']->update_order_item($_POST['line_no'], input_num('qty'), input_num('price'),
262                         @$_POST['req_del_date'], $_POST['item_description'] );
263                 unset_form_variables();
264         }       
265     line_start_focus();
266 }
267
268 //---------------------------------------------------------------------------------------------------
269
270 function handle_add_new_item()
271 {
272         $allow_update = check_data();
273         
274         if ($allow_update == true)
275         { 
276                 if (count($_SESSION['PO']->line_items) > 0)
277                 {
278                     foreach ($_SESSION['PO']->line_items as $order_item) 
279                     {
280                         /* do a loop round the items on the order to see that the item
281                         is not already on this order */
282                             if (($order_item->stock_id == $_POST['stock_id'])) 
283                             {
284                                         display_warning(_("The selected item is already on this order."));
285                             }
286                     } /* end of the foreach loop to look for pre-existing items of the same code */
287                 }
288
289                 if ($allow_update == true)
290                 {
291                         $result = get_short_info($_POST['stock_id']);
292
293                         if (db_num_rows($result) == 0)
294                         {
295                                 $allow_update = false;
296                         }
297
298                         if ($allow_update)
299                         {
300                                 $_SESSION['PO']->add_to_order (count($_SESSION['PO']->line_items), $_POST['stock_id'], input_num('qty'), 
301                                         get_post('stock_id_text'), //$myrow["description"], 
302                                         input_num('price'), '', // $myrow["units"], (retrived in cart)
303                                         $_SESSION['PO']->trans_type == ST_PURCHORDER ? $_POST['req_del_date'] : '', 0, 0);
304
305                                 unset_form_variables();
306                                 $_POST['stock_id']      = "";
307                         } 
308                         else 
309                         {
310                              display_error(_("The selected item does not exist or it is a kit part and therefore cannot be purchased."));
311                         }
312
313                 } /* end of if not already on the order and allow input was true*/
314     }
315         line_start_focus();
316 }
317
318 //---------------------------------------------------------------------------------------------------
319
320 function can_commit()
321 {
322         if (!get_post('supplier_id')) 
323         {
324                 display_error(_("There is no supplier selected."));
325                 set_focus('supplier_id');
326                 return false;
327         } 
328
329         if (!is_date($_POST['OrderDate'])) 
330         {
331                 display_error(_("The entered order date is invalid."));
332                 set_focus('OrderDate');
333                 return false;
334         } 
335         if (($_SESSION['PO']->trans_type == ST_SUPPRECEIVE || $_SESSION['PO']->trans_type == ST_SUPPINVOICE) 
336                 && !is_date_in_fiscalyear($_POST['OrderDate'])) {
337                 display_error(_("The entered date is out of fiscal year or is closed for further data entry."));
338                 set_focus('OrderDate');
339                 return false;
340         }
341
342         if (($_SESSION['PO']->trans_type==ST_SUPPINVOICE) && !is_date($_POST['due_date'])) 
343         {
344                 display_error(_("The entered due date is invalid."));
345                 set_focus('due_date');
346                 return false;
347         } 
348
349         if (!$_SESSION['PO']->order_no) 
350         {
351         if (!check_reference(get_post('ref'), $_SESSION['PO']->trans_type))
352         {
353                 _vd("bad reference");
354                 exit;
355                         set_focus('ref');
356                 return false;
357         }
358         }
359
360         if ($_SESSION['PO']->trans_type == ST_SUPPINVOICE && trim(get_post('supp_ref')) == false)
361         {
362                 display_error(_("You must enter a supplier's invoice reference."));
363                 set_focus('supp_ref');
364                 return false;
365         }
366         if ($_SESSION['PO']->trans_type==ST_SUPPINVOICE 
367                 && is_reference_already_there($_SESSION['PO']->supplier_id, get_post('supp_ref'), $_SESSION['PO']->order_no))
368         {
369                 display_error(_("This invoice number has already been entered. It cannot be entered again.") . " (" . get_post('supp_ref') . ")");
370                 set_focus('supp_ref');
371                 return false;
372         }
373         if ($_SESSION['PO']->trans_type == ST_PURCHORDER && get_post('delivery_address') == '')
374         {
375                 display_error(_("There is no delivery address specified."));
376                 set_focus('delivery_address');
377                 return false;
378         } 
379         if (get_post('StkLocation') == '')
380         {
381                 display_error(_("There is no location specified to move any items into."));
382                 set_focus('StkLocation');
383                 return false;
384         } 
385         if (!db_has_currency_rates($_SESSION['PO']->curr_code, $_POST['OrderDate'], true))
386                 return false;
387         if ($_SESSION['PO']->order_has_items() == false)
388         {
389         display_error (_("The order cannot be placed because there are no lines entered on this order."));
390         return false;
391         }
392         if (floatcmp(input_num('prep_amount'), $_SESSION['PO']->get_trans_total()) > 0)
393         {
394                 display_error(_("Required prepayment is greater than total invoice value."));
395                 set_focus('prep_amount');
396                 return false;
397         }
398
399         return true;
400 }
401
402 function handle_commit_order()
403 {
404         $cart = &$_SESSION['PO'];
405
406         if (can_commit()) {
407
408                 copy_to_cart();
409                 new_doc_date($cart->orig_order_date);
410                 if ($cart->order_no == 0) { // new po/grn/invoice
411                         $trans_no = add_direct_supp_trans($cart);
412                         if ($trans_no) {
413                                 unset($_SESSION['PO']);
414                                 if ($cart->trans_type == ST_PURCHORDER)
415                                         meta_forward($_SERVER['PHP_SELF'], "AddedID=$trans_no");
416                                 elseif ($cart->trans_type == ST_SUPPRECEIVE)
417                                         meta_forward($_SERVER['PHP_SELF'], "AddedGRN=$trans_no");
418                                 else
419                                         meta_forward($_SERVER['PHP_SELF'], "AddedPI=$trans_no");
420                         }
421                 } else { // order modification
422                         $order_no = update_po($cart);
423                         unset($_SESSION['PO']);
424                 meta_forward($_SERVER['PHP_SELF'], "AddedID=$order_no&Updated=1");      
425                 }
426         }
427 }
428 //---------------------------------------------------------------------------------------------------
429 if (isset($_POST['update'])) {
430         copy_to_cart();
431         $Ajax->activate('items_table');
432 }
433
434 $id = find_submit('Delete');
435 if ($id != -1)
436         handle_delete_item($id);
437
438 if (isset($_POST['Commit']))
439 {
440         handle_commit_order();
441 }
442 if (isset($_POST['UpdateLine']))
443         handle_update_item();
444
445 if (isset($_POST['EnterLine']))
446         handle_add_new_item();
447
448 if (isset($_POST['CancelOrder'])) 
449         handle_cancel_po();
450
451 if (isset($_POST['CancelUpdate']))
452         unset_form_variables();
453
454 if (isset($_POST['CancelUpdate']) || isset($_POST['UpdateLine'])) {
455         line_start_focus();
456 }
457
458 //---------------------------------------------------------------------------------------------------
459
460 start_form();
461
462 display_po_header($_SESSION['PO']);
463 echo "<br>";
464
465 display_po_items($_SESSION['PO']);
466
467 start_table(TABLESTYLE2);
468
469
470 if ($_SESSION['PO']->trans_type == ST_SUPPINVOICE) {
471         cash_accounts_list_row(_("Payment:"), 'cash_account', null, false, _('Delayed'));
472 }
473
474 textarea_row(_("Memo:"), 'Comments', null, 70, 4);
475
476 end_table(1);
477
478 div_start('controls', 'items_table');
479 $process_txt = _("Place Order");
480 $update_txt = _("Update Order");
481 $cancel_txt = _("Cancel Order");
482 if ($_SESSION['PO']->trans_type == ST_SUPPRECEIVE) {
483         $process_txt = _("Process GRN");
484         $update_txt = _("Update GRN");
485         $cancel_txt = _("Cancel GRN");
486 }       
487 elseif ($_SESSION['PO']->trans_type == ST_SUPPINVOICE) {
488         $process_txt = _("Process Invoice");
489         $update_txt = _("Update Invoice");
490         $cancel_txt = _("Cancel Invoice");
491 }       
492 if ($_SESSION['PO']->order_has_items()) 
493 {
494         if ($_SESSION['PO']->order_no)
495                 submit_center_first('Commit', $update_txt, '', 'default');
496         else
497                 submit_center_first('Commit', $process_txt, '', 'default');
498         submit_center_last('CancelOrder', $cancel_txt);         
499 }
500 else
501         submit_center('CancelOrder', $cancel_txt, true, false, 'cancel');
502 div_end();
503 //---------------------------------------------------------------------------------------------------
504
505 end_form();
506 end_page();