From b0e112621af4ffcf4fed2264bffd0ebbda258a48 Mon Sep 17 00:00:00 2001 From: Janusz Dobrowolski Date: Tue, 26 Jan 2010 14:19:46 +0000 Subject: [PATCH] Added full support for editable item descriptions in sales --- includes/ui/ui_lists.inc | 108 +++++++++++++++++---------- inventory/includes/db/items_db.inc | 12 +-- inventory/manage/items.php | 19 +++-- inventory/prices.php | 2 +- js/inserts.js | 35 +++++++-- sales/includes/cart_class.inc | 30 ++++---- sales/includes/ui/sales_order_ui.inc | 19 +++-- sales/sales_order_entry.php | 17 +++-- 8 files changed, 158 insertions(+), 84 deletions(-) diff --git a/includes/ui/ui_lists.inc b/includes/ui/ui_lists.inc index d84b0d9d..cde7b8ab 100644 --- a/includes/ui/ui_lists.inc +++ b/includes/ui/ui_lists.inc @@ -60,7 +60,8 @@ $opts = array( // default options 'disabled' => false, 'box_hint' => null, // box/selectors hints; null = std see below 'category' => false, // category column name or false - 'show_inactive' => false // show inactive records. + 'show_inactive' => false, // show inactive records. + 'editable' => false // false, or length of editable entry field ); // ------ merge options with defaults ---------- if($options != null) @@ -68,7 +69,11 @@ $opts = array( // default options if (!is_array($opts['where'])) $opts['where'] = array($opts['where']); $search_box = $opts['search_box']===true ? '_'.$name.'_edit' : $opts['search_box']; + // select content filtered by search field: $search_submit = $opts['search_submit']===true ? '_'.$name.'_button' : $opts['search_submit']; + // select set by select content field + $search_button = $search_submit ? $search_submit : ($opts['editable'] ? '_'.$name.'_button' : false); + $select_submit = $opts['select_submit']; $spec_id = $opts['spec_id']; $spec_option = $opts['spec_option']; @@ -84,7 +89,7 @@ $opts = array( // default options $opts['sel_hint'] = $by_id || $search_box==false ? '' : _('Press Space tab for search pattern entry'); - if ($opts['box_hint'] === null) + if ($opts['box_hint'] === null) // dodaƦ hint dla pustego **** $opts['box_hint'] = $search_box && $search_submit != false ? ($by_id ? _('Enter code fragment to search or * for all') : _('Enter description fragment to search or * for all')) :''; @@ -99,7 +104,7 @@ $opts = array( // default options $rel = ''; $limit = ''; - if (isset($_POST['_'.$name.'_update'])) { + if (isset($_POST['_'.$name.'_update'])) { // select list or search box change if ($by_id) $txt = $_POST[$name]; if (!$opts['async']) @@ -110,30 +115,30 @@ $opts = array( // default options if ($search_box) { // search related sql modifications - $rel = "rel='$search_box'"; // set relation to list - if ($opts['search_submit']) { - if (isset($_POST[$search_submit])) { - $selected_id = array(); // ignore selected_id while search - if (!$opts['async']) - $Ajax->activate('_page_body'); - else - $Ajax->activate($name); - } - if ($txt == '') { - if ($spec_option === false && $selected_id == array()) - $limit = ' LIMIT 1'; - else - $opts['where'][] = $valfield . "='". get_post($name, $spec_id)."'"; - } - else - if ($txt != '*') { + $rel = "rel='$search_box'"; // set relation to list + if ($opts['search_submit']) { + if (isset($_POST[$search_submit])) { + $selected_id = array(); // ignore selected_id while search + if (!$opts['async']) + $Ajax->activate('_page_body'); + else + $Ajax->activate($name); + } + if ($txt == '') { + if ($spec_option === false && $selected_id == array()) + $limit = ' LIMIT 1'; + else + $opts['where'][] = $valfield . "='". get_post($name, $spec_id)."'"; + } + else + if ($txt != '*') { - foreach($opts['search'] as $i=> $s) - $opts['search'][$i] = $s . " LIKE '%{$txt}%'"; - $opts['where'][] = '('. implode($opts['search'], ' OR ') . ')'; + foreach($opts['search'] as $i=> $s) + $opts['search'][$i] = $s . " LIKE '%{$txt}%'"; + $opts['where'][] = '('. implode($opts['search'], ' OR ') . ')'; + } } } - } // sql completion if (count($opts['where'])) { $where = strpos($sql, 'WHERE')==false ? ' WHERE ':' AND '; @@ -158,19 +163,26 @@ $opts = array( // default options $first_id = false; $found = false; $lastcat = null; -//if($name=='stock_id') display_error($sql); + $edit = false; +//if($name=='stock_id') display_notification('
'.print_r($_POST, true).'
'); +//if($name=='stock_id') display_error($search_submit); if($result = db_query($sql)) { while ($contact_row = db_fetch($result)) { $value = $contact_row[0]; $descr = $opts['format']==null ? $contact_row[1] : call_user_func($opts['format'], $contact_row); $sel = ''; - if (get_post($search_submit) && ($txt === $value)) { + if (get_post($search_button) && ($txt == $value)) { $selected_id[] = $value; } if (in_array($value, $selected_id)) { $sel = 'selected'; $found = $value; + $edit = $opts['editable'] && $contact_row['editable'] + && ($_POST[$search_box] == $value) + ? $descr : false; + if ($edit) + break; // selected field is editable - abandon list construction } // show selected option even if inactive if (!$opts['show_inactive'] && @$contact_row['inactive'] && $sel==='') { @@ -207,24 +219,37 @@ $opts = array( // default options if ($found===false) { $selected_id = array($first_id); } + $_POST[$name] = $multi ? $selected_id : $selected_id[0]; - if ($by_id && $search_box != false) { - $txt = $found; - $Ajax->addUpdate($name, $search_box, $txt ? $txt : ''); - } $selector = "\n"; + if ($by_id && ($search_box != false || $opts['editable']) ) { + // on first display show selector list + if (isset($_POST[$search_box]) && $opts['editable'] && $edit) { + $selector = "" + ."\n"; +// if ($_POST['_focus'] == $name) { + set_focus($name.'_text'); // prevent lost focus +// } + } else if (isset($_POST[$name.'_text'])) + set_focus($name); // prevent lost focus + if (!$opts['editable']) + $txt = $found; + $Ajax->addUpdate($name, $search_box, $txt ? $txt : ''); + } + $Ajax->addUpdate($name, "_{$name}_sel", $selector); - // because of bug which M$ cannot fix since IE 5.0 - // we must embed whole selector in span tags to enable proper ajax update + // span for select list/inut field update $selector = "".$selector."\n"; - if ($select_submit != false) { // if submit on change is used - add select button + // if selectable or editable list is used - add select button + if ($select_submit != false || $search_button) { global $_select_button; // button class selects form reload/ajax selector update $selector .= sprintf($_select_button, $disabled, user_theme(), @@ -232,7 +257,6 @@ $opts = array( // default options '_'.$name.'_update')."\n"; } // ------ make combo ---------- - $edit_entry = ''; if ($search_box != false) { $edit_entry = "\n"; - if ($search_submit != false) { + if ($search_submit != false || $opts['editable']) { global $_search_button; $edit_entry .= sprintf($_search_button, $disabled, user_theme(), (fallback_mode() ? '' : 'display:none;'), - $search_submit)."\n"; + $search_submit ? $search_submit : "_{$name}_button")."\n"; } } default_focus(($search_box && $by_id) ? $search_box : $name); @@ -721,7 +745,7 @@ function sales_items_list($name, $selected_id=null, $all_option=false, global $all_items; // all sales codes $sql = "SELECT i.item_code, i.description, c.description, count(*)>1 as kit, - i.inactive + i.inactive, if(count(*)>1, '0', s.editable) as editable FROM ".TB_PREF."stock_master s, ".TB_PREF."item_codes i @@ -751,7 +775,9 @@ function sales_items_list($name, $selected_id=null, $all_option=false, 'size'=>15, 'select_submit'=> $submit_on_change, 'category' => 2, - 'order' => array('c.description','i.item_code') + 'order' => array('c.description','i.item_code'), + 'editable' => 30, + 'max' => 255 ), $opts) ); } @@ -766,7 +792,7 @@ function sales_items_list_cells($label, $name, $selected_id=null, $all_option=fa function sales_kits_list($name, $selected_id=null, $all_option=false, $submit_on_change=false) { return sales_items_list($name, $selected_id, $all_option, $submit_on_change, - 'kits', array('cells'=>false)); + 'kits', array('cells'=>false, 'editable' => false)); } function sales_local_items_list_row($label, $name, $selected_id=null, $all_option=false, $submit_on_change=false) @@ -776,7 +802,7 @@ function sales_local_items_list_row($label, $name, $selected_id=null, $all_optio echo "$label\n"; echo ""; echo sales_items_list($name, $selected_id, $all_option, $submit_on_change, - 'local', array('cells'=>false)); + 'local', array('cells'=>false, 'editable' => false)); echo ""; } //------------------------------------------------------------------------------------ @@ -2149,7 +2175,7 @@ function extset_list($name, $value=null, $submit_on_change=false) $items[] = sprintf(_("Activated for '%s'"), $comp['name']); return array_selector( $name, $value, $items, array( - 'spec_option'=> _("Installed on system"), + 'spec_option'=> _("Available and/or installed"), 'spec_id' => -1, 'select_submit'=> $submit_on_change, 'async' => true diff --git a/inventory/includes/db/items_db.inc b/inventory/includes/db/items_db.inc index 534d8b71..de6ce056 100644 --- a/inventory/includes/db/items_db.inc +++ b/inventory/includes/db/items_db.inc @@ -12,7 +12,7 @@ function update_item($stock_id, $description, $long_description, $category_id, $tax_type_id, $units='', $mb_flag='', $sales_account, $inventory_account, $cogs_account, $adjustment_account, $assembly_account, $dimension_id, - $dimension2_id, $no_sale) + $dimension2_id, $no_sale, $editable) { $sql = "UPDATE ".TB_PREF."stock_master SET long_description=".db_escape($long_description).", description=".db_escape($description).", @@ -25,7 +25,8 @@ function update_item($stock_id, $description, $long_description, $category_id, dimension_id=".db_escape($dimension_id).", dimension2_id=".db_escape($dimension2_id).", tax_type_id=".db_escape($tax_type_id).", - no_sale=".db_escape($no_sale); + no_sale=".db_escape($no_sale).", + editable=".db_escape($editable); if ($units != '') $sql .= ", units='$units'"; @@ -43,11 +44,11 @@ function update_item($stock_id, $description, $long_description, $category_id, function add_item($stock_id, $description, $long_description, $category_id, $tax_type_id, $units, $mb_flag, $sales_account, $inventory_account, $cogs_account, $adjustment_account, $assembly_account, $dimension_id, - $dimension2_id, $no_sale) + $dimension2_id, $no_sale, $editable) { $sql = "INSERT INTO ".TB_PREF."stock_master (stock_id, description, long_description, category_id, tax_type_id, units, mb_flag, sales_account, inventory_account, cogs_account, - adjustment_account, assembly_account, dimension_id, dimension2_id, no_sale) + adjustment_account, assembly_account, dimension_id, dimension2_id, no_sale, editable) VALUES (".db_escape($stock_id).", ".db_escape($description).", ".db_escape($long_description).", ".db_escape($category_id).", ".db_escape($tax_type_id).", " .db_escape($units).", ".db_escape($mb_flag).", @@ -55,7 +56,8 @@ function add_item($stock_id, $description, $long_description, $category_id, .", ".db_escape($cogs_account).",".db_escape($adjustment_account) .", ".db_escape($assembly_account).", " .db_escape($dimension_id).", ".db_escape($dimension2_id)."," - .db_escape($no_sale).")"; + .db_escape($no_sale)."," + .db_escape($editable).")"; db_query($sql, "The item could not be added"); diff --git a/inventory/manage/items.php b/inventory/manage/items.php index 5e72e405..872dc5b9 100644 --- a/inventory/manage/items.php +++ b/inventory/manage/items.php @@ -169,7 +169,7 @@ if (isset($_POST['addupdate'])) $_POST['inventory_account'], $_POST['cogs_account'], $_POST['adjustment_account'], $_POST['assembly_account'], $_POST['dimension_id'], $_POST['dimension2_id'], - check_value('no_sale')); + check_value('no_sale'), check_value('editable')); update_record_status($_POST['NewStockID'], $_POST['inactive'], 'stock_master', 'stock_id'); update_record_status($_POST['NewStockID'], $_POST['inactive'], @@ -187,12 +187,12 @@ if (isset($_POST['addupdate'])) $_POST['inventory_account'], $_POST['cogs_account'], $_POST['adjustment_account'], $_POST['assembly_account'], $_POST['dimension_id'], $_POST['dimension2_id'], - check_value('no_sale')); + check_value('no_sale'), check_value('editable')); display_notification(_("A new item has been added.")); $_POST['stock_id'] = $_POST['NewStockID'] = $_POST['description'] = $_POST['long_description'] = ''; - $_POST['no_sale'] = 0; + $_POST['no_sale'] = $_POST['editable'] = 0; set_focus('NewStockID'); } $Ajax->activate('_page_body'); @@ -297,6 +297,7 @@ else $_POST['no_sale'] = $myrow['no_sale']; $_POST['del_image'] = 0; $_POST['inactive'] = $myrow["inactive"]; + $_POST['editable'] = $myrow["editable"]; label_row(_("Item Code:"),$_POST['NewStockID']); hidden('NewStockID', $_POST['NewStockID']); set_focus('description'); @@ -323,6 +324,8 @@ if ($new_item && (list_updated('category_id') || !isset($_POST['units']))) { $_POST['dimension_id'] = $category_record["dflt_dim1"]; $_POST['dimension2_id'] = $category_record["dflt_dim2"]; $_POST['no_sale'] = $category_record["dflt_no_sale"]; + $_POST['editable'] = 0; + } $fresh_item = !isset($_POST['NewStockID']) || $new_item || check_usage($_POST['stock_id'],false); @@ -333,6 +336,12 @@ stock_item_types_list_row(_("Item Type:"), 'mb_flag', null, $fresh_item); stock_units_list_row(_('Units of Measure:'), 'units', null, $fresh_item); +check_row(_("Editable description:"), 'editable'); + +check_row(_("Exclude from sales:"), 'no_sale'); + +table_section(2); + $dim = get_company_pref('use_dimension'); if ($dim >= 1) { @@ -347,8 +356,6 @@ if ($dim < 1) if ($dim < 2) hidden('dimension2_id', 0); -table_section(2); - table_section_title(_("GL Accounts")); gl_all_accounts_list_row(_("Sales Account:"), 'sales_account', $_POST['sales_account']); @@ -397,8 +404,6 @@ label_row(" ", $stock_img_link); if ($check_remove_image) check_row(_("Delete Image:"), 'del_image'); -check_row(_("Exclude from sales:"), 'no_sale'); - record_status_list_row(_("Item status:"), 'inactive'); end_outer_table(1); div_end(); diff --git a/inventory/prices.php b/inventory/prices.php index 40dd11f7..56034cbb 100644 --- a/inventory/prices.php +++ b/inventory/prices.php @@ -54,7 +54,7 @@ if (!isset($_POST['stock_id'])) $_POST['stock_id'] = get_global_stock_item(); echo "
" . _("Item:"). " "; -echo sales_items_list('stock_id', $_POST['stock_id'], false, true); +echo sales_items_list('stock_id', $_POST['stock_id'], false, true, '', array('random_entry' => false)); echo "
"; set_global_stock_item($_POST['stock_id']); diff --git a/js/inserts.js b/js/inserts.js index cebb2a43..a853a716 100644 --- a/js/inserts.js +++ b/js/inserts.js @@ -53,8 +53,9 @@ function _set_combo_input(e) { save_focus(select); // submit request if there is submit_on_change option set and // search field has changed. + if (button && (this.value != this.getAttribute('_last'))) { - JsHttpRequest.request(button); + JsHttpRequest.request(button); } else if(this.className=='combo2') { this.style.display = 'none'; select.style.display = 'inline'; @@ -95,8 +96,10 @@ function _update_box(s) { if(box && s.selectedIndex>=0) { var opt = s.options[s.selectedIndex]; if(box) { + var old = box.value; box.value = byid ? opt.value : opt.text; box.setAttribute('_last', box.value); + return old != box.value } } } @@ -107,10 +110,13 @@ function _set_combo_select(e) { // signaling we must track selectedIndex in onblur handler. e.setAttribute('_last', e.selectedIndex); e.onblur = function() { - if(this.className=='combo') - _update_box(this); - if (this.selectedIndex != this.getAttribute('_last')) - this.onchange(); + var box = document.getElementsByName(this.getAttribute('rel'))[0]; +// if(this.className=='combo') +// _update_box(this); + if ((this.selectedIndex != this.getAttribute('_last')) + ||(this.className=='combo' && _update_box(this)) + ) + this.onchange(); } e.onchange = function() { var s = this; @@ -258,12 +264,29 @@ var inserts = { } } }, - 'button[aspect=selector], input[aspect=selector]': function(e) { + 'button[aspect=selector], button[aspect=abort], input[aspect=selector]': function(e) { e.onclick = function() { passBack(this.getAttribute('rel')); return false; } }, + 'button[aspect=popup]': function(e) { + var old = e.onclick + e.onclick = function() { +// this.form.target = '_blank'; +// old(); +// return true; + if(_w) _w.close(); // this is really necessary to have window on top in FF2 :/ + _w = open(document.location+'popup=1', + "edit","Scrollbars=0,resizable=0,width=800,height=600, top=50,left=50"); + if (_w.opener == null) + _w.opener = self; + // editors._call = key; // store call point for passBack +// _w.moveTo(50, 50); + _w.focus(); + return false; + } + }, 'select': function(e) { if(e.onfocus==undefined) { e.onfocus = function() { diff --git a/sales/includes/cart_class.inc b/sales/includes/cart_class.inc index 1ba84ea6..b43c945f 100644 --- a/sales/includes/cart_class.inc +++ b/sales/includes/cart_class.inc @@ -291,16 +291,16 @@ class cart $this->freight_cost = $freight_cost; } - function add_to_cart($line_no,$stock_id, $qty, $price, $disc, $qty_done=0, $standard_cost=0, $description=null, $id=0, $src_no=0) + function add_to_cart($line_no, $stock_id, $qty, $price, $disc, $qty_done=0, $standard_cost=0, $description=null, $id=0, $src_no=0) { - if (isset($stock_id) && $stock_id != "" && isset($qty)/* && $qty > 0*/) { - $this->line_items[$line_no] = new line_details($stock_id, $qty, $price, $disc, - $qty_done, $standard_cost, $description, $id, $src_no); + $line = new line_details($stock_id, $qty, $price, $disc, + $qty_done, $standard_cost, $description, $id, $src_no); + + if ($line->valid) { + $this->line_items[$line_no] = $line; return 1; - } else { - // shouldn't come here under normal circumstances - display_db_error("unexpected - adding an invalid item or null quantity", "", true); - } + } else + display_error(_("You have to enter valid stock code or nonempty description")); return 0; } @@ -473,6 +473,9 @@ class line_details var $qty_dispatched; // quantity selected to process var $qty_old=0; // quantity dispatched before edition var $standard_cost; + var $descr_editable; + + var $valid; // validation in constructor function line_details ($stock_id, $qty, $prc, $disc_percent, $qty_done, $standard_cost, $description, $id=0, $src_no=0 ) @@ -483,19 +486,19 @@ class line_details $this->src_no = $src_no; $item_row = get_item($stock_id); - if ($item_row == null) - display_db_error("invalid item added to order : $stock_id", ""); - + if (!$item_row) + return; + $this->mb_flag = $item_row["mb_flag"]; $this->units = $item_row["units"]; - if ($description == null) + $this->descr_editable = $item_row["editable"]; + if ($description == null || !$this->descr_editable) $this->item_description = $item_row["description"]; else $this->item_description = $description; //$this->standard_cost = $item_row["material_cost"] + $item_row["labour_cost"] + $item_row["overhead_cost"]; $this->tax_type = $item_row["tax_type_id"]; $this->tax_type_name = $item_row["tax_type_name"]; - $this->stock_id = $stock_id; $this->quantity = $qty; $this->qty_dispatched = $qty; @@ -503,6 +506,7 @@ class line_details $this->discount_percent = $disc_percent; $this->qty_done = $qty_done; $this->standard_cost = $standard_cost; + $this->valid = true; } // get unit price as stated on document diff --git a/sales/includes/ui/sales_order_ui.inc b/sales/includes/ui/sales_order_ui.inc index 028ca8b7..bb20dce6 100644 --- a/sales/includes/ui/sales_order_ui.inc +++ b/sales/includes/ui/sales_order_ui.inc @@ -13,7 +13,7 @@ include_once($path_to_root . "/sales/includes/cart_class.inc"); include_once($path_to_root . "/includes/manufacturing.inc"); //-------------------------------------------------------------------------------- -function add_to_order(&$order, $new_item, $new_item_qty, $price, $discount) +function add_to_order(&$order, $new_item, $new_item_qty, $price, $discount, $description='') { // calculate item price to sum of kit element prices factor for // value distribution over all exploded kit items @@ -47,7 +47,7 @@ function add_to_order(&$order, $new_item, $new_item_qty, $price, $discount) if (!$item['is_foreign'] && $item['item_code'] != $item['stock_id']) { // this is sales kit - recurse add_to_order($order, $item['stock_id'], $new_item_qty*$item['quantity'], - $item_price, $discount, $std_price); + $item_price, $discount); } else { // stock item record eventually with foreign code @@ -63,9 +63,10 @@ function add_to_order(&$order, $new_item, $new_item_qty, $price, $discount) } } $order->add_to_cart (count($order->line_items), $item['stock_id'], - $new_item_qty*$item['quantity'], $item_price, $discount); + $new_item_qty*$item['quantity'], $item_price, $discount, 0,0, $description); } } + } //--------------------------------------------------------------------------------- @@ -486,11 +487,19 @@ function sales_order_item_controls(&$order, &$rowcounter, $line_no=-1) $_POST['qty'] = number_format2($order->line_items[$id]->qty_dispatched, $dec); $_POST['price'] = price_format($order->line_items[$id]->price); $_POST['Disc'] = percent_format($order->line_items[$id]->discount_percent*100); - $_POST['item_description'] = $order->line_items[$id]->item_description; $units = $order->line_items[$id]->units; + $_POST['item_description'] = $order->line_items[$id]->item_description; hidden('stock_id', $_POST['stock_id']); label_cell($_POST['stock_id']); - text_cells(null,'item_description', null, 45, 150); + if ($order->line_items[$id]->descr_editable) + text_cells(null,'item_description', null, 45, 150); + else { + hidden('item_description', $_POST['item_description']); + label_cell($_POST['item_description']); + } +// } else { +// sales_items_list_cells(null,'item_description', null, false, true); +// } //label_cell($order->line_items[$line_no]->item_description, "nowrap"); $Ajax->activate('items_table'); } diff --git a/sales/sales_order_entry.php b/sales/sales_order_entry.php index c7255881..6c349361 100644 --- a/sales/sales_order_entry.php +++ b/sales/sales_order_entry.php @@ -409,8 +409,13 @@ if (isset($_POST['update'])) { function check_item_data() { global $SysPrefs; - - if (!check_num('qty', 0) || !check_num('Disc', 0, 100)) { + + if(!get_post('stock_id_text', true)) { + display_error( _("Item description cnnot be empty.")); + set_focus('stock_id_edit'); + return false; + } + elseif (!check_num('qty', 0) || !check_num('Disc', 0, 100)) { display_error( _("The item could not be updated because you are attempting to set the quantity ordered to less than 0, or the discount percent to more than 100.")); set_focus('qty'); return false; @@ -474,9 +479,10 @@ function handle_new_item() if (!check_item_data()) { return; } - add_to_order($_SESSION['Items'], $_POST['stock_id'], input_num('qty'), - input_num('price'), input_num('Disc') / 100); - $_POST['_stock_id_edit'] = $_POST['stock_id'] = ""; + add_to_order($_SESSION['Items'], get_post('stock_id'), input_num('qty'), + input_num('price'), input_num('Disc') / 100, get_post('stock_id_text')); + + unset($_POST['_stock_id_edit'], $_POST['stock_id']); line_start_focus(); } @@ -657,5 +663,4 @@ if ($customer_error == "") { } end_form(); end_page(); - ?> \ No newline at end of file -- 2.30.2