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_ITEM';
13 $path_to_root = "../..";
14 include($path_to_root . "/includes/session.inc");
16 if ($use_popup_windows)
17 $js .= get_js_open_window(900, 500);
19 $js .= get_js_date_picker();
21 page(_($help_context = "Items"), @$_REQUEST['popup'], false, "", $js);
23 include_once($path_to_root . "/includes/date_functions.inc");
24 include_once($path_to_root . "/includes/ui.inc");
25 include_once($path_to_root . "/includes/data_checks.inc");
27 include_once($path_to_root . "/inventory/includes/inventory_db.inc");
29 $user_comp = user_company();
30 $new_item = get_post('stock_id')=='' || get_post('cancel') || get_post('clone');
31 //------------------------------------------------------------------------------------
33 if (isset($_GET['stock_id']))
35 $_POST['stock_id'] = $_GET['stock_id'];
37 $stock_id = get_post('stock_id');
38 if (list_updated('stock_id')) {
39 $_POST['NewStockID'] = $stock_id = get_post('stock_id');
41 $Ajax->activate('details');
42 $Ajax->activate('controls');
45 if (get_post('cancel')) {
46 $_POST['NewStockID'] = $stock_id = $_POST['stock_id'] = '';
48 set_focus('stock_id');
49 $Ajax->activate('_page_body');
51 if (list_updated('category_id') || list_updated('mb_flag')) {
52 $Ajax->activate('details');
55 if (isset($_FILES['pic']) && $_FILES['pic']['name'] != '')
57 $stock_id = $_POST['NewStockID'];
58 $result = $_FILES['pic']['error'];
59 $upload_file = 'Yes'; //Assume all is well to start off with
60 $filename = company_path().'/images';
61 if (!file_exists($filename))
65 $filename .= "/".item_img_name($stock_id).".jpg";
67 //But check for the worst
68 if ((list($width, $height, $type, $attr) = getimagesize($_FILES['pic']['tmp_name'])) !== false)
72 //$imagetype = exif_imagetype($_FILES['pic']['tmp_name']);
73 if ($imagetype != IMAGETYPE_GIF && $imagetype != IMAGETYPE_JPEG && $imagetype != IMAGETYPE_PNG)
75 display_warning( _('Only graphics files can be uploaded'));
78 elseif (!in_array(strtoupper(substr(trim($_FILES['pic']['name']), strlen($_FILES['pic']['name']) - 3)), array('JPG','PNG','GIF')))
80 display_warning(_('Only graphics files are supported - a file extension of .jpg, .png or .gif is expected'));
83 elseif ( $_FILES['pic']['size'] > ($max_image_size * 1024))
85 display_warning(_('The file size is over the maximum allowed. The maximum size allowed in KB is') . ' ' . $max_image_size);
88 elseif (file_exists($filename))
90 $result = unlink($filename);
93 display_error(_('The existing image could not be removed'));
98 if ($upload_file == 'Yes')
100 $result = move_uploaded_file($_FILES['pic']['tmp_name'], $filename);
102 $Ajax->activate('details');
103 /* EOF Add Image upload for New Item - by Ori */
106 check_db_has_stock_categories(_("There are no item categories defined in the system. At least one item category is required to add a item."));
108 check_db_has_item_tax_types(_("There are no item tax types defined in the system. At least one item tax type is required to add a item."));
110 function clear_data()
112 unset($_POST['long_description']);
113 unset($_POST['description']);
114 unset($_POST['category_id']);
115 unset($_POST['tax_type_id']);
116 unset($_POST['units']);
117 unset($_POST['mb_flag']);
118 unset($_POST['NewStockID']);
119 unset($_POST['dimension_id']);
120 unset($_POST['dimension2_id']);
121 unset($_POST['no_sale']);
124 //------------------------------------------------------------------------------------
126 if (isset($_POST['addupdate']))
130 if ($upload_file == 'No')
132 if (strlen($_POST['description']) == 0)
135 display_error( _('The item name must be entered.'));
136 set_focus('description');
138 elseif (strlen($_POST['NewStockID']) == 0)
141 display_error( _('The item code cannot be empty'));
142 set_focus('NewStockID');
144 elseif (strstr($_POST['NewStockID'], " ") || strstr($_POST['NewStockID'],"'") ||
145 strstr($_POST['NewStockID'], "+") || strstr($_POST['NewStockID'], "\"") ||
146 strstr($_POST['NewStockID'], "&") || strstr($_POST['NewStockID'], "\t"))
149 display_error( _('The item code cannot contain any of the following characters - & + OR a space OR quotes'));
150 set_focus('NewStockID');
153 elseif ($new_item && db_num_rows(get_item_kit($_POST['NewStockID'])))
156 display_error( _("This item code is already assigned to stock item or sale kit."));
157 set_focus('NewStockID');
160 if ($input_error != 1)
162 if (check_value('del_image'))
164 $filename = company_path().'/images/'.item_img_name($_POST['NewStockID']).".jpg";
165 if (file_exists($filename))
170 { /*so its an existing one */
171 update_item($_POST['NewStockID'], $_POST['description'],
172 $_POST['long_description'], $_POST['category_id'],
173 $_POST['tax_type_id'], get_post('units'),
174 get_post('mb_flag'), $_POST['sales_account'],
175 $_POST['inventory_account'], $_POST['cogs_account'],
176 $_POST['adjustment_account'], $_POST['assembly_account'],
177 $_POST['dimension_id'], $_POST['dimension2_id'],
178 check_value('no_sale'), check_value('editable'));
179 update_record_status($_POST['NewStockID'], $_POST['inactive'],
180 'stock_master', 'stock_id');
181 update_record_status($_POST['NewStockID'], $_POST['inactive'],
182 'item_codes', 'item_code');
183 set_focus('stock_id');
184 $Ajax->activate('stock_id'); // in case of status change
185 display_notification(_("Item has been updated."));
190 add_item($_POST['NewStockID'], $_POST['description'],
191 $_POST['long_description'], $_POST['category_id'], $_POST['tax_type_id'],
192 $_POST['units'], $_POST['mb_flag'], $_POST['sales_account'],
193 $_POST['inventory_account'], $_POST['cogs_account'],
194 $_POST['adjustment_account'], $_POST['assembly_account'],
195 $_POST['dimension_id'], $_POST['dimension2_id'],
196 check_value('no_sale'), check_value('editable'));
198 display_notification(_("A new item has been added."));
199 $_POST['stock_id'] = $_POST['NewStockID'] =
200 $_POST['description'] = $_POST['long_description'] = '';
201 $_POST['no_sale'] = $_POST['editable'] = 0;
202 set_focus('NewStockID');
204 $Ajax->activate('_page_body');
208 if (get_post('clone')) {
209 unset($_POST['stock_id']);
211 unset($_POST['inactive']);
212 set_focus('NewStockID');
213 $Ajax->activate('_page_body');
216 //------------------------------------------------------------------------------------
218 function check_usage($stock_id, $dispmsg=true)
220 $msg = item_in_foreign_codes($stock_id);
223 if($dispmsg) display_error($msg);
229 //------------------------------------------------------------------------------------
231 if (isset($_POST['delete']) && strlen($_POST['delete']) > 1)
234 if (check_usage($_POST['NewStockID'])) {
236 $stock_id = $_POST['NewStockID'];
237 delete_item($stock_id);
238 $filename = company_path().'/images/'.item_img_name($stock_id).".jpg";
239 if (file_exists($filename))
241 display_notification(_("Selected item has been deleted."));
242 $_POST['stock_id'] = '';
244 set_focus('stock_id');
246 $Ajax->activate('_page_body');
250 function item_settings(&$stock_id)
252 global $SysPrefs, $path_to_root, $new_item, $pic_height;
254 start_outer_table(TABLESTYLE2);
258 table_section_title(_("Item"));
260 //------------------------------------------------------------------------------------
263 text_row(_("Item Code:"), 'NewStockID', null, 21, 20);
265 $_POST['inactive'] = 0;
268 { // Must be modifying an existing item
269 if (get_post('NewStockID') != get_post('stock_id') || get_post('addupdate')) { // first item display
271 $_POST['NewStockID'] = $_POST['stock_id'];
273 $myrow = get_item($_POST['NewStockID']);
275 $_POST['long_description'] = $myrow["long_description"];
276 $_POST['description'] = $myrow["description"];
277 $_POST['category_id'] = $myrow["category_id"];
278 $_POST['tax_type_id'] = $myrow["tax_type_id"];
279 $_POST['units'] = $myrow["units"];
280 $_POST['mb_flag'] = $myrow["mb_flag"];
282 $_POST['sales_account'] = $myrow['sales_account'];
283 $_POST['inventory_account'] = $myrow['inventory_account'];
284 $_POST['cogs_account'] = $myrow['cogs_account'];
285 $_POST['adjustment_account'] = $myrow['adjustment_account'];
286 $_POST['assembly_account'] = $myrow['assembly_account'];
287 $_POST['dimension_id'] = $myrow['dimension_id'];
288 $_POST['dimension2_id'] = $myrow['dimension2_id'];
289 $_POST['no_sale'] = $myrow['no_sale'];
290 $_POST['del_image'] = 0;
291 $_POST['inactive'] = $myrow["inactive"];
292 $_POST['editable'] = $myrow["editable"];
294 label_row(_("Item Code:"),$_POST['NewStockID']);
295 hidden('NewStockID', $_POST['NewStockID']);
296 set_focus('description');
299 text_row(_("Name:"), 'description', null, 52, 200);
301 textarea_row(_('Description:'), 'long_description', null, 42, 3);
303 stock_categories_list_row(_("Category:"), 'category_id', null, false, $new_item);
305 if ($new_item && (list_updated('category_id') || !isset($_POST['units']))) {
307 $category_record = get_item_category($_POST['category_id']);
309 $_POST['tax_type_id'] = $category_record["dflt_tax_type"];
310 $_POST['units'] = $category_record["dflt_units"];
311 $_POST['mb_flag'] = $category_record["dflt_mb_flag"];
312 $_POST['inventory_account'] = $category_record["dflt_inventory_act"];
313 $_POST['cogs_account'] = $category_record["dflt_cogs_act"];
314 $_POST['sales_account'] = $category_record["dflt_sales_act"];
315 $_POST['adjustment_account'] = $category_record["dflt_adjustment_act"];
316 $_POST['assembly_account'] = $category_record["dflt_assembly_act"];
317 $_POST['dimension_id'] = $category_record["dflt_dim1"];
318 $_POST['dimension2_id'] = $category_record["dflt_dim2"];
319 $_POST['no_sale'] = $category_record["dflt_no_sale"];
320 $_POST['editable'] = 0;
323 $fresh_item = !isset($_POST['NewStockID']) || $new_item
324 || check_usage($_POST['stock_id'],false);
326 item_tax_types_list_row(_("Item Tax Type:"), 'tax_type_id', null);
328 stock_item_types_list_row(_("Item Type:"), 'mb_flag', null, $fresh_item);
330 stock_units_list_row(_('Units of Measure:'), 'units', null, $fresh_item);
332 check_row(_("Editable description:"), 'editable');
334 check_row(_("Exclude from sales:"), 'no_sale');
338 $dim = get_company_pref('use_dimension');
341 table_section_title(_("Dimensions"));
343 dimensions_list_row(_("Dimension")." 1", 'dimension_id', null, true, " ", false, 1);
345 dimensions_list_row(_("Dimension")." 2", 'dimension2_id', null, true, " ", false, 2);
348 hidden('dimension_id', 0);
350 hidden('dimension2_id', 0);
352 table_section_title(_("GL Accounts"));
354 gl_all_accounts_list_row(_("Sales Account:"), 'sales_account', $_POST['sales_account']);
356 if (!is_service($_POST['mb_flag']))
358 gl_all_accounts_list_row(_("Inventory Account:"), 'inventory_account', $_POST['inventory_account']);
359 gl_all_accounts_list_row(_("C.O.G.S. Account:"), 'cogs_account', $_POST['cogs_account']);
360 gl_all_accounts_list_row(_("Inventory Adjustments Account:"), 'adjustment_account', $_POST['adjustment_account']);
364 gl_all_accounts_list_row(_("C.O.G.S. Account:"), 'cogs_account', $_POST['cogs_account']);
365 hidden('inventory_account', $_POST['inventory_account']);
366 hidden('adjustment_account', $_POST['adjustment_account']);
370 if (is_manufactured($_POST['mb_flag']))
371 gl_all_accounts_list_row(_("Item Assembly Costs Account:"), 'assembly_account', $_POST['assembly_account']);
373 hidden('assembly_account', $_POST['assembly_account']);
375 table_section_title(_("Other"));
377 // Add image upload for New Item - by Joe
378 file_row(_("Image File (.jpg)") . ":", 'pic', 'pic');
379 // Add Image upload for New Item - by Joe
380 $stock_img_link = "";
381 $check_remove_image = false;
382 if (isset($_POST['NewStockID']) && file_exists(company_path().'/images/'
383 .item_img_name($_POST['NewStockID']).".jpg"))
385 // 31/08/08 - rand() call is necessary here to avoid caching problems. Thanks to Peter D.
386 $stock_img_link .= "<img id='item_img' alt = '[".$_POST['NewStockID'].".jpg".
387 "]' src='".company_path().'/images/'.item_img_name($_POST['NewStockID']).
388 ".jpg?nocache=".rand()."'"." height='$pic_height' border='0'>";
389 $check_remove_image = true;
393 $stock_img_link .= _("No image");
396 label_row(" ", $stock_img_link);
397 if ($check_remove_image)
398 check_row(_("Delete Image:"), 'del_image');
400 record_status_list_row(_("Item status:"), 'inactive');
403 div_start('controls');
404 if (!isset($_POST['NewStockID']) || $new_item)
406 submit_center('addupdate', _("Insert New Item"), true, '', 'default');
410 submit_center_first('addupdate', _("Update Item"), '',
411 @$_REQUEST['popup'] ? true : 'default');
412 submit_return('select', get_post('stock_id'),
413 _("Select this items and return to document entry."), 'default');
414 submit('clone', _("Clone This Item"), true, '', true);
415 submit('delete', _("Delete This Item"), true, '', true);
416 submit_center_last('cancel', _("Cancel"), _("Cancel Edition"), 'cancel');
422 //--------------------------------------------------------------------------------------------
426 if (db_has_stock_items())
428 start_table(TABLESTYLE_NOBORDER);
430 stock_items_list_cells(_("Select an item:"), 'stock_id', null,
431 _('New item'), true, check_value('show_inactive'));
432 $new_item = get_post('stock_id')=='';
433 check_cells(_("Show inactive:"), 'show_inactive', null, true);
437 if (get_post('_show_inactive_update')) {
438 $Ajax->activate('stock_id');
439 set_focus('stock_id');
444 hidden('stock_id', get_post('stock_id'));
447 div_start('details');
449 $stock_id = get_post('stock_id');
451 unset($_POST['_tabs_sel']); // force settings tab for new customer
453 tabbed_content_start('tabs', array(
454 'settings' => array(_('&General settings'), $stock_id),
455 'sales_pricing' => array(_('S&ales Pricing'), $stock_id),
456 'purchase_pricing' => array(_('&Purchasing Pricing'), $stock_id),
457 'standard_cost' => array(_('Standard &Costs'), $stock_id),
458 'reorder_level' => array(_('&Reorder Levels'), (is_inventory_item($stock_id) ? $stock_id : null)),
459 'movement' => array(_('&Transactions'), $stock_id),
460 'status' => array(_('&Status'), $stock_id),
463 switch (get_post('_tabs_sel')) {
466 item_settings($stock_id);
468 case 'sales_pricing':
469 $_GET['stock_id'] = $stock_id;
471 include_once($path_to_root."/inventory/prices.php");
473 case 'purchase_pricing':
474 $_GET['stock_id'] = $stock_id;
476 include_once($path_to_root."/inventory/purchasing_data.php");
478 case 'standard_cost':
479 $_GET['stock_id'] = $stock_id;
481 include_once($path_to_root."/inventory/cost_update.php");
483 case 'reorder_level':
484 if (!is_inventory_item($stock_id))
488 $_GET['stock_id'] = $stock_id;
490 include_once($path_to_root."/inventory/reorder_level.php");
493 $_GET['stock_id'] = $stock_id;
495 include_once($path_to_root."/inventory/inquiry/stock_movements.php");
498 $_GET['stock_id'] = $stock_id;
500 include_once($path_to_root."/inventory/inquiry/stock_status.php");
504 tabbed_content_end();
509 hidden('popup', @$_REQUEST['popup']);
512 //------------------------------------------------------------------------------------
514 end_page(@$_REQUEST['popup']);