! -> Note
$ -> Affected files
+24-Nov-2008 Janusz Dobrowolski
++ Added alias/foreign item codes and sales kits support.
+$ /applications/inventory.php
+ /includes/ui/ui_lists.inc
+ /inventory/prices.php
+ /inventory/includes/inventory_db.inc
+ /inventory/includes/db/items_category_db.inc
+ /inventory/includes/db/items_db.inc
+ /inventory/manage/items.php
+ /inventory/includes/db/items_codes_db.inc (new)
+ /inventory/manage/item_codes.php (new)
+ /inventory/manage/sales_kits.php (new)
+ /sales/includes/sales_db.inc
+ /sales/includes/ui/sales_order_ui.inc
+! Added decimals to get_item_edit_info() return (sql usage optimization).
+$ /includes/db/inventory_db.inc
+ /inventory/includes/item_adjustments_ui.inc
+ /inventory/includes/stock_transfers_ui.inc
+ /manufacturing/includes/work_order_issue_ui.inc
+ /purchasing/includes/ui/po_ui.inc
+ /sales/includes/ui/sales_credit_ui.inc
+! Added postlabel update in amount_cells_ex() and derivative helpers, fixed qty_cell $dec handling
+$ /includes/ui/ui_input.inc
+# Fixed _vd() debug function for use also in ajax mode.
+$ /includes/ui/ui_view.inc
+! Changed foreign column name to avoid mysql syntax problems, added category.
+$ /sql/alter2.1.sql
+ /sql/alter2.1.php
+# Fixed unconsistent units of measure.
+$ /sql/en_US-demo.sql
+ /sql/en_US-new.sql
+
24-Nov-2008 Joe Hunt
! Preparing for graphic Links
$ config.php
$this->add_module(_("Maintenance"));
$this->add_lapp_function(2, _("&Items"),"inventory/manage/items.php?");
+ $this->add_lapp_function(2, _("&Foreign Item Codes"),"inventory/manage/item_codes.php?");
+ $this->add_lapp_function(2, _("Sales &Kits"),"inventory/manage/sales_kits.php?");
$this->add_lapp_function(2, _("Item &Categories"),"inventory/manage/item_categories.php?");
$this->add_lapp_function(2, _("Inventory &Locations"),"inventory/manage/locations.php?");
$this->add_rapp_function(2, _("Inventory &Movement Types"),"inventory/manage/movement_types.php?");
return $str;
}
*/
+//---------------------------------------------------------------------------------------------------
+//
+// Select item via foreign code.
+//
+function sales_items_list($name, $selected_id=null, $all_option=false,
+ $submit_on_change=false, $type='', $opts=array())
+{
+ global $all_items;
+ // all sales codes
+ $sql = "SELECT i.item_code, i.description, c.description, count(*)>1 as kit
+ FROM
+ ".TB_PREF."item_codes i
+ LEFT JOIN
+ ".TB_PREF."stock_category c
+ ON i.category_id=c.category_id";
+
+ if ($type == 'local') { // exclude foreign codes
+ $sql .= " WHERE NOT i.is_foreign";
+ } elseif ($type == 'kits') { // sales kits
+ $sql .= " WHERE NOT i.is_foreign
+ AND NOT i.item_code=i.stock_id";
+ }
+
+ $sql .= " GROUP BY i.item_code";
+
+ return combo_input($name, $selected_id, $sql, 'i.item_code', 'c.description',
+ array_merge(
+ array(
+ 'format' => '_format_stock_items',
+ 'spec_option' => $all_option===true ? _("All Items") : $all_option,
+ 'spec_id' => $all_items,
+ 'search_box' => true,
+ 'search' => array("i.item_code", "c.description","s.description"),
+ 'search_submit' => get_company_pref('no_item_list')!=0,
+ 'size'=>15,
+ 'select_submit'=> $submit_on_change,
+ 'order' => 'i.item_code'
+ ), $opts) );
+}
+
+function sales_items_list_cells($label, $name, $selected_id=null, $all_option=false, $submit_on_change=false)
+{
+ if ($label != null)
+ echo "<td>$label</td>\n";
+ $str = sales_items_list($name, $selected_id, $all_option, $submit_on_change,
+ '', array('cells'=>true));
+ return $str;
+}
+
+function sales_kits_list($name, $selected_id=null, $all_option=false, $submit_on_change=false)
+{
+ $str = sales_items_list($name, $selected_id, $all_option, $submit_on_change,
+ 'kits', array('cells'=>false));
+ return $str;
+}
+
+function sales_local_items_list_row($label, $name, $selected_id=null, $all_option=false, $submit_on_change=false)
+{
+ echo "<tr>";
+ if ($label != null)
+ echo "<td>$label</td>\n";
+ echo "<td>";
+ $str = sales_items_list($name, $selected_id, $all_option, $submit_on_change,
+ 'local', array('cells'=>false));
+ echo "</td></tr>";
+ return $str;
+}
//------------------------------------------------------------------------------------
function base_stock_items_list($where, $name, $selected_id=null,
return $row[0];
}
-
?>
\ No newline at end of file
--- /dev/null
+<?php
+/*
+ item_codes table is used to store both multiply foreign codes and
+ sale kits definition.
+*/
+function update_item_code($id, $item_code, $stock_id, $description, $category, $qty, $foreign=0)
+{
+ $sql = "UPDATE ".TB_PREF."item_codes SET
+ item_code = ".db_escape($item_code).",
+ stock_id = ".db_escape($stock_id).",
+ description = ".db_escape($description).",
+ category_id = $category,
+ quantity = ".db_escape($qty).",
+ is_foreign = ".db_escape($foreign)."
+ WHERE ";
+
+ if ($id == -1) // update with unknown $id i.e. from items table editor
+ "item_code = ".db_escape($item_code)
+ ." AND stock_id = ".db_escape($stock_id);
+ else
+ $sql .= "id = $id";
+
+ db_query($sql,"an item code could not be updated");
+}
+
+function add_item_code($item_code, $stock_id, $description, $category, $qty, $foreign=0)
+{
+ $sql = "INSERT INTO ".TB_PREF."item_codes
+ (item_code, stock_id, description, category_id, quantity, is_foreign)
+ VALUES( ".db_escape($item_code).",".db_escape($stock_id).",
+ ".db_escape($description).",$category,".db_escape($qty).",".$foreign.")";
+
+ db_query($sql,"an item code could not be added");
+}
+
+function delete_item_code($id)
+{
+ $sql="DELETE FROM ".TB_PREF."item_codes WHERE id=$id";
+ db_query($sql,"an item code could not be deleted");
+}
+
+function get_item_code($id)
+{
+ $sql="SELECT * FROM ".TB_PREF."item_codes WHERE id='$id'";
+
+ $result = db_query($sql,"item code could not be retrieved");
+
+ return db_fetch($result);
+}
+
+function get_all_item_codes($stock_id, $foreign=1)
+{
+ $sql="SELECT i.*, c.description as cat_name FROM "
+ .TB_PREF."item_codes as i,"
+ .TB_PREF."stock_category as c
+ WHERE stock_id='$stock_id'
+ AND i.category_id=c.category_id
+ AND i.is_foreign=$foreign";
+
+ $result = db_query($sql,"all item codes could not be retrieved");
+
+ return $result;
+}
+
+function delete_item_kit($item_code)
+{
+ $sql="DELETE FROM ".TB_PREF."item_codes WHERE item_code='$item_code'";
+ db_query($sql,"an item kit could not be deleted");
+}
+
+function get_item_kit($item_code)
+{
+ $sql="SELECT DISTINCT kit.*, item.units, comp.description as comp_name
+ FROM "
+ .TB_PREF."item_codes kit,"
+ .TB_PREF."item_codes comp
+ LEFT JOIN "
+ .TB_PREF."stock_master item
+ ON
+ item.stock_id=comp.item_code
+ WHERE
+ kit.stock_id=comp.item_code
+ AND kit.item_code='$item_code'";
+
+ $result = db_query($sql,"item kit could not be retrieved");
+
+ return $result;
+}
+
+function get_item_code_dflts($stock_id)
+{
+ $sql = "SELECT units, decimals, description, category_id
+ FROM ".TB_PREF."stock_master,".TB_PREF."item_units
+ WHERE stock_id='$stock_id'";
+
+ $result = db_query($sql,"item code defaults could not be retrieved");
+ return db_fetch($result);
+}
+//
+// Check if kit contains given item, optionally recursive.
+//
+function check_item_in_kit($old_id, $kit_code, $item_code, $recurse=false)
+{
+ $result = get_item_kit($kit_code);
+ if ($result != 0)
+ {
+ while ($myrow = db_fetch($result))
+ {
+ if ($myrow['id'] == $old_id)
+ continue;
+
+ if ($myrow['stock_id'] == $item_code)
+ {
+ return 1;
+ }
+
+ if ($recurse && $myrow['item_code'] != $myrow['stock_id']
+ && check_item_in_kit($old_id, $item_code, $myrow['stock_id'], true))
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+function get_kit_props($kit_code)
+{
+ $sql = "SELECT description, category_id FROM ".TB_PREF."item_codes "
+ . " WHERE item_code='$kit_code'";
+ $res = db_query($sql, "kit name query failed");
+ return db_fetch($res);
+}
+
+function update_kit_props($kit_code, $name, $category)
+{
+ $sql = "UPDATE ".TB_PREF."item_codes SET description="
+ . db_escape($name).",category_id=".db_escape($category)
+ . " WHERE item_code='$kit_code'";
+ db_query($sql, "kit name update failed");
+}
+
+function get_where_used($item_code)
+{
+ $sql = "SELECT item_code, description FROM "
+ .TB_PREF."item_codes "
+ . " WHERE stock_id='$item_code'
+ AND item_
+ code!='$item_code'";
+ return db_query($sql, "where used query failed");
+}
+?>
\ No newline at end of file
WHERE stock_id='$stock_id'";
db_query($sql, "The item could not be updated");
+
+ update_item_code(-1, $stock_id, $stock_id, $description, 1, 0);
}
function add_item($stock_id, $description, $long_description, $category_id, $tax_type_id, $units, $mb_flag,
SELECT ".TB_PREF."locations.loc_code, '$stock_id' FROM ".TB_PREF."locations";
db_query($sql, "The item locstock could not be added");
+
+ add_item_code($stock_id, $stock_id, $description, 1, 0);
}
function delete_item($stock_id)
/*and cascade delete the bill of material if any */
$sql = "DELETE FROM ".TB_PREF."bom WHERE parent='$stock_id'";
db_query($sql, "could not delete stock item bom");
+
+ delete_item_kit($stock_id);
}
function get_item($stock_id)
include_once($path_to_root . "/inventory/includes/db/items_category_db.inc");
include_once($path_to_root . "/inventory/includes/db/items_trans_db.inc");
include_once($path_to_root . "/inventory/includes/db/items_prices_db.inc");
+include_once($path_to_root . "/inventory/includes/db/items_codes_db.inc");
include_once($path_to_root . "/inventory/includes/db/items_db.inc");
include_once($path_to_root . "/inventory/includes/db/items_locations_db.inc");
include_once($path_to_root . "/inventory/includes/db/movement_types_db.inc");
--- /dev/null
+<?php
+$page_security = 11;
+$path_to_root="../..";
+include_once($path_to_root . "/includes/session.inc");
+
+page(_("Foreign Item Codes"));
+
+include_once($path_to_root . "/includes/date_functions.inc");
+include_once($path_to_root . "/includes/ui.inc");
+include_once($path_to_root . "/includes/manufacturing.inc");
+include_once($path_to_root . "/includes/data_checks.inc");
+
+check_db_has_purchasable_items(_("There are no inventory items defined in the system."));
+
+simple_page_mode(true);
+//--------------------------------------------------------------------------------------------------
+
+if ($Mode=='ADD_ITEM' || $Mode=='UPDATE_ITEM')
+{
+
+ $input_error = 0;
+ if ($_POST['stock_id'] == "" || !isset($_POST['stock_id']))
+ {
+ $input_error = 1;
+ display_error( _("There is no item selected."));
+ set_focus('stock_id');
+ }
+ elseif (!check_num('quantity', 0))
+ {
+ $input_error = 1;
+ display_error( _("The price entered was not numeric."));
+ set_focus('quantity');
+ }
+ elseif ($_POST['description'] == '')
+ {
+ $input_error = 1;
+ display_error( _("Item code description cannot be empty."));
+ set_focus('description');
+ }
+ elseif($selected_id == -1)
+ {
+ $kit = get_item_kit($_POST['item_code']);
+ if (db_num_rows($kit)) {
+ $input_error = 1;
+ display_error( _("This item code is already assigned to stock item or sale kit."));
+ set_focus('item_code');
+ }
+ }
+
+ if ($input_error == 0)
+ {
+ if ($Mode == 'ADD_ITEM')
+ {
+ add_item_code($_POST['item_code'], $_POST['stock_id'],
+ $_POST['description'], $_POST['category_id'], $_POST['quantity'], 1);
+
+ display_notification(_("New item code has been added."));
+ } else
+ {
+ update_item_code($selected_id, $_POST['item_code'], $_POST['stock_id'],
+ $_POST['description'], $_POST['category_id'], $_POST['quantity'], 1);
+
+ display_notification(_("Item code has been updated."));
+ }
+ $Mode = 'RESET';
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+
+if ($Mode == 'Delete')
+{
+ delete_item_code($selected_id);
+
+ display_notification(_("The purchasing data item has been sucessfully deleted."));
+ $Mode = 'RESET';
+}
+
+if ($Mode == 'RESET')
+{
+ $selected_id = -1;
+ unset($_POST);
+}
+
+if (list_updated('stock_id'))
+ $Ajax->activate('_page_body');
+
+//--------------------------------------------------------------------------------------------------
+
+start_form(false, true);
+
+if (!isset($_POST['stock_id']))
+ $_POST['stock_id'] = get_global_stock_item();
+
+echo "<center>" . _("Item:"). " ";
+stock_purchasable_items_list('stock_id', $_POST['stock_id'], false, true);
+
+echo "<hr></center>";
+
+set_global_stock_item($_POST['stock_id']);
+
+$result = get_item_code_dflts($_POST['stock_id']);
+$dec = $result['decimals'];
+$units = $result['units'];
+$dflt_desc = $result['description'];
+$dflt_cat = $result['category_id'];
+
+$result = get_all_item_codes($_POST['stock_id']);
+div_start('code_table');
+ start_table("$table_style width=60%");
+
+ $th = array(_("EAN/UPC Code"), _("Quantity"), _("Units"),
+ _("Description"),_("Category"), "", "");
+
+ table_header($th);
+
+ $k = $j = 0; //row colour counter
+
+ while ($myrow = db_fetch($result))
+ {
+ alt_table_row_color($k);
+
+ label_cell($myrow["item_code"]);
+ qty_cell($myrow["quantity"], $dec);
+ label_cell($units);
+ label_cell($myrow["description"]);
+ label_cell($myrow["cat_name"]);
+ edit_button_cell("Edit".$myrow['id'], _("Edit"));
+ edit_button_cell("Delete".$myrow['id'], _("Delete"));
+ end_row();
+
+ $j++;
+ If ($j == 12)
+ {
+ $j = 1;
+ table_header($th);
+ } //end of page full new headings
+ } //end of while loop
+
+ end_table();
+div_end();
+
+//-----------------------------------------------------------------------------------------------
+
+if ($Mode =='Edit')
+{
+ $myrow = get_item_code($selected_id);
+ $_POST['item_code'] = $myrow["item_code"];
+ $_POST['quantity'] = $myrow["quantity"];
+ $_POST['description'] = $myrow["description"];
+ $_POST['category_id'] = $myrow["category_id"];
+}
+ else {
+ $_POST['quantity'] = 1;
+ $_POST['description'] = $dflt_desc;
+ $_POST['category_id'] = $dflt_cat;
+}
+
+echo "<br>";
+hidden('selected_id', $selected_id);
+start_table($table_style2);
+
+hidden('code_id', $selected_id);
+
+text_row(_("UPC/EAN code:"), 'item_code', null, 20, 21);
+qty_row(_("Quantity:"), 'quantity', null, '', $units, $dec);
+text_row(_("Description:"), 'description', null, 50, 200);
+stock_categories_list_row(_("Category:"), 'category_id', null);
+
+end_table(1);
+
+submit_add_or_update_center($selected_id == -1, '', true);
+
+end_form();
+end_page();
+
+?>
set_focus('NewStockID');
}
-
+ elseif ($new_item && db_num_rows(get_item_kit($_POST['NewStockID'])))
+ {
+ $input_error = 1;
+ display_error( _("This item code is already assigned to stock item or sale kit."));
+ set_focus('NewStockID');
+ }
+
if ($input_error != 1)
{
display_error(_('Cannot delete this item because there are existing purchase order items for it.'));
return false;
}
-
+ $kits = get_where_used($stock_id);
+ $num_kits = db_num_rows($kits);
+ if ($num_kits) {
+ $msg = _("This item cannot be deleted because some code aliases
+ or foreign codes was entered for it, or there are kits defined
+ using this item as component")
+ .':<br>';
+
+ while($num_kits--) {
+ $kit = db_fetch($kits);
+ $msg .= "'".$kit[0]."'";
+ if ($num_kits) $msg .= ',';
+ }
+ display_error($msg);
+ return false;
+ }
return true;
}
--- /dev/null
+<?php
+
+$page_security = 11;
+$path_to_root="../..";
+include_once($path_to_root . "/includes/session.inc");
+
+page(_("Sales Kits & Alias Codes"));
+
+include_once($path_to_root . "/includes/date_functions.inc");
+include_once($path_to_root . "/includes/ui.inc");
+include_once($path_to_root . "/includes/data_checks.inc");
+
+include_once($path_to_root . "/includes/manufacturing.inc");
+
+check_db_has_stock_items(_("There are no items defined in the system."));
+
+simple_page_mode(true);
+/*
+if (isset($_GET['item_code']))
+{
+ $_POST['item_code'] = $_GET['item_code'];
+ $selected_kit = $_GET['item_code'];
+}
+*/
+//--------------------------------------------------------------------------------------------------
+function display_kit_items($selected_kit)
+{
+ global $table_style;
+
+ $result = get_item_kit($selected_kit);
+div_start('bom');
+ start_table("$table_style width=60%");
+ $th = array(_("Stock Item"), _("Description"), _("Quantity"), _("Units"),
+ '','');
+ table_header($th);
+
+ $k = 0;
+ while ($myrow = db_fetch($result))
+ {
+
+ alt_table_row_color($k);
+
+ label_cell($myrow["stock_id"]);
+ label_cell($myrow["comp_name"]);
+ qty_cell($myrow["quantity"], false,
+ $myrow["units"] == '' ? 0 : get_qty_dec($myrow["comp_name"]));
+ label_cell($myrow["units"] == '' ? _('kit') : $myrow["units"]);
+ edit_button_cell("Edit".$myrow['id'], _("Edit"));
+ edit_button_cell("Delete".$myrow['id'], _("Delete"));
+ end_row();
+
+ } //END WHILE LIST LOOP
+ end_table();
+div_end();
+}
+
+//--------------------------------------------------------------------------------------------------
+
+function update_component($kit_code, $selected_item)
+{
+ global $Mode, $Ajax, $selected_kit;
+
+ if (!check_num('quantity', 0))
+ {
+ display_error(_("The quantity entered must be numeric and greater than zero."));
+ set_focus('quantity');
+ return;
+ }
+ elseif ($_POST['description'] == '')
+ {
+ display_error( _("Item code description cannot be empty."));
+ set_focus('description');
+ return;
+ }
+ elseif ($selected_item == -1) // adding new item or new alias/kit
+ {
+ if (get_post('item_code') == '') { // New kit/alias definition
+ $kit = get_item_kit($_POST['item_code']);
+ if (db_num_rows($kit)) {
+ $input_error = 1;
+ display_error( _("This item code is already assigned to stock item or sale kit."));
+ set_focus('kit_code');
+ return;
+ }
+ if (get_post('kit_code') == '') {
+ display_error( _("Kit/alias code cannot be empty."));
+ set_focus('kit_code');
+ return;
+ }
+ }
+ }
+
+ if (check_item_in_kit($selected_item, $kit_code, $_POST['component'], true)) {
+ display_error(_("The selected component contains directly or on any lower level the kit under edition. Recursive kits are not allowed."));
+ set_focus('component');
+ return;
+ }
+
+ /*Now check to see that the component is not already in the kit */
+ if (check_item_in_kit($selected_item, $kit_code, $_POST['component'])) {
+ display_error(_("The selected component is already in this kit. You can modify it's quantity but it cannot appear more than once in the same kit."));
+ set_focus('component');
+ return;
+ }
+ if ($selected_item == -1) { // new item alias/kit
+ if ($_POST['item_code']=='') {
+ $kit_code = $_POST['kit_code'];
+ $selected_kit = $_POST['item_code'] = $kit_code;
+ $msg = _("New alias code has been created.");
+ }
+ else
+ $msg =_("New component has been added to selected kit.");
+
+ add_item_code( $kit_code, get_post('component'), get_post('description'),
+ get_post('category'), input_num('quantity'), 0);
+ display_notification($msg);
+
+ } else {
+ $props = get_kit_props($_POST['item_code']);
+ update_item_code($selected_item, $kit_code, get_post('component'),
+ $props['description'], $props['category_id'], input_num('quantity'), 0);
+ display_notification(_("Component of selected kit has been updated."));
+ }
+ $Mode = 'RESET';
+ $Ajax->activate('_page_body');
+}
+
+//--------------------------------------------------------------------------------------------------
+
+if (get_post('update_name')) {
+ update_kit_props(get_post('item_code'), get_post('description'), get_post('category'));
+ display_notification(_('Kit common properties has been updated'));
+ $Ajax->activate('_page_body');
+}
+
+if ($Mode=='ADD_ITEM' || $Mode=='UPDATE_ITEM')
+ update_component($_POST['item_code'], $selected_id);
+
+if ($Mode == 'Delete')
+{
+ // Before removing last component from selected kit check
+ // if selected kit is not included in any other kit.
+ //
+ $other_kits = get_where_used($_POST['item_code']);
+ $num_kits = db_num_rows($other_kits);
+ if ($num_kits) {
+ $msg = _("This item cannot be deleted because it is the last item in the kit used by following kits")
+ .':<br>';
+
+ while($num_kits--) {
+ $kit = db_fetch($other_kits);
+ $msg .= "'".$kit[0]."'";
+ if ($num_kits) $msg .= ',';
+ }
+ display_error($msg);
+ } else {
+ delete_item_code($selected_id);
+ display_notification(_("The component item has been deleted from this bom"));
+ $Mode = 'RESET';
+ }
+}
+
+if ($Mode == 'RESET')
+{
+ $selected_id = -1;
+ unset($_POST['quantity']);
+ unset($_POST['component']);
+}
+
+//--------------------------------------------------------------------------------------------------
+
+start_form(false, true);
+
+echo "<center>" . _("Select a sale kit:") . " ";
+sales_kits_list('item_code', null, _('New kit'), true);
+echo "</center><br>";
+$props = get_kit_props($_POST['item_code']);
+
+if (isset($_POST['_item_code_update'])) {
+ if (get_post('item_code') == '')
+ $_POST['description'] = '';
+ $Ajax->activate('_page_body');
+}
+
+$selected_kit = $_POST['item_code'];
+//----------------------------------------------------------------------------------
+if (get_post('item_code') == '') {
+// New sales kit entry
+ start_table($table_style2);
+ text_row(_("Alias/kit code:"), 'kit_code', null, 20, 21);
+} else
+{ // Kit selected so display bom or edit component
+ $_POST['description'] = $props['description'];
+ $_POST['category'] = $props['category_id'];
+ start_table($table_style2);
+ text_row(_("Description:"), 'description', null, 50, 200);
+ stock_categories_list_row(_("Category:"), 'category', null);
+ submit_row('update_name', _("Update"), false, 'align=center colspan=2', _('Update kit/alias name'), true);
+ end_row();
+ end_table(1);
+ display_kit_items($selected_kit);
+ echo '<br>';
+ start_table($table_style2);
+}
+
+ if ($Mode == 'Edit') {
+ $myrow = get_item_code($selected_id);
+ $_POST['component'] = $myrow["stock_id"];
+ $_POST['quantity'] = number_format2($myrow["quantity"], get_qty_dec($myrow["stock_id"]));
+ }
+ hidden("selected_id", $selected_id);
+
+ sales_local_items_list_row(_("Component:"),'component', null, false, true);
+
+// if (get_post('description') == '')
+// $_POST['description'] = get_kit_name($_POST['component']);
+ if (get_post('item_code') == '') { // new kit/alias
+ $_POST['description'] = $props['description'];
+ $_POST['category'] = $props['category_id'];
+ text_row(_("Description:"), 'description', null, 50, 200);
+ stock_categories_list_row(_("Category:"), 'category', null);
+ }
+ $res = get_item_edit_info(get_post('component'));
+ $dec = $res["decimals"] == '' ? 0 : $res["decimals"];
+ $units = $res["units"] == '' ? _('kits') : $res["units"];
+ if (list_updated('component'))
+ {
+ $_POST['quantity'] = number_format2(1, $dec);
+ $Ajax->activate('quantity');
+ $Ajax->activate('category');
+ }
+ qty_row(_("Quantity:"), 'quantity', null, '', $units, $dec);
+
+ end_table(1);
+ submit_add_or_update_center($selected_id == -1, '', true);
+ end_form();
+//----------------------------------------------------------------------------------
+
+end_page();
+
+?>
$_POST['stock_id'] = get_global_stock_item();
echo "<center>" . _("Item:"). " ";
-stock_items_list('stock_id', $_POST['stock_id'], false, true);
+sales_items_list('stock_id', $_POST['stock_id'], false, true);
echo "<hr></center>";
set_global_stock_item($_POST['stock_id']);
// after change of stock, currency or salestype selector
// display default calculated price for new settings.
// If we have this price already in db it is overwritten later.
- $_POST['price'] = price_format(get_price(get_post('stock_id'),
+ $_POST['price'] = price_format(get_kit_price(get_post('stock_id'),
get_post('curr_abrev'), get_post('sales_type_id')));
$Ajax->activate('price_details');
}
$factor = $myrow['factor'];
}
- $sql = "SELECT ".TB_PREF."prices.price
+ $sql = "SELECT price
FROM ".TB_PREF."prices
- WHERE ".TB_PREF."prices.stock_id = '" . $stock_id . "' "
- ." AND ".TB_PREF."prices.sales_type_id = " . $sales_type_id
- ." AND ".TB_PREF."prices.curr_abrev = '$currency'";
+ WHERE stock_id = '" . $stock_id . "' "
+ ." AND sales_type_id = " . $sales_type_id
+ ." AND curr_abrev = '$currency'";
$msg = "There was a problem retrieving the pricing information for the part $stock_id for customer";
$result = db_query($sql, $msg);
$myrow = db_fetch_row($result);
return $myrow[0];
}
- if ($factor == 0) return 0; // auto price calculations off
+ if ($factor == 0) return false; // auto price calculations off
$base_id = get_base_sales_type();
$home_curr = get_company_currency();
// get all prices which we can use to guess the price.
// alternative is make up to 2 additional sql queries
- $sql = "SELECT ".TB_PREF."prices.price,".TB_PREF."prices.curr_abrev,
- ".TB_PREF."prices.sales_type_id
+ $sql = "SELECT price, curr_abrev, sales_type_id
FROM ".TB_PREF."prices
- WHERE ".TB_PREF."prices.stock_id = '" . $stock_id . "' "
- ." AND (".TB_PREF."prices.sales_type_id = " . $sales_type_id
- ." OR ".TB_PREF."prices.sales_type_id = " . $base_id.")"
- ." AND (".TB_PREF."prices.curr_abrev = '$currency'"
- ." OR ".TB_PREF."prices.curr_abrev = '$home_curr')";
+ WHERE stock_id = '" . $stock_id . "' "
+ ." AND (sales_type_id = " . $sales_type_id
+ ." OR sales_type_id = " . $base_id.")"
+ ." AND (curr_abrev = '$currency'"
+ ." OR curr_abrev = '$home_curr')";
$result = db_query($sql, $msg);
$rate = round(get_exchange_rate_from_home_currency($currency, $date),
user_exrate_dec());
- $price = 0.00;
+ $price = false;
if (isset($prices[$sales_type_id][$home_curr]))
{
}
if (isset($prices[$base_id][$currency]))
{
- $price =$prices[$base_id][$currency] * $factor;
+ $price = $prices[$base_id][$currency] * $factor;
}
if (isset($prices[$base_id][$home_curr]))
{
- $price =$prices[$base_id][$home_curr] * $factor / $rate;
+ $price = $prices[$base_id][$home_curr] * $factor / $rate;
}
- return round($price, user_price_dec());
+ return $price === false ? false : round($price, user_price_dec());
+}
+//----------------------------------------------------------------------------------------
+//
+// Get price for given item or kit.
+// When $std==true price is calculated as a sum of all included stock items,
+// otherwise all prices set for kits and items are accepted.
+//
+function get_kit_price($item_code, $currency, $sales_type_id, $factor=null,
+ $date=null, $std = false)
+{
+ $kit_price = 0.00;
+ if (!$std) {
+ $kit_price = get_price( $item_code, $currency, $sales_type_id,
+ $factor, $date);
+
+ if ($kit_price !== false) {
+ return $kit_price;
+ }
+ }
+ // no price for kit found, get total value of all items
+ $kit = get_item_kit($item_code);
+
+ while($item = db_fetch($kit)) {
+ if ($item['item_code'] != $item['stock_id']) {
+ // foreign/kit code
+ $kit_price += $item['quantity'] * get_kit_price( $item['stock_id'],
+ $currency, $sales_type_id, $factor, $date, $std);
+
+ } else {
+ // stock item
+ $kit_price += $item['quantity'] * get_price( $item['stock_id'],
+ $currency, $sales_type_id, $factor, $date);
+ }
+ }
+ return $kit_price;
}
//-----------------------------------------------------------------------------
$result = get_customer_trans_details($doc_type,$trans_no);
if (db_num_rows($result) > 0) {
for($line_no=0; $myrow = db_fetch($result); $line_no++) {
- $cart->add_to_cart($line_no,$myrow["stock_id"],$myrow["quantity"],
+ $cart->line_items[$line_no] = new line_details(
+ $myrow["stock_id"],$myrow["quantity"],
$myrow["unit_price"], $myrow["discount_percent"],
$myrow["qty_done"], $myrow["standard_cost"],
$myrow["StockDescription"],$myrow["id"], $myrow["debtor_trans_no"]);
//--------------------------------------------------------------------------------
function add_to_order(&$order, $new_item, $new_item_qty, $price, $discount)
{
+ // calculate item price to sum of kit element prices factor for
+ // value distribution over all exploded kit items
+ $std_price = get_kit_price($new_item, $order->customer_currency,
+ $order->sales_type, $order->price_factor, get_post('OrderDate'), true);
- foreach ($order->line_items AS $order_item)
- {
- if (strcasecmp($order_item->stock_id, $new_item) == 0)
+ if ($std_price == 0)
+ $price_factor = 0;
+ else
+ $price_factor = $price/$std_price;
+
+ $kit = get_item_kit($new_item);
+ $item_num = db_num_rows($kit);
+
+ while($item = db_fetch($kit)) {
+ $std_price = get_kit_price($item['stock_id'], $order->customer_currency,
+ $order->sales_type, $order->price_factor, get_post('OrderDate'), true);
+
+ // rounding differences are included in last price item in kit
+ $item_num--;
+ if ($item_num) {
+ $price -= $item['quantity']*$std_price*$price_factor;
+ $item_price = $std_price*$price_factor;
+ } else {
+ if ($item['quantity'])
+ $price = $price/$item['quantity'];
+ $item_price = $price;
+ }
+ $item_price = round($item_price, user_price_dec());
+
+ 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);
+ }
+ else
+ { // stock item record eventually with foreign code
+
+ // check duplicate stock item
+ foreach ($order->line_items as $order_item)
{
- display_notification(_("For Part :") . $new_item . " " . _("This item is already on this order. You have been warned."));
- break;
+ if (strcasecmp($order_item->stock_id, $item['stock_id']) == 0)
+ {
+ display_notification(_("For Part :").$item['stock_id']. " "
+ . _("This item is already on this order. You have been warned."));
+ break;
+ }
}
+ $order->add_to_cart (count($order->line_items), $item['stock_id'],
+ $new_item_qty*$item['quantity'], $item_price, $discount);
+ }
}
-
- $order->add_to_cart (count($order->line_items),$new_item, $new_item_qty, $price, $discount);
}
-
//---------------------------------------------------------------------------------
function get_customer_details_to_order(&$order, $customer_id, $branch_id)
if ($change_prices != 0) {
foreach ($order->line_items as $line_no=>$item) {
$line = &$order->line_items[$line_no];
- $line->price = get_price($line->stock_id, $order->customer_currency,
+ $line->price = get_kit_price($line->stock_id, $order->customer_currency,
$order->sales_type, $order->price_factor, get_post('OrderDate'));
// $line->discount_percent = $order->default_discount;
}
alt_table_row_color($rowcounter);
$id = find_submit('Edit');
- if ($line_no!=-1 && $line_no == $id)
+ if ($line_no!=-1 && $line_no == $id) // edit old line
{
$_POST['stock_id'] = $order->line_items[$id]->stock_id;
$dec = get_qty_dec($_POST['stock_id']);
label_cell($order->line_items[$line_no]->item_description, "nowrap");
$Ajax->activate('items_table');
}
- else
+ else // prepare new line
{
- stock_items_list_cells(null,'stock_id', null, false, true);
+ sales_items_list_cells(null,'stock_id', null, false, true);
if (list_updated('stock_id')) {
$Ajax->activate('price');
$Ajax->activate('units');
$item_info = get_item_edit_info($_POST['stock_id']);
$units = $item_info["units"];
- $dec = get_qty_dec($_POST['stock_id']);
+ $dec = $item_info['decimals'];
$_POST['qty'] = number_format2(1, $dec);
-
- $_POST['price'] = price_format(get_price ($_POST['stock_id'],
+ $price = get_kit_price($_POST['stock_id'],
$order->customer_currency, $order->sales_type,
- $order->price_factor, get_post('OrderDate')));
+ $order->price_factor, get_post('OrderDate'));
+ $_POST['price'] = price_format($price);
// default to the customer's discount %
$_POST['Disc'] = percent_format($order->default_discount * 100);
-
}
qty_cells(null, 'qty', $_POST['qty'], null, null, $dec);