From 19dce8c7be29e4cc8e7be92d044259348373d456 Mon Sep 17 00:00:00 2001 From: Janusz Dobrowolski Date: Wed, 18 Feb 2015 13:13:33 +0100 Subject: [PATCH] Transaction references extended with parametrized patterns, added check_reference() ui helper, initial transaction reference pattern set to {001}/{YYYY}. --- admin/db/fiscalyears_db.inc | 3 +- admin/db/transactions_db.inc | 12 +- admin/forms_setup.php | 56 +- applications/setup.php | 2 +- dimensions/dimension_entry.php | 13 +- gl/bank_transfer.php | 14 +- gl/gl_bank.php | 15 +- gl/gl_journal.php | 12 +- gl/includes/db/gl_db_banking.inc | 6 +- gl/includes/db/gl_db_trans.inc | 1 + gl/includes/ui/gl_bank_ui.inc | 2 +- gl/manage/revaluate_currencies.php | 12 +- includes/data_checks.inc | 14 + includes/db/class.data_set.inc | 518 ++++++++++++ includes/db/class.reflines_db.inc | 179 +++++ includes/db/inventory_db.inc | 2 +- includes/db/references_db.inc | 122 --- includes/references.inc | 387 ++++++++- includes/ui/class.crud_view.inc | 756 ++++++++++++++++++ includes/ui/class.reflines_crud.inc | 115 +++ includes/ui/ui_input.inc | 61 +- includes/ui/ui_lists.inc | 34 + includes/ui/ui_view.inc | 2 +- inventory/adjustments.php | 9 +- inventory/includes/item_adjustments_ui.inc | 4 +- inventory/includes/stock_transfers_ui.inc | 3 +- inventory/transfers.php | 9 +- .../includes/db/work_order_costing_db.inc | 10 +- .../includes/work_order_issue_ui.inc | 9 +- manufacturing/work_order_add_finished.php | 15 +- manufacturing/work_order_costs.php | 2 +- manufacturing/work_order_entry.php | 12 +- manufacturing/work_order_issue.php | 14 +- purchasing/includes/db/invoice_db.inc | 2 +- purchasing/includes/purchasing_db.inc | 2 +- purchasing/includes/ui/grn_ui.inc | 2 +- purchasing/includes/ui/invoice_ui.inc | 6 +- purchasing/includes/ui/po_ui.inc | 3 +- purchasing/po_entry_items.php | 12 +- purchasing/po_receive_items.php | 13 +- purchasing/supplier_credit.php | 17 +- purchasing/supplier_invoice.php | 17 +- purchasing/supplier_payment.php | 14 +- sales/create_recurrent_invoices.php | 6 +- sales/credit_note_entry.php | 2 +- sales/customer_credit_invoice.php | 7 +- sales/customer_delivery.php | 7 +- sales/customer_invoice.php | 7 +- sales/customer_payments.php | 23 +- sales/includes/cart_class.inc | 6 +- sales/includes/db/sales_invoice_db.inc | 4 +- sales/includes/db/sales_order_db.inc | 2 - sales/includes/ui/sales_credit_ui.inc | 3 +- sales/includes/ui/sales_order_ui.inc | 2 +- sales/sales_order_entry.php | 6 +- sql/alter2.4.sql | 17 + sql/en_US-demo.sql | 84 +- sql/en_US-new.sql | 83 +- 58 files changed, 2244 insertions(+), 528 deletions(-) create mode 100644 includes/db/class.data_set.inc create mode 100644 includes/db/class.reflines_db.inc delete mode 100644 includes/db/references_db.inc create mode 100644 includes/ui/class.crud_view.inc create mode 100644 includes/ui/class.reflines_crud.inc diff --git a/admin/db/fiscalyears_db.inc b/admin/db/fiscalyears_db.inc index 9051e475..f9b4d415 100644 --- a/admin/db/fiscalyears_db.inc +++ b/admin/db/fiscalyears_db.inc @@ -160,7 +160,7 @@ function close_year($year) if ($balance != 0.0) { $cart = new items_cart(ST_JOURNAL); - $cart->reference = $Refs->get_next(ST_JOURNAL, null, $to); + $cart->reference = $Refs->get_next(ST_JOURNAL, null, sql2date($to)); $cart->tran_date = $cart->doc_date = $cart->event_date = $to; $cart->add_gl_item($co['retained_earnings_act'], 0, 0, -$balance, _("Closing Year"), '', 0); @@ -372,6 +372,7 @@ function delete_this_fiscalyear($selected_id) $trans_type = ST_JOURNAL; $date_ = sql2date($to); $reference = $Refs->get_next($trans_type, null, $date_); + $Refs->save($trans_type, $trans_no, $reference); add_journal($trans_type, $trans_no, $total, $date_, get_company_currency(), $reference); $Refs->save($trans_type, $trans_no, $reference); add_audit_trail($trans_type, $trans_no, $date_); diff --git a/admin/db/transactions_db.inc b/admin/db/transactions_db.inc index d3e3cfc5..d343b7c4 100644 --- a/admin/db/transactions_db.inc +++ b/admin/db/transactions_db.inc @@ -36,8 +36,6 @@ function get_sql_for_view_transactions($filtertype, $from, $to, &$trans_ref) $sql .= ", t.$type_name as type"; $sql .= " FROM $table_name t LEFT JOIN ".TB_PREF."voided v ON" ." t.$trans_no_name=v.id AND v.type=$filtertype"; - if (!$trans_ref) - $sql .= " LEFT JOIN ".TB_PREF."refs r ON t.$trans_no_name=r.id AND r.type=$filtertype"; $sql .= " WHERE ISNULL(v.`memo_`)"; if ($from != null && $to != null) @@ -209,16 +207,8 @@ function get_systype_db_info($type) case 31 : return array(TB_PREF."service_orders", null, "order_no", "cust_ref", "date"); case ST_SALESQUOTE : return array(TB_PREF."sales_orders", "trans_type", "order_no", "reference", "ord_date"); case ST_DIMENSION : return array(TB_PREF."dimensions", null, "id", "reference", "date_"); - case ST_COSTUPDATE : return array(TB_PREF."gl_trans", "type", "type_no", null, "tran_date"); + case ST_COSTUPDATE : return array(TB_PREF."journal", "type", "trans_no", "reference", "tran_date"); } display_db_error("invalid type ($type) sent to get_systype_db_info", "", true); } - -function get_systypes() -{ - $sql = "SELECT * FROM ".TB_PREF."sys_types"; - $result = db_query($sql, "could not query systypes table"); - return $result; -} - diff --git a/admin/forms_setup.php b/admin/forms_setup.php index 5a91d31e..a2895ab6 100644 --- a/admin/forms_setup.php +++ b/admin/forms_setup.php @@ -10,59 +10,21 @@ See the License here . ***********************************************************************/ $page_security = 'SA_FORMSETUP'; -$path_to_root = ".."; -include($path_to_root . "/includes/session.inc"); +$path_to_root=".."; -page(_($help_context = "Forms Setup")); +include_once($path_to_root . "/includes/session.inc"); +include_once('../includes/ui/class.reflines_crud.inc'); -include($path_to_root . "/includes/ui.inc"); +include_once($path_to_root . "/includes/ui.inc"); -//------------------------------------------------------------------------------------------------- - -if (isset($_POST['setprefs'])) -{ - - $systypes = get_systypes(); - - begin_transaction(); - - while ($type = db_fetch($systypes)) - { - save_next_reference($type["type_id"], $_POST['id' . $type["type_id"]]); - } - - commit_transaction(); - - display_notification_centered(_("Forms settings have been updated.")); -} +page(_($help_context = "Transaction References")); start_form(); -start_outer_table(TABLESTYLE2); - -$systypes = get_systypes(); -table_section(1); - -$th = array(_("Form"), _("Next Reference")); -table_header($th); -$i = 0; -while ($type = db_fetch($systypes)) -{ - if ($i++ == ST_CUSTCREDIT) - { - table_section(2); - table_header($th); - } - ref_row($systypes_array[$type["type_id"]], 'id' . $type["type_id"], '', $type["next_reference"]); -} - -end_outer_table(1); - -submit_center('setprefs', _("Update"), true, '', 'default'); - -end_form(2); +$companies = new fa_reflines(); -//------------------------------------------------------------------------------------------------- +$companies->show(); -end_page(); +end_form(); +end_page(); \ No newline at end of file diff --git a/applications/setup.php b/applications/setup.php index e29817be..99fa48d5 100644 --- a/applications/setup.php +++ b/applications/setup.php @@ -24,7 +24,7 @@ class setup_app extends application "admin/security_roles.php?", 'SA_SECROLES', MENU_SETTINGS); $this->add_lapp_function(0, _("&Display Setup"), "admin/display_prefs.php?", 'SA_SETUPDISPLAY', MENU_SETTINGS); - $this->add_lapp_function(0, _("&Forms Setup"), + $this->add_lapp_function(0, _("Transaction &References"), "admin/forms_setup.php?", 'SA_FORMSETUP', MENU_SETTINGS); $this->add_rapp_function(0, _("&Taxes"), "taxes/tax_types.php?", 'SA_TAXRATES', MENU_MAINTENANCE); diff --git a/dimensions/dimension_entry.php b/dimensions/dimension_entry.php index 7809bd1b..f46be106 100644 --- a/dimensions/dimension_entry.php +++ b/dimensions/dimension_entry.php @@ -109,17 +109,8 @@ function can_process() if ($selected_id == -1) { - - if (!$Refs->is_valid($_POST['ref'])) - { - display_error( _("The dimension reference must be entered.")); - set_focus('ref'); - return false; - } - - if (!is_new_reference($_POST['ref'], ST_DIMENSION)) + if (!check_reference($_POST['ref'], ST_DIMENSION)) { - display_error(_("The entered reference is already in use.")); set_focus('ref'); return false; } @@ -264,7 +255,7 @@ if ($selected_id != -1) else { $_POST['dimension_tags'] = array(); - ref_row(_("Dimension Reference:"), 'ref', '', $Refs->get_next(ST_DIMENSION)); + ref_row(_("Dimension Reference:"), 'ref', '', $Refs->get_next(ST_DIMENSION), false, ST_DIMENSION); } text_row_ex(_("Name") . ":", 'name', 50, 75); diff --git a/gl/bank_transfer.php b/gl/bank_transfer.php index 7b987636..3ebc2453 100644 --- a/gl/bank_transfer.php +++ b/gl/bank_transfer.php @@ -87,7 +87,7 @@ function gl_payment_controls($trans_no) $_POST['target_amount'] = price_format($to_trans['amount']); $_POST['amount'] = price_format(-$from_trans['amount']); } else { - $_POST['ref'] = $Refs->get_next(ST_BANKTRANSFER); + $_POST['ref'] = $Refs->get_next(ST_BANKTRANSFER, null, get_post('DatePaid')); $_POST['memo_'] = ''; $_POST['FromBankAccount'] = 0; $_POST['ToBankAccount'] = 0; @@ -115,7 +115,8 @@ function gl_payment_controls($trans_no) } date_row(_("Transfer Date:"), 'DatePaid', '', true, 0, 0, 0, null, true); - ref_row(_("Reference:"), 'ref', '', $_POST['ref']); + ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_BANKTRANSFER, null, get_post('DatePaid')), false, ST_BANKTRANSFER, + array('date' => get_post('DatePaid'))); table_section(2); @@ -232,15 +233,8 @@ function check_valid_entries($trans_no) set_focus('charge'); return false; } - if (!$Refs->is_valid($_POST['ref'])) - { - display_error(_("You must enter a reference.")); - set_focus('ref'); - return false; - } - if (! $trans_no && ! is_new_reference($_POST['ref'], ST_BANKTRANSFER)) { - display_error(_("The entered reference is already in use.")); + if (!check_reference($_POST['ref'], ST_BANKTRANSFER, $trans_no)) { set_focus('ref'); return false; } diff --git a/gl/gl_bank.php b/gl/gl_bank.php index b965f1d5..3d3f86e6 100644 --- a/gl/gl_bank.php +++ b/gl/gl_bank.php @@ -153,7 +153,8 @@ function create_cart($type, $trans_no) $bank_trans = db_fetch(get_bank_trans($type, $trans_no)); $_POST['bank_account'] = $bank_trans["bank_act"]; $_POST['PayType'] = $bank_trans["person_type_id"]; - + $cart->reference = $bank_trans["ref"]; + if ($bank_trans["person_type_id"] == PT_CUSTOMER) { $trans = get_customer_trans($trans_no, $type); @@ -174,7 +175,6 @@ function create_cart($type, $trans_no) $cart->memo_ = get_comments_string($type, $trans_no); $cart->tran_date = sql2date($bank_trans['trans_date']); - $cart->reference = $Refs->get($type, $trans_no); $cart->original_amount = $bank_trans['amount']; $result = get_gl_trans($type, $trans_no); @@ -197,7 +197,7 @@ function create_cart($type, $trans_no) $cart->gl_items[$line_no]->amount *= $ex_rate; } else { - $cart->reference = $Refs->get_next($cart->trans_type); + $cart->reference = $Refs->get_next($cart->trans_type, null, $cart->tran_date); $cart->tran_date = new_doc_date(); if (!is_date_in_fiscalyear($cart->tran_date)) $cart->tran_date = end_fiscalyear(); @@ -246,15 +246,8 @@ function check_trans() set_focus('amount'); $input_error = 1; } - if (!$Refs->is_valid($_POST['ref'])) - { - display_error( _("You must enter a reference.")); - set_focus('ref'); - $input_error = 1; - } - elseif ($_POST['ref'] != $_SESSION['pay_items']->reference && !is_new_reference($_POST['ref'], $_SESSION['pay_items']->trans_type)) + if (!check_reference($_POST['ref'], $_SESSION['pay_items']->trans_type, $_SESSION['pay_items']->order_id)) { - display_error( _("The entered reference is already in use.")); set_focus('ref'); $input_error = 1; } diff --git a/gl/gl_journal.php b/gl/gl_journal.php index f2defddc..e057d098 100644 --- a/gl/gl_journal.php +++ b/gl/gl_journal.php @@ -130,8 +130,6 @@ function create_cart($type=0, $trans_no=0) $cart->memo_ = get_comments_string($type, $trans_no); $cart->reference = $header['reference']; - $_POST['ref_original'] = $cart->reference; // Store for comparison when updating - // update net_amounts from tax register // retrieve tax details @@ -164,7 +162,6 @@ function create_cart($type=0, $trans_no=0) if (!is_date_in_fiscalyear($cart->tran_date)) $cart->tran_date = end_fiscalyear(); $cart->reference = $Refs->get_next(ST_JOURNAL, null, $cart->tran_date); - $_POST['ref_original'] = -1; } $_POST['memo_'] = $cart->memo_; @@ -239,15 +236,8 @@ if (isset($_POST['Process'])) set_focus('doc_date'); $input_error = 1; } - if (!$Refs->is_valid($_POST['ref'])) - { - display_error( _("You must enter a reference.")); - set_focus('ref'); - $input_error = 1; - } - elseif (($_POST['ref'] != $_POST['ref_original']) && $Refs->exists(ST_JOURNAL,$_POST['ref'])) + if (!check_reference($_POST['ref'], ST_JOURNAL, $_SESSION['journal_items']->order_id)) { - display_error( _("The entered reference is already in use.")); set_focus('ref'); $input_error = 1; } diff --git a/gl/includes/db/gl_db_banking.inc b/gl/includes/db/gl_db_banking.inc index 9d5b9693..095dadcd 100644 --- a/gl/includes/db/gl_db_banking.inc +++ b/gl/includes/db/gl_db_banking.inc @@ -156,7 +156,7 @@ function add_exchange_variation_all($date=null, $ref="", $memo) { add_comments(ST_JOURNAL, $trans_no, $date, $memo); if ($ref == "") - $ref = $Refs->get_next(ST_JOURNAL); + $ref = $Refs->get_next(ST_JOURNAL, null, $date); $Refs->save(ST_JOURNAL, $trans_no, $ref); add_audit_trail(ST_JOURNAL, $trans_no, $date); } @@ -288,7 +288,7 @@ function add_bank_transfer($from_account, $to_account, $date_, } if ($exchanged == true) { - $ref1 = $Refs->get_next(ST_JOURNAL); + $ref1 = $Refs->get_next(ST_JOURNAL, null, $date_); $Refs->save(ST_JOURNAL, $trans_no1, $ref1); add_audit_trail(ST_JOURNAL, $trans_no1, $date_); } @@ -525,7 +525,7 @@ function write_bank_transaction($trans_type, $trans_no, $from_account, $items, $ if ($exchanged || add_exchange_variation($trans_no1, $date_, $from_account, $bank_gl_account, $currency, $person_type_id, $person_id)) { - $ref1 = $Refs->get_next(ST_JOURNAL); + $ref1 = $Refs->get_next(ST_JOURNAL, null, $date_); $Refs->save(ST_JOURNAL, $trans_no1, $ref1); add_audit_trail(ST_JOURNAL, $trans_no1, $date_); } diff --git a/gl/includes/db/gl_db_trans.inc b/gl/includes/db/gl_db_trans.inc index c4fff50c..40187bb2 100644 --- a/gl/includes/db/gl_db_trans.inc +++ b/gl/includes/db/gl_db_trans.inc @@ -515,6 +515,7 @@ function get_tax_summary($from, $to, $also_zero_purchases=false) // display_error($sql); return db_query($sql,"Cannot retrieve tax summary"); } + //-------------------------------------------------------------------------------------------------- function exists_gl_trans($type, $trans_id) diff --git a/gl/includes/ui/gl_bank_ui.inc b/gl/includes/ui/gl_bank_ui.inc index ce3af74a..8e491712 100644 --- a/gl/includes/ui/gl_bank_ui.inc +++ b/gl/includes/ui/gl_bank_ui.inc @@ -23,7 +23,7 @@ function display_bank_header(&$order) date_row(_("Date:"), 'date_', '', true, 0, 0, 0, null, true); - ref_row(_("Reference:"), 'ref', ''); + ref_row(_("Reference:"), 'ref', '', $order->reference, false, $order->trans_type, get_post('date_')); table_section(2, "33%"); diff --git a/gl/manage/revaluate_currencies.php b/gl/manage/revaluate_currencies.php index c05237ac..f0141418 100644 --- a/gl/manage/revaluate_currencies.php +++ b/gl/manage/revaluate_currencies.php @@ -60,16 +60,8 @@ function check_data() set_focus('date'); return false; } - if (!$Refs->is_valid($_POST['ref'])) + if (!check_reference($_POST['ref'], ST_JOURNAL)) { - display_error(_("You must enter a reference.")); - set_focus('ref'); - return false; - } - - if (!is_new_reference($_POST['ref'], ST_JOURNAL)) - { - display_error(_("The entered reference is already in use.")); set_focus('ref'); return false; } @@ -102,7 +94,7 @@ function display_reval() if (!isset($_POST['date'])) $_POST['date'] = Today(); date_row(_("Date for Revaluation:"), 'date', '', null, 0, 0, 0, null, true); - ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_JOURNAL)); + ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_JOURNAL, null, $_POST['date']), false, ST_JOURNAL); textarea_row(_("Memo:"), 'memo_', null, 40,4); end_table(1); diff --git a/includes/data_checks.inc b/includes/data_checks.inc index 7ce8d668..7243e43f 100644 --- a/includes/data_checks.inc +++ b/includes/data_checks.inc @@ -524,3 +524,17 @@ function check_is_editable($trans_type, $trans_no, $msg=null) check_is_closed($trans_type, $trans_no, $msg); } +function check_reference($reference, $trans_type, $trans_no=0, $context=null, $line=null) +{ + global $Refs; + + if (!$Refs->is_valid($reference, $trans_type, $context, $line)) + { + display_error(_("The entered reference is invalid.")); return false; + } + elseif (!$Refs->is_new_reference($reference, $trans_type, $trans_no)) + { + display_error( _("The entered reference is already in use.")); return false; + } + return true; +} diff --git a/includes/db/class.data_set.inc b/includes/db/class.data_set.inc new file mode 100644 index 00000000..f536e13c --- /dev/null +++ b/includes/db/class.data_set.inc @@ -0,0 +1,518 @@ +. +***********************************************************************/ + +// array contains optional/required params for all supported validator types +// +$validator_types = array( + 'required' => array(), + 'range' => array('min'=>0, 'max' =>null, 'lt', 'gt', 'le', 'ge') +); + +/* + Generic record set object +*/ +abstract class record_set { + var $key; // unique key fields + var $fields; // other fields + var $name; // table name (without prefix) + var $checks = array(); // checks on data before insert/update/delete + + var $selected_id; // current key + var $data; // current record data + var $errors = array(); + var $debug = array(); + var $subset; // optional where clause for record subset + + function __wakeup() + { + $this->errors = array(); + } + + function record_set($name, $fields, $key, $subset=null) + { + $this->name = $name; + $this->fields = $fields; + $this->key = $key; + $this->subset = $subset; + } + + function error($msg, $field=null) { + global $db; + + // save error message + if (!isset($field)) + $field = count($this->errors); + $this->errors[$field] = $msg; + + // save db errors for debugging purposes + if ($db && db_error_no()) $this->debug[] = db_error_msg($db); + + return false; + } + //============================================================================================== + // + // Data valiation + + /** + * Set validator for insert/update/delete + * + * @check - validator description string in format: 'field_name:uid_modes:check_type[[:param1][:param2]...]' + * parameters can be expressed with name in form: name=value + * @msg - message stored on error + **/ + + function set_validator($check, $msg=null) + { + $params = explode(':', $check); + if (count($params)<3) + display_error(_('Invalid validator string')); + + $fieldname = array_shift($params); + $mode = array_shift($params); + $type = array_shift($params); + $options = array(); + if (count($params)) + { + foreach ($params as $par) { + if (($n = strpos($par, '=')) !== false) { + $options[substr($par, 0, $n)] = substr($par, $n+1); + } else + $options[] = $par; + } + } + $this->checks[] = array('fld'=>$fieldname, 'type' => $type, 'msg' => $msg, 'opts' => $options, 'mode'=>$mode); + } + + /** + * Validate data + * @key - record key (u/d) + * @data - data to be validated (i/u) + **/ + function _validate($key=null, $data) + { + $mode = isset($data) ? (isset($key) ? 'u' : 'i') : 'd'; + + foreach($this->checks as $check) { + + if (strpos($check['mode'], $mode) !== false) { + $msg = $check['msg']; + $fld = $check['fld']; + $opts = @$check['opts']; + + // precheck for existing + if ($mode == 'i' && $fld && !isset($data[$fld])) { + $msg = sprintf(_("Input parameter '%s' have to be set."), $check['fld']); + return $this->error($msg, $check['fld']); + } + + switch($check['type']) { + + case 'required': + if ($data[$fld]==='') { + if (!$msg) $msg = sprintf(_("Parameter '%s' cannot be empty.", $check['fld'])); + return $this->error($msg, $check['fld']); + } + break; + + case 'clean_file_name': + if (isset($data[$fld]) && ($data[$fld] != clean_file_name($data[$fld]))) { + if (!$msg) $msg = sprintf(_("Parameter '%s' contains invalid characters.", $check['fld'])); + return $this->error($msg, $check['fld']); + } + break; + + case 'range': + if (!$msg) $msg = sprintf(_("Parameter '%s' has invalid value.", $check['fld'])); + // TODO: check at least one named parameter is passed + if (isset($opts['lt']) && !($data[$fld] < $opts['lt']) || + (isset($opts['gt']) && !($data[$fld] > $opts['gt'])) || + (isset($opts['min']) && !($data[$fld] < $opts['min'])) || + (isset($opts['max']) && !($data[$fld] > $opts['max'])) ) + return $this->error($msg, $check['fld']); + +// case 'match': + break; + + // user defined checks + default: + $func = $check['type']; + if (method_exists($this, $func)) { + if (!$this->$func($data, $check['opts'], $key)) + return $this->error($msg, $check['fld']); + } else if (function_exists($func)) { + if (!$func($data, $key, $check['opts'], $key)) + return $this->error($msg, $check['fld']); + } + } + } + } + return true; + } + + /** + * + * Returns editable status for selected record. + * Array contains true for editable, false for readonly fields. + * This looks redundant ('forbidden' update_check could be used) + * but in fact the constraints are related to exact record, so changes with key. + **/ + function edit_status($key) + { + $editables = array(); + + // default: all but key fields editable + foreach ($this->fields as $fld=>$val) + $editables[$fld] = !in_array($fld, (array)$this->key); + + return $editables; + } + + + function delete_check($key) + { + return $this->_validate($key, null); + } + + function insert_check($data) + { + return $this->_validate(null, $data); + } + + function update_check($key, $data) + { + // Note: this does not allow change of key + return $this->_validate( $key, $data); + } + + //=========================================================================== + // Database functions placeholders + + // + // Generic read record routine + // + function get($key=null) + { + $defaults = array(); + // return all defined default values + foreach ($this->fields as $name => $def) + { + if(!is_numeric($name)) { + if (is_string($def)) + $defaults[$name] = $def; + elseif (isset($def['dflt'])) + $defaults[$name] = $def['dflt']; + } + } + return $defaults; + } + // + // Generic list record routine + // + abstract function get_all(); + // + // Generic update record routine + // + function update($key, $data) + { + if (!$this->update_check($key, $data)) + return false; + + return true; + } + // + // Generic delete record routine + // + function delete($key) + { + if (!$this->delete_check($key)) + return false; + + return true; + } + // + // Insert record + // + function insert($data) + { + if (!$this->insert_check($data)) + return false; + + return true; + } + +} + +class data_set extends record_set { + + function data_set($name, $fields, $key, $subset=null) + { + $this->record_set($name, $fields, $key, $subset); + } + + // + // Generic read record routine + // + function get($key=null) + { + if ($key===null) + return parent::get(); + + $sql = "SELECT * FROM ".TB_PREF.$this->name." WHERE "; + $where = $this->subset ? (array)$this->subset : array(); + + if (is_array($this->key)) { + foreach($this->key as $fld) + if (isset($key[$fld])) + $where[$fld] = "`$fld`=".db_escape($key[$fld]); + else + return $this->error(sprintf(_("Invalid key passed reading '%s'"), $this->name)); + } else { + $where = array($this->key => "`".$this->key."`=".db_escape($key)); + } + + $sql .= implode(' AND ', $where); + $result = db_query($sql); + if (!$result) + return $this->error("Cannot get record from ".$this->name); + + return $rec = db_num_rows($result) ? db_fetch_assoc($result) : null; + } + // + // Generic list record routine + // + function get_all($where=null, $order_by=null) + { + $fields = array(); + foreach($this->fields as $fld) + $fields[] = '`'.$fld.'`'; + $sql = "SELECT ".implode(',', $fields)." FROM ".TB_PREF.$this->name; + + if ($where) + $sql .= " WHERE ".($this->subset ? '('.$this->subset . ') AND ' : ''). $where; + if ($order_by) { + $order_by = (array)$order_by; + foreach($order_by as $i => $fld) + $order_by[$i] = '`'.$fld.'`'; + $sql .= " ORDER BY ".implode(',', (array)$order_by); + } + $result = db_query($sql); + if ($result==false) + return $this->error("Cannot get record from ".$this->name); + + return $result; + } + // + // Generic update record routine + // + function update($key, $data) + { + if (!parent::update($key, $data)) // validate data + return false; + + $sql = "UPDATE ".TB_PREF.$this->name." SET "; + $updates = array(); + + foreach($data as $fld => $value) { // select only data relevant for this model + if (in_array($fld, $this->fields)) + $updates[$fld] = "`$fld`=".db_escape($value); + } + if (count($updates) == 0) + return $this->error(_("Empty update data for table ").$this->name); + + $sql .= implode(',', $updates)." WHERE "; + $where = $this->subset ? (array)$this->subset : array(); + + if(is_array($this->key)) { // construct key phrase + foreach($this->key as $fld) + if (isset($key[$fld])) + $where[$fld] = "`$fld`=".db_escape($key[$fld]); + else + return $this->error(sprintf(_("Invalid key for update '%s'"), $this->name)); + } else { + $where = array("`".$this->key."`=".db_escape($key)); + } + + $sql .= implode(' AND ', $where); + $result = db_query($sql); + + if ($result===false) + return $this->error("cannot update record in ".$this->name); + + return $result; + } + // + // Generic delete record routine + // + function delete($key) + { + if (!parent::delete_check($key)) + return false; + + $sql = "DELETE FROM ".TB_PREF.$this->name; + $where = $this->subset ? (array)$this->subset : array(); + + if(is_array($this->key)) { + foreach($this->key as $fld) + if (isset($key[$fld])) + $where[$fld] = "`$fld`=".db_escape($key[$fld]); + else + return $this->error(sprintf(_("Invalid key for update '%s'"), $this->name)); + } else { + $where = array("`".$this->key."`=".db_escape($key)); + } + + $sql .= " WHERE ".implode(' AND ', $where); + $result = db_query($sql); + if (!$result) + return $this->error(_("Cannot update record in ").$this->name); + + return $result; + } + // + // Insert record + // + function insert($data) + { + if (!parent::insert_check($data)) + return false; + + $sql = "INSERT INTO ".TB_PREF.$this->name. ' ('; + $fields = array(); + foreach($data as $fld => $value) { + if (in_array($fld, $this->fields) || (is_array($this->key) ? in_array($this->key) : $fld==$this->key)) + $fields["`$fld`"] = db_escape($value); + } + if (!count($fields)) + return $this->error(_("Empty data set for insertion into ".$this->name)); + + $sql .= implode(',', array_keys($fields)) .') VALUES ('. implode(',', $fields).')'; + + $result = db_query($sql); + if (!$result) + return $this->error(_("Cannot insert record into ").$this->name); + + return $result; + } + +} + +/** +* +* Data set as array of arrays/objects +* +* TODO: default to: fields = ReflectionClass->getProperties +**/ +class array_set extends record_set { + + var $array = array(); + + var $object_class; // name of record object class or null for arrays + + function array_set($name, $fields, $key=null, &$arr=array(), $class = null) + { + $this->array = &$arr; + $this->object_class = $class; + $this->record_set($name, $fields, $key); + } + + //=========================================================================== + // Database functions placeholders + + // + // + // + function get($key=null) + { + if ($key===null) + return parent::get(); + + return @$this->array[$key]; + } + // + // Generic list record routine + // + function get_all() + { + return $this->array; + } + + function _set_record($data, $record = null) + { + if (!isset($record)) { + if ($this->object_class) { + $record = new $this->object_class; + } + else + $record = array(); + } + foreach(array_merge($this->fields, (array)$this->key) as $n => $fld) + { + if (!is_numeric($n)) + $fld = $n; + if (array_key_exists($fld, $data)) + { + if ($this->object_class) + $record->$fld = $data[$fld]; + else + $record[$fld] = $data[$fld]; + $updates = true; + } + } + return $updates ? $record : null; + } + // + // Generic update record routine + // + function update($key, $data) + { + if (parent::update($key, $data) === false) + return false; + + $record = $this->_set_record($data, $this->array[$key]); + if (!$record) + return $this->error(_("Empty update data for array ").$this->name); + + $this->array[$key] = $record; + + return true; + } + // + // Delete record + // + function delete($key) + { + if (!parent::delete($key)) + return false; + + unset($this->array[$key]); + + return true; + } + // + // Insert record + // + function insert($data) + { + if (parent::insert($data) === false) + return false; + + $record = $this->_set_record($data); + if (!$record) + return $this->error(_("Empty data for array ").$this->name); + + $this->array[] = $record; + + $ret = array_keys($this->array); + return end($ret); + } +} + diff --git a/includes/db/class.reflines_db.inc b/includes/db/class.reflines_db.inc new file mode 100644 index 00000000..344a18bf --- /dev/null +++ b/includes/db/class.reflines_db.inc @@ -0,0 +1,179 @@ +. +***********************************************************************/ +include_once 'class.data_set.inc'; + +/** +* Reference lines. +* +**/ + +class reflines_db extends data_set { + function reflines_db() + { + $this->set_validator('prefix:ui:_check_prefix', _("This prefix conflicts with another one already defined. Prefix have to be unambigous.")); + $this->set_validator('prefix:ui:_check_template', _("Invalid template format.")); + $this->set_validator('trans_type:ui:required', _("Transaction type cannot be empty.")); + $this->set_validator('pattern:ui:required', _("Next reference cannot be empty.")); + $this->data_set('reflines', + array('trans_type', 'prefix', 'description', 'default', 'pattern', 'id', 'inactive'), + 'id'); + } + + /* + Prefix cannot be ambigous. + */ + function _check_prefix($data, $dummy_opt, $key) + { + $cond = "`id`<>".db_escape($key)." AND `trans_type`=".db_escape($data['trans_type']); + if ($data['prefix'] === '') + $cond .= " AND `prefix`='".$data['prefix']."'"; + else + $cond .= "AND ((LOCATE('".$data['prefix']."', CONCAT(`prefix`,`pattern`))=1 OR (`prefix`<>'' AND LOCATE(`prefix`, '".$data['prefix'].$data['pattern']."')=1)))"; + + return db_num_rows($this->get_all($cond)) == 0; + } + + function _check_template($data, $dummy_opt, $key) + { + global $refline_options, $refline_placeholders; + + if (strpbrk($data['prefix'], '{}') !== false) + return $this->error(_("You cannot use placeholders in refline prefix.")); + + if (substr_count($data['pattern'], '{') != substr_count($data['pattern'], '}')) + return $this->error(_("Curly brackets does not balance.")); + + if (preg_match_all('/\{([^\}]*)\}/', $data['pattern'], $match)) // placeholders defind in template + { + $numph = 0; + foreach($match[1] as $ph) { + if (is_numeric($ph)) + $numph++; + elseif (!isset($refline_placeholders[$ph]) || !@in_array($refline_placeholders[$ph], $refline_options[$data['trans_type']])) { + $allowed = array(); + foreach($refline_placeholders as $id => $dt) + if (in_array($dt, $refline_options[$data['trans_type']])) + $allowed[] = $id; + + return $this->error(sprintf(_("Invalid placeholder '%s'. Placeholders allowed for this transaction type are: %s."), + $ph, implode(',', $allowed))); + } + } + + if ($numph !== 1) + return $this->error(_("Missing numeric placeholder. If you want to use template based references, you have to define numeric placeholder too.")); + } + return true; + } + + function is_used($prefix, $trans_type) + { + + $sql = "SELECT * + FROM (SELECT r.* FROM 0_refs r + LEFT JOIN ".TB_PREF."voided as v + ON r.id=v.id AND r.type=v.type + WHERE r.type=".db_escape($trans_type)." AND ISNULL(v.id) + ) ref + LEFT JOIN 0_reflines line ON ref.type=line.trans_type AND substr(ref.reference,1, LENGTH(line.prefix))= line.prefix AND line.prefix<>'' + WHERE ".($prefix == '' ? "ISNULL(prefix)" : "prefix=".db_escape($prefix)); + + $res = db_query($sql, "cannot check reference line"); + + return db_num_rows($res); + } + + function delete_check($ref_id) + { + $rec = $this->get($ref_id); + if ($rec['default']) + return $this->error(_("Reference line which is default for any transaction type cannot be deleted.")); + + if ($this->is_used($rec['prefix'], $rec['trans_type'])) + return $this->error(_("Reference line cannot be deleted because it is already in use.")); + + return true; + } + + function _set_as_default($id, $type) + { + $sql = "UPDATE ".TB_PREF."reflines SET `default`=(`id`=".db_escape($id).") + WHERE `trans_type`=".db_escape($type); + return db_query($sql, "cannot update default refline"); + } + + function insert($data) + { + if (!parent::insert($data)) + return false; + if (@$data['default']) + return $this->_set_as_default(db_insert_id(), $data['trans_type']); + return true; + } + + function update($key, $data) + { + if (!parent::update($key, $data)) + return false; + if (@$data['default']) + return $this->_set_as_default($key , $data['trans_type']); + return true; + } + + function get_default($type) + { + $sql = "SELECT * FROM ".TB_PREF."reflines WHERE trans_type=".db_escape($type)." AND `default`"; + $result = db_query($sql, "cannot retreive default refline for trnasaction type $type"); + return db_fetch($result); + } + + function count($type, $all=false) + { + $sql = "SELECT count(*) FROM ".TB_PREF."reflines WHERE trans_type=".db_escape($type); + if (!$all) + $sql .= " AND !inactive"; + $result = db_query($sql, "cannot retreive refline count for transaction type $type"); + $rec = db_fetch($result); + return $rec ? $rec[0] : 0; + } + + /* + Recognize refline by reference prefix + */ + function find_refline_id($reference, $type, $fallback = true) + { + $sql = "SELECT * FROM ".TB_PREF."reflines WHERE trans_type=".db_escape($type) + ." AND CHAR_LENGTH(`prefix`) AND LEFT('$reference', CHAR_LENGTH(`prefix`)) = `prefix`"; + if ($fallback) // if not found return refline with empty prefix + $sql .= " UNION SELECT * FROM ".TB_PREF."reflines WHERE trans_type=".db_escape($type)." AND `prefix`=''"; + $ret = db_query($sql, "cannot check reference line id"); + $line = db_fetch($ret); + + if (!$fallback && (db_num_rows($fallback) != 1)) // more than one record means ambigous reference line + return null; + + return $line ? $line['id'] : null; + } + + function save_next($type, $reference, $line=null) + { + $sql = "UPDATE ".TB_PREF."reflines SET pattern=SUBSTRING(" . db_escape(trim($reference)) .", LENGTH(`prefix`)+1)" + . " WHERE trans_type = ".db_escape($type) . " AND "; + + if (isset($line)) + $sql .= "`id`=".db_escape($line); + else + $sql .= "`default`"; + + return db_query($sql, "The next transaction ref for $type could not be updated"); + } +} diff --git a/includes/db/inventory_db.inc b/includes/db/inventory_db.inc index 9c9d2b2e..87f045f8 100644 --- a/includes/db/inventory_db.inc +++ b/includes/db/inventory_db.inc @@ -320,7 +320,7 @@ function handle_negative_inventory($stock_id, $quantity, $standard_cost, $date_) global $Refs; $id = get_next_trans_no(ST_JOURNAL); - $ref = $Refs->get_next(ST_JOURNAL); + $ref = $Refs->get_next(ST_JOURNAL, null, $date_); $diff = round($qoh*get_standard_cost($stock_id) + $quantity*$standard_cost, user_price_dec()); if ($diff != 0) diff --git a/includes/db/references_db.inc b/includes/db/references_db.inc deleted file mode 100644 index 4933d8db..00000000 --- a/includes/db/references_db.inc +++ /dev/null @@ -1,122 +0,0 @@ -. -***********************************************************************/ -//-------------------------------------------------------------------------------------------------- - -function get_reference($type, $id) -{ - $sql = "SELECT * FROM ".TB_PREF."refs WHERE type=".db_escape($type)." AND id=".db_escape($id); - - $result = db_query($sql, "could not query reference table"); - $row = db_fetch($result); - return $row['reference']; -} - -//-------------------------------------------------------------------------------------------------- - -function update_reference($type, $id, $reference) -{ - $sql = "REPLACE ".TB_PREF."refs SET reference=".db_escape($reference) - .", type=".db_escape($type).", id=".db_escape($id); - db_query($sql, "could not update reference entry"); -} - -//-------------------------------------------------------------------------------------------------- - -function delete_reference($type, $id) -{ - $sql = "DELETE FROM ".TB_PREF."refs WHERE type=".db_escape($type)." AND id=".db_escape($id); - - return db_query($sql, "could not delete from reference table"); -} - -//-------------------------------------------------------------------------------------------------- - -function find_reference($type, $reference) -{ - // ignore refs references for voided transactions - $sql = "SELECT r.id FROM ".TB_PREF."refs r LEFT JOIN ".TB_PREF."voided v ON" - ." r.type=v.type AND r.id=v.id" - ." WHERE r.type=".db_escape($type) - ." AND reference=".db_escape($reference) - ." AND ISNULL(`memo_`)"; - - $result = db_query($sql, "could not query reference table"); - - return (db_num_rows($result) > 0); -} - -//-------------------------------------------------------------------------------------------------- - -function save_next_reference($type, $reference) -{ - $sql = "UPDATE ".TB_PREF."sys_types SET next_reference=" . db_escape(trim($reference)) - . " WHERE type_id = ".db_escape($type); - - db_query($sql, "The next transaction ref for $type could not be updated"); -} - -//-------------------------------------------------------------------------------------------------- - -function get_next_reference($type) -{ - $sql = "SELECT next_reference FROM ".TB_PREF."sys_types WHERE type_id = ".db_escape($type); - - $result = db_query($sql,"The last transaction ref for $type could not be retreived"); - - $row = db_fetch_row($result); - return $row[0]; -} - -//---------------------------------------------------------------------------- -// -// Check if reference was not used so far (for other transaction than $trans_no) -// -function is_new_reference($ref, $type, $trans_no=0) -{ - $db_info = get_systype_db_info($type); - $db_name = $db_info[0]; - $db_type = $db_info[1]; - $db_trans = $db_info[2]; - $db_ref = $db_info[3]; - - $ref = db_escape(trim($ref)); - $type = db_escape($type); - - if ($db_ref == null) { // journal or bank trans store references in refs table - $db_name = TB_PREF."refs"; - $db_type = 'type'; - $db_trans = 'id'; - $db_ref = 'reference'; - } - - if ($db_type != null) { - $sql = "SELECT $db_ref FROM $db_name tbl - LEFT JOIN ".TB_PREF."voided v ON - tbl.$db_type=v.type AND tbl.$db_trans=v.id - WHERE $db_ref=$ref AND ISNULL(v.id) - AND tbl.$db_type=$type"; - } else { - $sql = "SELECT $db_ref ref FROM $db_name tbl - LEFT JOIN ".TB_PREF."voided v ON - v.type=$type AND tbl.$db_trans=v.id - WHERE $db_ref=$ref AND ISNULL(v.id)"; - } - if ($trans_no) - $sql .= " AND tbl.`$db_trans` != ".db_escape($trans_no); - - $result = db_query($sql, "could not test for unique reference"); - - return (db_num_rows($result) == 0); - -} - - diff --git a/includes/references.inc b/includes/references.inc index bba6f155..a5e872d7 100644 --- a/includes/references.inc +++ b/includes/references.inc @@ -9,77 +9,384 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License here . ***********************************************************************/ -include_once($path_to_root . "/includes/db/references_db.inc"); +include_once($path_to_root . "/includes/db/class.reflines_db.inc"); //--------------------------------------------------------------------------------------------- +// 2.4 - further changes toward removing refs table introduced: +// . all transactions now have references stored in trans table. +// . all reference related moved to class (is_new_reference yet preserved) +// . template based reflines implemented // -// For now (2.3) the references system has somewhat inconsistent design scheme. -// Most transactions store references in respective table, but this is not the case -// for journal entries. All references regardless of type are stored also in refs table. -// Reference uniquness now can be checked with is_new_reference() for all transactions. -// In near future this should be fixed either with removing reference fields -// in transaction tables, or adding ref in bank transaction/journal and removing refs table. -// +// FIXME: +// - implement refline field in all transaction tables (obsoletes not always accurate find_refline_id) +// - remove save() and restore_last() - for now preserved for reflines without placeholder +// - see fixmes below +// - remove refs table and create view instead (need e.g. CREATE VIEW support in db_import/db_export) + +$refline_options = array( + ST_JOURNAL => array('date', 'user'), + ST_COSTUPDATE => array('date', 'user'), + + ST_BANKPAYMENT => array('date', 'user'), + ST_BANKDEPOSIT => array('date', 'user'), + ST_BANKTRANSFER => array('date', 'user'), + ST_SUPPAYMENT => array('date', 'user'), + ST_CUSTPAYMENT => array('date', 'user'), + + ST_SALESORDER => array('date', 'customer', 'branch', 'user', 'pos'), + ST_SALESQUOTE => array('date', 'customer', 'branch', 'user', 'pos'), + ST_SALESINVOICE => array('date', 'customer', 'branch', 'user', 'pos'), + ST_CUSTCREDIT => array('date', 'customer', 'branch', 'user', 'pos'), + ST_CUSTDELIVERY => array('date', 'customer', 'branch', 'user', 'pos'), + + ST_LOCTRANSFER => array('date', 'location', 'user'), + ST_INVADJUST => array('date', 'location', 'user'), + + ST_PURCHORDER => array('date', 'location', 'supplier', 'user'), + ST_SUPPINVOICE => array('date', 'location', 'supplier', 'user'), + ST_SUPPCREDIT => array('date', 'location', 'supplier', 'user'), + ST_SUPPRECEIVE => array('date', 'location', 'supplier', 'user'), + + ST_WORKORDER => array('date', 'location', 'user'), + ST_MANUISSUE => array('date', 'location', 'user'), + ST_MANURECEIVE => array('date', 'user'), +); + +$refline_placeholders = array( + 'MM' => 'date', + 'YY' => 'date', + 'YYYY' => 'date', + 'UU' => 'user', + 'P' => 'pos', +// FIXME: for placeholders below all the code should work, but as the ref length is variable, +// length specification in placeholder format should be implemented. +// 'C' => 'customer', +// 'B' => 'branch', +// 'S' => 'supplier', +// 'L' => 'location' +); class references { - // - // Get reference from refs table for given transaction. - // Used for transactions which do not hold references (journal and bank). - // - function get($type, $id) + var $reflines; + + function references() { - return get_reference($type, $id); + $this->reflines = new reflines_db(); } + + function _legacy_line($refline) + { + return strpbrk($refline['pattern'], '{}') == false; + } + + function _parse_next($type, $template, $context=null) + { + global $refline_options, $refline_placeholders; + + // date based placeholders are always allowed, so default for non-array context is date + if (!isset($context)) + $context = new_doc_date(); + + if (is_string($context)) + $context = array('date' => $context); + + $context['user'] = $_SESSION['wa_current_user']->user; + $context['pos'] = $_SESSION['wa_current_user']->pos; + $out = ''; + + while(($start = strpos($template, '{')) !==false) { + + $out .= substr($template, 0, $start); + $stop = strpos($template, '}'); + if ($stop === false) { + display_warning(_("Invalid refline template.")); + $out .= $template; // debug + break; + } + $ph = substr($template, $start+1, $stop-$start-1); + $template = substr($template, $stop+1); + + if (isset($refline_placeholders[$ph])) { + if (!isset($context[$refline_placeholders[$ph]])) + { + display_warning(sprintf(_("Missing refline context data: '%s'"), $refline_placeholders[$ph])); + $out .= $ph; // debug + } else { + switch ($ph) + { + case 'MM': + case 'YY': + case 'YYYY': + list($day, $month, $year) = explode_date_to_dmy($context['date']); + $out .= $ph == 'MM' ? sprintf('%02d', $month) : ($ph == 'YY' ? sprintf('%02d', $year%100): sprintf('%04d', $year)); + break; + case 'C': + $out .= sprintf('%d', $context['customer']); + break; + + case 'B': + $out .= sprintf('%d', $context['branch']); + break; + + case 'S': + $out .= sprintf('%d', $context['supplier']); + break; + + case 'L': + $out .= sprintf('%s', $context['location']); + break; + + case 'P': + $out .= sprintf('%s', $context['pos']); + break; + + case 'UU': + $out .= sprintf('%02d', $context['user']); + break; + } + } + } elseif (is_numeric($ph)) { + $out .= '{'.$ph.'}'; // index placeholder + } + } + + if (!preg_match('/^([^\{]*)?\{([^\}]*)\}(.*)/', $out, $match)) { // parse index + display_error(_("Missing numeric placeholder in refline definition.")); + return $out; + } + + $prefix = $match[1]; + $postfix = $match[3]; + + $db_info = get_systype_db_info($type); + $trans_table = $db_info[0]; + $type_fld = $db_info[1]; + $tno_fld = $db_info[2]; + $ref_fld = $db_info[3]; + + // retrieve last ref number in the refline from original transaction table + $sql = "SELECT MAX(CAST(SUBSTR($ref_fld, ".(strlen($prefix)+1).",LENGTH($ref_fld)-".(strlen($postfix)+strlen($prefix)).") AS UNSIGNED))" + ." FROM `$trans_table` tbl + LEFT JOIN ".TB_PREF."voided v ON tbl.`$tno_fld`=v.id AND v.type=$type" + ." WHERE ISNULL(v.id)" + .($type_fld ? " AND tbl.`$type_fld`=$type" : '') + ." AND `$ref_fld` REGEXP ".db_escape('^'.preg_quote($prefix).'[0-9]*'.preg_quote($postfix).'$'); + $result = db_query($sql, 'cannot retrieve last reference'); + $result = db_fetch_row($result); + + // fill with zeros to the length of original index placeholder + return $prefix.sprintf('%0'.strlen($match[2]).'d', $result[0]+1).$postfix; + } + // - // Check if reference is used for any non voided transaction (used for ST_JOURNALENTRY type) + // Get/check transaction reference. + // $ref!=null => check reference is not used (or unique for $trans_no!=0) + // $trans!=0 $ref=null => retrieve reference for the $type/$trans_no (if any) // - function exists($type, $reference) + function _get($type, $trans_no=0, $ref=null) + { + $db_info = get_systype_db_info($type); + $trans_table = $db_info[0]; + $type_fld = $db_info[1]; + $tno_fld = $db_info[2]; + $ref_fld = $db_info[3]; + + $type = db_escape($type); + + $sql = "SELECT `$ref_fld` + FROM `$trans_table` tbl + LEFT JOIN ".TB_PREF."voided v ON + tbl.`$tno_fld`=v.id AND v.type=$type" + ." WHERE ISNULL(v.id)" + .($type_fld ? " AND tbl.`$type_fld`=$type" : ''); + if ($ref) + { + $sql .= " AND tbl.`$ref_fld`=".db_escape(trim($ref)); + if ($trans_no) + $sql .= " AND tbl.`$tno_fld` != ".db_escape($trans_no); + } else { + $sql .= " AND tbl.`$tno_fld`=".db_escape($trans_no); + } + + $result = db_query($sql, "could not test for unique reference"); + if (!$result) + return false; + + $result = db_fetch_row($result); + return $result[0]; + } + + function is_new_reference($ref, $type, $trans_no=0) { - return (find_reference($type, $reference) != null); + return !$this->_get($type, $trans_no, $ref); } + // - // Get default reference on new transaction creation. + // Get default reference for new transaction. // - function get_next($type) + function get_next($type, $line=null, $context=null) { - return get_next_reference($type); + + if (isset($line)) + $refline = $this->reflines->get($line); + else { + $refs = $this->reflines->get_all("trans_type=".db_escape($type)." AND `default`"); + $refline = db_fetch($refs); + } + + if ($this->_legacy_line($refline)) + return $refline['pattern']; + + return $this->_parse_next($type, $refline['prefix'].$refline['pattern'], $context); } + + /** + * Normalize reference to format allowed by refline (optionally selected by prefix). + * FIXME: currently this is fake function which return either input reference or + * next reference when no line has been recognized. + **/ + function normalize($ref, $type, $context, $line=null) + { + if (!isset($type)) // inquiries + return $ref; + + if (!$line) + $line = $this->reflines->find_refline_id($ref, $type); + + return $this->is_valid($ref, $type, $context, $line) ? $ref : $this->get_next($type, $line, $context); + } + // // Check reference is valid before add/update transaction. + // FIXME: does not check leading zeros in number // - function is_valid($reference) + function is_valid($reference, $type, $context=null, $line=null) { - return strlen(trim($reference)) > 0; + if (!isset($line)) + $line = $this->reflines->find_refline_id($reference, $type, true); + + if (!isset($line)) + return false; + + $refline = $this->reflines->get($line); + + if ($this->_legacy_line($refline)) //legacy non-templated line + return strlen(trim($reference)) > 0; + + $regex = preg_quote($refline['prefix'].$refline['pattern']); + if (!is_array($context)) + $context = array('date'=>$context); + + $context['pos'] = $_SESSION["wa_current_user"]->pos; + + if (is_date(@$context['date'])) + { + list($year4, $month, $day) = explode("-", date2sql($context['date'])); + $year2 = substr($year4, 2); + } else + { + $month = '\d{2,}'; + $year2 = '\d{2,}'; + $year4 = '\d{4,}'; + } + $cust = @$context['customer'] ? $context['customer'] : '\d+'; + $supp = @$context['supplier'] ? $context['supplier'] : '\d+'; + $branch = @$context['branch'] ? $context['branch'] : '\d+'; + $location = @$context['location'] ? $context['location'] : '[a-z0-9]+'; + $pos = @$context['pos'] ? $context['pos'] : '\d+'; + $user = sprintf("%02d", $_SESSION['wa_current_user']->user); + + $regex = preg_replace( + array( + '/\\\{/', // unquote placeholders + '/\\\}/', + '/\{MM\}/', + '/\{YY\}/', + '/\{YYYY\}/', + '/\{C\}/', + '/\{B\}/', + '/\{S\}/', + '/\{L\}/', + '/\{UU\}/', + '/\{P\}/', + '/\{\d+}/', + ), + array( + '{', + '}', + $month, + $year2, + $year4, + $cust, + $branch, + $supp, + $location, + $user, + $pos, + '\d+', + ), $regex); + + $regex = '"^'.$regex.'"i'; + + return preg_match($regex, $reference, $match) ? 1 : 0; } + // // Save reference (and prepare next) on write transaction. // - function save($type, $id, $reference) + function save($type, $id, $reference, $line = null) { - update_reference($type, $id, $reference); // store in refs table - if ($reference == $this->get_next($type)) { // if reference was bigger or not changed from default + if ($reference == 'auto') + return; + + $sql = "REPLACE ".TB_PREF."refs SET reference=".db_escape($reference) + .", type=".db_escape($type).", id=".db_escape($id); + db_query($sql, "could not update reference entry"); + + if (!isset($line)) + { + $line = $this->reflines->find_refline_id($reference, $type); + } + + $refline = $this->reflines->get($line); + // legacy code used with simple templates + if ($this->_legacy_line($refline) && ($reference == $this->get_next($type, $line))) { // if reference was not changed from default $next = $this->_increment($reference); // increment default - save_next_reference($type, $next); + $this->reflines->save_next($type, $next, $line); } } // // Restore previous reference (if possible) after voiding transaction. // - function restore_last($type, $id) + function restore_last($type, $id) { + // get refline for removed document reference $reference = get_reference($type, $id); - $prev = $this->_increment($this->get_next($type), true); //decrement - if ($reference==$prev) { - save_next_reference($type, $prev); + $line = $this->reflines->find_refline_id($reference, $type); + $refline = $this->reflines->get($line); + + if ($this->_legacy_line($refline)) // legacy code used with simple templates + { + $last = $this->_increment($this->get_next($type, $line), true); // find last reference used in this line + if ($reference == $last) + { + // save last reference as next + $sql = "UPDATE ".TB_PREF."reflines SET pattern=SUBSTRING(" . db_escape(trim($last)) .", LENGTH(`prefix`)+1)" + . " WHERE trans_type = ".db_escape($type) . " AND `id`=".db_escape($line); + + db_query($sql, "The next transaction ref for $type could not be updated"); + } } } + //----------------------------------------------------------------------- // // Increments (or decrements if $back==true) reference template // function _increment($reference, $back=false) { - // New method done by Pete. So f.i. WA036 will increment to WA037 and so on. + // Legacy code used when no palceholder is in use: + // WA036 will increment to WA037 and so on. // If $reference contains at least one group of digits, // extract first didgits group and add 1, then put all together. // NB. preg_match returns 1 if the regex matches completely @@ -98,5 +405,23 @@ class references else return $reference; } + +} + +//---------------------------------------------------------------------------- +// +// Check if reference was not used so far (for other transaction than $trans_no) +// +function is_new_reference($ref, $type, $trans_no=0) +{ + global $Refs; + + return $Refs->is_new_reference($ref, $type, $trans_no); } +function get_reference($type, $trans_no) +{ + global $Refs; + + return $Refs->_get($type, $trans_no); +} diff --git a/includes/ui/class.crud_view.inc b/includes/ui/class.crud_view.inc new file mode 100644 index 00000000..8572fdbe --- /dev/null +++ b/includes/ui/class.crud_view.inc @@ -0,0 +1,756 @@ +. +***********************************************************************/ + +include_once $path_to_root.'/includes/db/class.data_set.inc'; + +class UI { + var $ui_mode; + + // formatters + function text($value, $name='', $opts=array()) + { + $text = array('label', 'size'=>"", 'max'=>"", 'title'=>false, 'labparams'=>"", 'post_label'=>"", 'inparams'=>""); + $opts = array_merge($text, $opts); + + if (!$name) + return $value; + + call_user_func_array('text_cells', $opts); + } +} +/* + TODO: for php5: + . use __construct in base class to avoid need for implicit call to parent constructor. + . use private instead _* function name convention +*/ +// +// User input-output conversions. +// +class user_view { + + var $data; // data in php format + var $fields; // input fields format descriptions + var $errors = array(); + var $dec; + var $name; + + function user_view($name) + { + $this->name = $name; + } + + function error($msg, $context=null) + { + // save error message + if (!isset($context)) + $context = count($this->errors); + $this->errors[$context] = $msg; + + return false; + } + /* + Input/output formatters - convert values between php/user domains. + */ + function _format_input($value, $fmt) + { + switch($fmt) { + case 'stock': + $this->dec = get_qty_dec($value); + return $value; + case 'price': + case 'qty': + case 'number': + return user_numeric($value); + case 'percent': + return user_numeric($value)/100; + case 'text': + case 'date': + default: + return $value; + } + } + // + // Returns formatted value + // + function _format_output($value, $fmt) + { + switch($fmt) { + case 'price': + return price_format($value); + case 'qty': + return number_format2($value, $this->dec); + case 'number': + return number_format2($value); + case 'percent': + return percent_format($value*100); + case 'stock': + $this->dec = get_qty_dec($value); // retrieve dec for use in following qty fields + case 'text': + case 'date': + default: + return $value; + } + } + /** + * Returns html element for given field + * @mode - true for edit, false for read-only + **/ + function _format_cells($value, $fmt, $mode) + { + $value = $this->_format_output($fmt); + + // available formatters with parameters + $formatters = array( + 'email_cell' => array('label', 'params'=>'', 'id'=>null), + 'amount_cell' => array('label'=>null, 'bold'=>false, 'params'=>'', 'id'=>null), + 'text_cells' => array('label', 'name', 'value'=>null, 'size'=>"", 'max'=>"", 'title'=>false, + 'labparams'=>"", 'post_label'=>"", 'inparams'=>"") + ); + // format functions used in various modes + $formats = array( + // field format => (view [,edit]) + '' => array('label_cell', 'text_cells'), // default + 'price' => array('label_cell', 'amount_cell'), + 'qty', + 'number', + 'percent', + 'stock', + 'text', + 'date', + ); + } + + /** + * + * PHP->user format values convertion. + * + **/ + function set_output($data=null, &$output=null) + { + if (isset($data)) + $this->data = $data; + + if (!isset($output)) { + $output = &$_POST; + $prefix = $this->name; + } else + $prefix = ''; + + foreach($this->fields as $name => $fmt) { + + if (is_int($name)) { + $name = $fmt; + $fmt = array(); + } elseif (!is_array($fmt)) + $fmt = array('fmt' => $fmt); + + $post = $prefix.(isset($fmt['post']) ? $fmt['post'] : $name); + + $fld = isset($fmt['fld']) ? $fmt['fld'] : $name; + + if (is_object($this->data)) + $value = isset($this->data->$fld) ? $this->data->$fld : @$fmt['dflt']; + else + $value = isset($this->data[$fld]) ? $this->data[$fld] : @$fmt['dflt']; + if(isset($value)) + $output[$post] = $this->_format_output($value, @$fmt['fmt']); + } + } + + /** + * + * User->php format values convertion. + * $input - data in user format + * $all - return also null values for non-existing input field. + **/ + function get_input($input=null, $all=false) + { + if (!isset($input)) + $input = $_POST; + + if ($this->name) // strip view name prefix + foreach($input as $postkey=>$postval ) + { + if (strpos($postkey, $this->name) === 0) + { + $id = substr($postkey, strlen($this->name)); + $input[$id] = $postval; + } + unset($input[$postkey]); + } + + $data = array(); + foreach ($this->fields as $name => $fmt) { + if (is_int($name)) { // direct string passed: this is name of field + $name = $fmt; + $fmt = array(); // default format + } elseif (!is_array($fmt)) + $fmt = array('fmt' => $fmt); + $post = isset($fmt['post']) ? $fmt['post'] : $name; // input name (default to field name) + $fld = isset($fmt['fld']) ? $fmt['fld'] : $name; // input value (default to field name) + +// if ($all || array_key_exists($post, $input)) +// { + $value = $this->_format_input(@$input[$post], @$fmt['fmt']); + +// if (is_array($data)) + if ($all || isset($value)) + $data[$fld] = $value; +// else +// $data->$fld = $value; +// } + } + + return $data; + } + + //-------------------------------------------------------- + // + // Return data formatted according to field descriptions. + // + function get_fields_views($input=null, $mode=null) + { + + if (!isset($input)) + $input = $_POST; + + $view = array(); + foreach ($this->fields as $name => $fmt) { + if (is_int($name)) { + $name = $fmt; + $fmt = array(); + } + $post = isset($fmt['post']) ? $fmt['post'] : $name; + $fld = isset($fmt['fld']) ? $fmt['fld'] : $name; + + $value = $this->_format_cells(@$input[$post], @$fmt['fmt'], $mode); + + $view[$fld] = $value; + } + return $view; + } + +} + +// +// Template for simple table editors +// + +class simple_crud_view extends user_view { + var $name; + // object status: + var $Mode = 'RESET'; + var $selected_id; + var $prev_id; + + var $_none = ''; // selector value when no item is selected + var $pre_handlers; // control buttons and related methods called before view display + var $views; + var $data = array(); + var $fields; + var $tool_buttons; + var $options = array( + 'delete' => true, // true or message for successfull action. + 'update' => true, + 'insert' => true, + 'clone' => true, + ); + var $dec; + var $data_set; + var $display_both = false; //when set to true both list and editor are displayed all the time (eventually set in sub classes) + // + // + function simple_crud_view($name, $data_set = null, $options=array()) + { + $this->user_view($name); + + $this->options = array_merge($this->options, $options); + + $this->views[''] = 'list_view'; // default view + + if ($this->options['update']) + $this->_add_action('Edit', '_edit', _('Edit'), _('Edit document line'), ICON_EDIT, '', + 'editor_view'); + + if ($this->options['delete']) + $this->_add_action('Delete', '_delete', _('Delete'), _('Remove line from document'), ICON_DELETE, '', + 'list_view'); + + if ($this->options['update']) + $this->_add_action('UPDATE', '_update', _('Update'), _('Submit changes'), ICON_UPDATE, 'default', + 'editor_view'); + + $this->_add_action('RESET', '_cancel', _('Cancel'), _('Cancel changes'), ICON_ESCAPE, 'cancel', + 'list_view'); + + if ($this->options['insert']) + $this->_add_action('ADD', '_add', _('Add'), _('Add new'), ICON_ADD, 'default', + 'editor_view'); + + if ($this->options['insert']) + $this->_add_action('NEW', '_add', _('New'), _('Add new'), ICON_ADD, 'default', + 'editor_view'); + + if ($this->options['clone']) + $this->_add_action('CLONE', '_cloning', _('Clone'), _('Clone'), ICON_ADD, '', + 'editor_view'); + + $this->data_set = $data_set; + $this->fields = $data_set->fields; + +// $this->_prev_status(); + } + + function _add_action($name, $handler, $but_value=null, $but_title=false, $but_icon=false, $aspect='', $view=null) + { + $this->pre_handlers[$name] = $handler; + + if ($but_value) + $this->tool_buttons[$name] = array($but_value, $but_title, $but_icon, $aspect); + + if ($view) + $this->_add_mode($name, $view); + } + + function _add_mode($name, $view) + { + $this->views[$name] = $view; + } + + function _prev_status() + { + // Restore previous mode/key (obsolete for views stored in session) + + $mod = get_post($this->name.'Mode', $this->Mode); + if ($mod) { + if (is_array($mod)) { + $val = key($mod); + $this->selected_id = $val!==null ? @quoted_printable_decode($val) : $this->_none; + $mod = $mod[$val]; + } else { + $val = $mod; + $this->selected_id = $this->_none; + } + } + $this->Mode = $mod; + } + + function _check_mode() + { + global $Ajax; + + $mod = '';//$this->Mode; + // Detect action (mode change) + foreach (array_keys($this->pre_handlers) as $m) { // check button controls + + if (isset($_POST[$this->name.$m])) { + unset($_POST['_focus']); // focus on first form entry + $Ajax->activate($this->name.'_div'); + $Ajax->activate($this->name.'_controls'); + $val = is_array($_POST[$this->name.$m]) ? key($_POST[$this->name.$m]) : null; + $this->prev_id = $this->selected_id; + $this->selected_id = $val!==null ? @quoted_printable_decode($val) : $this->_none; + $mod = $m; break; + } + } + if (!$mod && $_SERVER['REQUEST_METHOD'] == 'GET') // initialize on every GET + $mod = 'RESET'; + + return $mod; + } + + function display_error() + { + $this->errors = array_merge($this->data_set->errors, $this->errors); + $firsterr = reset($this->errors); + $field = key($this->errors); + + if (!is_numeric($field)) + set_focus($this->name.$field); + display_error($firsterr); + + $this->errors = array(); // clean up to prevent false errors on object reuse + } + // + // Set record for edition + // + function _edit($mode) + { + if ($this->selected_id != $this->prev_id || $mode != $this->Mode) { // get record for edition + $this->data = $this->data_set->get($this->selected_id !== $this->_none ? $this->selected_id : null); + $this->set_output(); + } +// if ($this->Mode != $mode) { +// } + +// else +// $this->display_error(); + + $this->Mode = $mode; + } + // + // Update record after edition + // + function _update($mode) + { + if (!$this->options['update']) + return; + + $this->data = $this->get_input(); + if ($this->data_set->update_check($this->selected_id, $this->data) && $this->data_set->update($this->selected_id, $this->data)) { + $this->selected_id = $this->_none; + $this->Mode = 'RESET'; + $this->_cancel(); + if (is_string($this->options['update'])) + display_notification($this->options['update']); + return; + } + else + $this->display_error(); + + $this->Mode = $mode; + } + // + // Add new record + // + function _add($mode) + { + if (!$this->options['insert']) + return; + + if ($mode == 'ADD') { + $this->data = $this->get_input(); + if ($this->data_set->insert_check($this->data) && ($this->data_set->insert($this->data) !== false)) { + $this->_cancel(); + if (is_string($this->options['insert'])) + display_notification($this->options['insert']); + $this->Mode = 'RESET'; + return; + } + else + $this->display_error(); + } else {// mode==NEW + $this->data = $this->data_set->get(); + } + $this->Mode = 'ADD'; + } + // + // Delete selected record + // + function _delete() + { + if (!$this->options['delete']) + return; + + if ($this->data_set->delete_check($this->selected_id) && $this->data_set->delete($this->selected_id)) + { + if (is_string($this->options['delete'])) + display_notification($this->options['delete']); + } else + $this->display_error(); + $this->_cancel(); + } + // + // Return to listing view + // + function _cancel() + { + global $Ajax; + $this->selected_id = $this->_none; + if ($this->display_both) + { + $this->data = $this->data_set->get(); + $this->set_output(); + } + $this->cancel(); + if (!$this->display_both) + $Ajax->activate($this->name.'_div'); + $this->Mode = 'RESET'; + } + // + // Clone record for new edition + // + function _cloning() + { + if (!$this->options['clone']) + return; + $this->Mode = 'ADD'; + $this->_edit('Edit'); + $this->selected_id = $this->_none; + } + /* + Generate form controls + */ + + function _record_controls($list_view = false) + { + $clone = $this->options['clone'] && $this->selected_id != $this->_none; + + div_start($this->name.'_controls'); + echo "
"; + + if ($list_view) + $this->action_button('NEW'); + else { + if ($this->Mode == 'NEW' || $this->selected_id==$this->_none) + { + $this->action_button('ADD'); + $this->action_button('RESET'); + } else { + $this->action_button('UPDATE', $this->selected_id); + if ($clone && $this->display_both) + $this->action_button('CLONE', $this->selected_id); + $this->action_button('RESET'); + } + } + + echo "
"; + div_end(); + } + + //=========================================================================== + // Public functions + // + + // + // Submit buttons for form actions + // + function action_button($action, $selected_id=null) + { + list($value, $title, $icon, $aspect) = $this->tool_buttons[$action]; + submit($this->name.$action.(isset($selected_id) ? "[$selected_id]" : ''), $value, true, $title, $aspect, $icon); + } + + // + // Tool button for grid line actions. + // + function tool_button($name, $selected_id=null, $params='') + { + $b = $this->tool_buttons[$name]; + + return "" + .button( "{$this->name}$name" + .($selected_id === null || $selected_id === $this->_none ? '': "[$selected_id]"), + $b[0], $b[1], $b[2], $b[3]).""; + } + // + // Main function - display current CRUD editor content + // + function show($Mode=null) + { + if (!isset($Mode)) + $Mode = $this->_check_mode(true); + + div_start($this->name.'_div'); + + if (array_key_exists($Mode, $this->pre_handlers)) { + $fun = $this->pre_handlers[$Mode]; + if (is_array($fun)) + call_user_func($fun, $Mode); + else + $this->$fun($Mode); + } + + if (isset($this->views[$this->Mode])) + $this->{$this->views[$this->Mode]}($Mode); + else + $this->{$this->views['']}($Mode); // default view + + // this is needed only when we use temporary crud object together with ajax screen updates + hidden($this->name.'Mode'.'['.$this->selected_id.']', $this->Mode); + div_end(); + } + + // + // Optional things like focus set performed on edition cancel. + // + function cancel() + { + } + + // + // Show database content in pager/table + // parameter $Mode contains new mode on change, or '' otherwise + // + function list_view($Mode) { + display_notification(__FUNCTION__. ' is not defined...'); + } + + // + // Show record editor screen content + // parameter $Mode contains new mode on change, or '' otherwise + // + function editor_view($Mode) { + display_notification(__FUNCTION__. ' is not defined...'); + } +}; + +class selector_crud_view extends simple_crud_view { + + function selector_crud_view($name, $data_set = null, $options=array()) + { + $this->display_both = true; + $this->simple_crud_view($name, $data_set, $options); + } + + function _check_mode() + { + global $Ajax; + + // list controls lookup + $prev_mode = $this->Mode; + $mod = ''; + + $list = $this->name.'_id'; + $this->prev_id = $this->selected_id; + $this->selected_id = get_post($list); + if (list_updated($list)) { + $Ajax->activate($this->name); + $Ajax->activate($this->name.'_controls'); + $mod = $this->selected_id == $this->_none ? 'RESET' : 'Edit'; + } else { + $mod = simple_crud_view::_check_mode(); + } + + if ($mod != $prev_mode) { + $Ajax->activate($this->name.'_controls'); + } + if (get_post('_show_inactive_update')) + { + $Ajax->activate($this->name.'_id'); + } + + $_POST[$list] = $this->selected_id; + return $mod; + } + + function cancel() + { + global $Ajax; + + $_POST[$this->name.'_id'] = $this->selected_id = $this->_none; + $Ajax->activate($this->name.'_id'); + } +} + +// +// Template for line table editors +// + +class table_crud_view extends simple_crud_view { + + var $title; + + function table_crud_view($name, &$data_set = null, $options=array()) + { + $this->display_both = true; + $this->simple_crud_view($name, $data_set, $options); + } + /** + * + * Returns selector string from data or current selected_id + * + **/ + function curr_id($data=null) + { + if ($data) + return $data ? implode('_', array_intersect_key($data, array_fill_keys($this->key, true))) : null; // php 5.2.0 + else + return $this->selected_id; + } + /** + * + * Show single line from record table + * + **/ + function show_record_row($line_no, $record=array()) + { +/* TBD + $id = $this->curr_id($record); // extract key + + $view = array(); + $this->set_output($line, $view); + + $editables = array(); + if ($this->options['edit'] && $this->Mode=='Edit' && $this->selected_id==$id) + { + $editables = $this->data_set->edit_status($key); + } + $ctrls = $this->get_field_views($record, $editables); + alt_table_row_color($k); + foreach($ctrls as $key => $fld) + { + echo ''; + echo $ctrls[$key]; + echo ''; + } + + if ($this->options['edit']) { + echo ''; + $this->tool_button($this->selected_id==$id ? 'UPDATE' : 'Edit', $id); + echo ''; + } + if ($this->options['delete']$this->selected_id==$id) { + echo ''; + $this->tool_button( ? 'Cancel' : 'Delete', $id); + echo ''; + } + end_row(); + + if ($this->options['insert']) + { + alt_table_row_color($k); + $this->new_line($line_no, $line); + end_row(); + } +*/ + } + function show_list_headers() + { + } + // + // Main function - display current CRUD table content + // + function show($Mode=null) + { + if (!isset($Mode)) + $Mode = $this->_check_mode(true); + div_start($this->name.'_div'); + + if (array_key_exists($Mode, $this->pre_handlers)) + { + $fun = $this->pre_handlers[$Mode]; + if (is_array($fun)) + { + if (is_object($fun[0])) + $fun[0]->$fun[1]($Mode); + } else + $this->$fun($Mode); + } + + if ($this->title) + display_heading($this->title); + + start_table(TABLESTYLE, "width=95%"); + $this->show_list_headers(); + + foreach($this->data_set->get_all() as $line_no => $line) { + $this->show_record_row($line_no, $line); + } + $this->show_record_row(); + + end_table(); + hidden($this->name.'Mode'.'['.$this->selected_id.']', $this->Mode); + div_end(); + } + +}; diff --git a/includes/ui/class.reflines_crud.inc b/includes/ui/class.reflines_crud.inc new file mode 100644 index 00000000..46b4d4dc --- /dev/null +++ b/includes/ui/class.reflines_crud.inc @@ -0,0 +1,115 @@ +. +***********************************************************************/ +include_once $path_to_root.'/includes/db/class.reflines_db.inc'; +include_once $path_to_root.'/includes/ui/class.crud_view.inc'; + +class fa_reflines extends simple_crud_view { + + function fa_reflines() + { + $this->simple_crud_view('refs', new reflines_db(), array('clone' => false)); + + $this->fields = array( + 'prefix', + 'description', + 'trans_type', + 'pattern', + 'default', + ); + + } + + function list_view($Mode) + { + global $Ajax, $systypes_array; + + start_table(TABLESTYLE); + + $th = array(_("Transaction type"), _("Prefix"), + _("Pattern"), _("Default"), _("Memo"), "", ""); + + inactive_control_column($th); + + table_header($th); + + $k = 0; + $data = $this->data_set->get_all(check_value('show_inactive') ? null : '!inactive', array('trans_type', 'prefix')); + + if (!$data) return false; + + while ($rec = db_fetch($data)) + { + alt_table_row_color($k); + + label_cell($systypes_array[$rec['trans_type']]); + label_cell($rec['prefix']); + label_cell($rec['pattern']); + label_cell($rec['default'] ? _("Yes") : _("No")); + label_cell($rec['description']); + + if (check_value('show_inactive') && $rec['default']) + label_cell(''); + else + inactive_control_cell($rec["id"], $rec["inactive"], 'reflines', 'id'); + if ($this->options['update']) + echo $this->tool_button('Edit', $rec['id']); + if ($this->options['delete']) { + echo $this->tool_button('Delete', $rec['id']); + } + end_row(); + } + inactive_control_row($th); + end_table(1); + $this->_record_controls(true); + + return true; + } + + function editor_view($Mode) + { + global $systypes_array; + + $selected_id = $this->selected_id; + + // new or never used + $fresh = $selected_id == $this->_none || !$this->data_set->is_used(get_post($this->name.'prefix'), get_post($this->name.'trans_type')); + + start_table(TABLESTYLE2); + if ($fresh) + { + systypes_list_row(_("Transaction Type:"), $this->name.'trans_type'); + $prefix = text_input($this->name.'prefix', null, 5, 30); + } else { + label_row(_("Transaction Type:"), $systypes_array[get_post($this->name.'trans_type')]); + hidden($this->name.'trans_type'); + $prefix = get_post($this->name.'prefix') . hidden($this->name.'prefix'); + } + + label_row(_("Reference Pattern:"), $prefix . text_input($this->name.'pattern', null, 30, 60)); + + if (get_post($this->name.'default')) + label_row(_("Default for This Type:"), _("Yes")); + else + check_row(_("Set as Default for This Type:"), $this->name.'default'); + + text_row_ex(_("Memo:"), $this->name.'description', 30, 60); + + end_table(1); + hidden($this->name.'selected_id', $selected_id); + $this->_record_controls(); + } + + function show($Mode=null) + { + parent::show($Mode); + } +} diff --git a/includes/ui/ui_input.inc b/includes/ui/ui_input.inc index bdb7e945..ed0e0595 100644 --- a/includes/ui/ui_input.inc +++ b/includes/ui/ui_input.inc @@ -709,19 +709,70 @@ function file_row($label, $name, $id = "") echo "\n"; } -//----------------------------------------------------------------------------------- +/*----------------------------------------------------------------------------------- + + Reference number input. -function ref_cells($label, $name, $title=null, $init=null, $params=null, $submit_on_change=false) + Optional $context array contains transaction data used in number parsing: + 'data' - data used for month/year codes + 'location' - location code + 'customer' - debtor_no + 'supplier' - supplier id + 'branch' - branch_code +*/ +function ref_cells($label, $name, $title=null, $init=null, $params=null, $submit_on_change=false, $type=null, $context=null) { - text_cells_ex($label, $name, 16, 18, $init, $title, $params, null, $submit_on_change); + global $Ajax, $Refs; + + if (isset($type)) { + if (empty($_POST[$name.'_list'])) // restore refline id + $_POST[$name.'_list'] = $Refs->reflines->find_refline_id(empty($_POST[$name]) ? $init : $_POST[$name], $type); + + if (empty($_POST[$name]) || ($_SERVER['REQUEST_METHOD'] == 'GET')) // initialization + { + if (isset($init)) + { + $_POST[$name] = $init; + } else { + $_POST[$name] = $Refs->get_next($type, $_POST[$name.'_list'], $context); // set default + } + $Ajax->addUpdate(true, $name, $_POST[$name]); + } + + if (check_ui_refresh($name)) { // call context changed + $_POST[$name] = $Refs->normalize($init, $type, $context, $_POST[$name.'_list']); + $Ajax->addUpdate(true, $name, $_POST[$name]); + } + + if ($Refs->reflines->count($type)>1) { + if (list_updated($name.'_list')) { + $_POST[$name] = $Refs->get_next($type, $_POST[$name.'_list'], $context); + $Ajax->addUpdate(true, $name, $_POST[$name]); + } + $list = refline_list($name.'_list', $type); + } else { + $list = ''; + } + + if (isset($label)) + label_cell($label, $params); + + label_cell($list.""); + } + else // just wildcard ref field (e.g. for global inquires) + { + text_cells_ex($label, $name, 16, 35, $init, $title, $params, null, $submit_on_change); + } } //----------------------------------------------------------------------------------- -function ref_row($label, $name, $title=null, $init=null, $submit_on_change=false) +function ref_row($label, $name, $title=null, $init=null, $submit_on_change=false, $type=null, $context = null) { echo "$label"; - ref_cells(null, $name, $title, $init, null, $submit_on_change); + ref_cells(null, $name, $title, $init, null, $submit_on_change, $type, $context); echo "\n"; } diff --git a/includes/ui/ui_lists.inc b/includes/ui/ui_lists.inc index 88b33f4f..bfb5c6eb 100644 --- a/includes/ui/ui_lists.inc +++ b/includes/ui/ui_lists.inc @@ -2365,6 +2365,40 @@ function tax_algorithm_list_row($label, $name, $value=null, $submit_on_change=fa tax_algorithm_list_cells(null, $name, $value, $submit_on_change); echo "\n"; } + +function refline_list($name, $type, $value=null, $spec_option=false) +{ + $sql = "SELECT id, prefix, inactive FROM ".TB_PREF."reflines"; + + $where = array(); + + if (isset($type)) + $where = array('`trans_type`='.db_escape($type)); + + return combo_input($name, $value, $sql, 'id', 'prefix', + array( + 'order'=>array('prefix'), + 'spec_option' => $spec_option, + 'spec_id' => '', + 'type' => 2, + 'where' => $where, + 'select_submit' => true, + ) + ); +} + +function refline_list_row($label, $name, $type, $selected_id=null, $spec_option=false) +{ + echo ""; + if ($label != null) + echo "$label\n"; + echo ""; + + echo refline_list($name, $type, $selected_id, $spec_option); + echo "\n"; +} + + //---------------------------------------------------------------------------------------------- function subledger_list($name, $account, $selected_id=null) diff --git a/includes/ui/ui_view.inc b/includes/ui/ui_view.inc index 12883aa0..9c2b594f 100644 --- a/includes/ui/ui_view.inc +++ b/includes/ui/ui_view.inc @@ -262,7 +262,7 @@ function check_ui_refresh($name=null) $name = $bt[1]['function']; $old = @$_SESSION['ui_context'][$name]; $new = $_SESSION['ui_context'][$name] = $bt[1]['args']; - return ($new != $old) || ($_SERVER['REQUEST_METHOD'] == 'GET'); + return ($new != $old); } //-------------------------------------------------------------------------------------- diff --git a/inventory/adjustments.php b/inventory/adjustments.php index 9a9a09d1..3d2c39ba 100644 --- a/inventory/adjustments.php +++ b/inventory/adjustments.php @@ -87,16 +87,9 @@ function can_process() set_focus('stock_id'); return false; } - if (!$Refs->is_valid($_POST['ref'])) - { - display_error( _("You must enter a reference.")); - set_focus('ref'); - return false; - } - if (!is_new_reference($_POST['ref'], ST_INVADJUST)) + if (!check_reference($_POST['ref'], ST_INVADJUST)) { - display_error( _("The entered reference is already in use.")); set_focus('ref'); return false; } diff --git a/inventory/includes/item_adjustments_ui.inc b/inventory/includes/item_adjustments_ui.inc index eb2f03d2..0bd5d2b7 100644 --- a/inventory/includes/item_adjustments_ui.inc +++ b/inventory/includes/item_adjustments_ui.inc @@ -35,7 +35,9 @@ function display_order_header(&$order) date_row(_("Date:"), 'AdjDate', '', true); table_section(2, "50%"); - ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_INVADJUST)); + + ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_INVADJUST, null, array('location'=>get_post('StockLocation'), 'date'=>get_post('AdjDate'))), + false, ST_INVADJUST); end_outer_table(1); // outer table } diff --git a/inventory/includes/stock_transfers_ui.inc b/inventory/includes/stock_transfers_ui.inc index 8c143196..3fd5110a 100644 --- a/inventory/includes/stock_transfers_ui.inc +++ b/inventory/includes/stock_transfers_ui.inc @@ -39,7 +39,8 @@ function display_order_header(&$order) date_row(_("Date:"), 'AdjDate', '', true); - ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_LOCTRANSFER)); + ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_LOCTRANSFER, null, array('date'=>get_post('Adjdate'), 'location'=> get_post('FromStockLocation'))), + false, ST_LOCTRANSFER); end_outer_table(1); // outer table } diff --git a/inventory/transfers.php b/inventory/transfers.php index 5315a23c..12f19d28 100644 --- a/inventory/transfers.php +++ b/inventory/transfers.php @@ -83,15 +83,8 @@ if (isset($_POST['Process'])) set_focus('stock_id'); $input_error = 1; } - if (!$Refs->is_valid($_POST['ref'])) + if (!check_reference($_POST['ref'], ST_LOCTRANSFER)) { - display_error(_("You must enter a reference.")); - set_focus('ref'); - $input_error = 1; - } - elseif (!is_new_reference($_POST['ref'], ST_LOCTRANSFER)) - { - display_error(_("The entered reference is already in use.")); set_focus('ref'); $input_error = 1; } diff --git a/manufacturing/includes/db/work_order_costing_db.inc b/manufacturing/includes/db/work_order_costing_db.inc index 8d8e1517..272e7328 100644 --- a/manufacturing/includes/db/work_order_costing_db.inc +++ b/manufacturing/includes/db/work_order_costing_db.inc @@ -107,8 +107,8 @@ function add_overhead_cost($stock_id, $qty, $date_, $costs, $adj_only=false) global $Refs; $id = get_next_trans_no(ST_JOURNAL); - $ref = $Refs->get_next(ST_JOURNAL); - + $ref = $Refs->get_next(ST_JOURNAL, null, $date_); + $stock_gl_code = get_stock_gl_code($stock_id); add_journal(ST_JOURNAL, $id, $costs, $date_, get_company_currency(), $ref); $memo = "WO Overhead cost settlement JV for zero/negative respository of ".$stock_id; @@ -163,7 +163,7 @@ function add_labour_cost($stock_id, $qty, $date_, $costs, $adj_only=false) global $Refs; $id = get_next_trans_no(ST_JOURNAL); - $ref = $Refs->get_next(ST_JOURNAL); + $ref = $Refs->get_next(ST_JOURNAL, null, $date_); add_journal(ST_JOURNAL, $id, $costs, $date_, get_company_currency(), $ref); $stock_gl_code = get_stock_gl_code($stock_id); @@ -219,7 +219,7 @@ function add_issue_cost($stock_id, $qty, $date_, $costs, $adj_only=false) global $Refs; $id = get_next_trans_no(ST_JOURNAL); - $ref = $Refs->get_next(ST_JOURNAL); + $ref = $Refs->get_next(ST_JOURNAL, null, $date_); add_journal(ST_JOURNAL, $id, $costs, $date_, get_company_currency(), $ref); $stock_gl_code = get_stock_gl_code($stock_id); @@ -265,7 +265,7 @@ function add_wo_costs_journal($wo_id, $amount, $cost_type, $cr_acc, $db_acc, $da begin_transaction(); $journal_id = get_next_trans_no(ST_JOURNAL); - if (!$ref) $ref = $Refs->get_next(ST_JOURNAL); + if (!$ref) $ref = $Refs->get_next(ST_JOURNAL, null, $date); add_gl_trans_std_cost(ST_JOURNAL, $journal_id, $date, $cr_acc, 0, 0, $wo_cost_types[$cost_type], -$amount); diff --git a/manufacturing/includes/work_order_issue_ui.inc b/manufacturing/includes/work_order_issue_ui.inc index d5e8eb80..540a57b8 100644 --- a/manufacturing/includes/work_order_issue_ui.inc +++ b/manufacturing/includes/work_order_issue_ui.inc @@ -160,7 +160,11 @@ function issue_options_controls() echo "
"; start_table(); - ref_row(_("Reference:"), 'ref', '', $Refs->get_next(28)); + date_row(_("Issue Date:"), 'date_'); + locations_list_row(_("From Location:"), 'Location'); + workcenter_list_row(_("To Work Centre:"), 'WorkCentre'); + + ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_MANUISSUE, null, array('date'=> get_post('date_'), 'location' => get_post('Location')); if (!isset($_POST['IssueType'])) $_POST['IssueType'] = 0; @@ -168,10 +172,7 @@ function issue_options_controls() yesno_list_row(_("Type:"), 'IssueType', $_POST['IssueType'], _("Return Items to Location"), _("Issue Items to Work order")); - locations_list_row(_("From Location:"), 'Location'); - workcenter_list_row(_("To Work Centre:"), 'WorkCentre'); - date_row(_("Issue Date:"), 'date_'); textarea_row(_("Memo"), 'memo_', null, 50, 3); diff --git a/manufacturing/work_order_add_finished.php b/manufacturing/work_order_add_finished.php index fefbf1b5..8a9947a4 100644 --- a/manufacturing/work_order_add_finished.php +++ b/manufacturing/work_order_add_finished.php @@ -71,16 +71,8 @@ function can_process($wo_details) { global $SysPrefs, $Refs; - if (!$Refs->is_valid($_POST['ref'])) + if (!check_reference($_POST['ref'], ST_MANURECEIVE)) { - display_error(_("You must enter a reference.")); - set_focus('ref'); - return false; - } - - if (!is_new_reference($_POST['ref'], 29)) - { - display_error(_("The entered reference is already in use.")); set_focus('ref'); return false; } @@ -191,7 +183,8 @@ if (!isset($_POST['quantity']) || $_POST['quantity'] == '') start_table(TABLESTYLE2); br(); -ref_row(_("Reference:"), 'ref', '', $Refs->get_next(29)); +ref_row(_("Reference:"), 'ref', '', $Refs->get_next(29, null, get_post('date_')), false, ST_MANUISSUE); +date_row(_("Date:"), 'date_'); if (!isset($_POST['ProductionType'])) $_POST['ProductionType'] = 1; @@ -201,8 +194,6 @@ yesno_list_row(_("Type:"), 'ProductionType', $_POST['ProductionType'], small_qty_row(_("Quantity:"), 'quantity', null, null, null, $dec); -date_row(_("Date:"), 'date_'); - textarea_row(_("Memo:"), 'memo_', null, 40, 3); end_table(1); diff --git a/manufacturing/work_order_costs.php b/manufacturing/work_order_costs.php index df0ea058..a76c5f5e 100644 --- a/manufacturing/work_order_costs.php +++ b/manufacturing/work_order_costs.php @@ -117,7 +117,7 @@ display_wo_details($_POST['selected_id']); //------------------------------------------------------------------------------------- if (!isset($_POST['ref'])) - $_POST['ref'] = $Refs->get_next(ST_JOURNAL); + $_POST['ref'] = $Refs->get_next(ST_JOURNAL, null, get_post('date_')); start_form(); diff --git a/manufacturing/work_order_entry.php b/manufacturing/work_order_entry.php index ccc2635e..6a27bfc2 100644 --- a/manufacturing/work_order_entry.php +++ b/manufacturing/work_order_entry.php @@ -126,16 +126,8 @@ function can_process() if (!isset($selected_id)) { - if (!$Refs->is_valid($_POST['wo_ref'])) + if (!check_reference($_POST['wo_ref'], ST_WORKORDER)) { - display_error(_("You must enter a reference.")); - set_focus('wo_ref'); - return false; - } - - if (!is_new_reference($_POST['wo_ref'], ST_WORKORDER)) - { - display_error(_("The entered reference is already in use.")); set_focus('wo_ref'); return false; } @@ -380,7 +372,7 @@ if (isset($selected_id)) else { $_POST['units_issued'] = $_POST['released'] = 0; - ref_row(_("Reference:"), 'wo_ref', '', $Refs->get_next(ST_WORKORDER)); + ref_row(_("Reference:"), 'wo_ref', '', $Refs->get_next(ST_WORKORDER, null, get_post('date_')), false, ST_WORKORDER); wo_types_list_row(_("Type:"), 'type', null); } diff --git a/manufacturing/work_order_issue.php b/manufacturing/work_order_issue.php index dfe11060..86e3677a 100644 --- a/manufacturing/work_order_issue.php +++ b/manufacturing/work_order_issue.php @@ -73,28 +73,20 @@ function can_process() { global $Refs; - if (!is_date($_POST['date_'])) + if (!is_date($_POST['date_'])) { display_error(_("The entered date for the issue is invalid.")); set_focus('date_'); return false; } - elseif (!is_date_in_fiscalyear($_POST['date_'])) + elseif (!is_date_in_fiscalyear($_POST['date_'])) { display_error(_("The entered date is out of fiscal year or is closed for further data entry.")); set_focus('date_'); return false; } - if (!$Refs->is_valid($_POST['ref'])) + if (!check_reference($_POST['ref'], ST_MANUISSUE)) { - display_error(_("You must enter a reference.")); - set_focus('ref'); - return false; - } - - if (!is_new_reference($_POST['ref'], ST_MANUISSUE)) - { - display_error(_("The entered reference is already in use.")); set_focus('ref'); return false; } diff --git a/purchasing/includes/db/invoice_db.inc b/purchasing/includes/db/invoice_db.inc index 543df442..11ce9f93 100644 --- a/purchasing/includes/db/invoice_db.inc +++ b/purchasing/includes/db/invoice_db.inc @@ -597,7 +597,7 @@ function void_supp_invoice($type, $type_no) //Chaitanya : Post a journal entry $id = get_next_trans_no(ST_JOURNAL); - $ref = $Refs->get_next(ST_JOURNAL); + $ref = $Refs->get_next(ST_JOURNAL, null, $date_); add_journal(ST_JOURNAL, $id, $details_row["quantity"] * $diff, $old_date, get_company_currency(), $ref); $stock_id = $details_row["stock_id"]; $stock_gl_code = get_stock_gl_code($stock_id); diff --git a/purchasing/includes/purchasing_db.inc b/purchasing/includes/purchasing_db.inc index 7b18d6ca..98308576 100644 --- a/purchasing/includes/purchasing_db.inc +++ b/purchasing/includes/purchasing_db.inc @@ -211,7 +211,7 @@ function add_direct_supp_trans($cart) $inv_no = add_supp_invoice($inv); if ($cart->cash_account) { - $pmt_no = write_supp_payment(0, $inv->supplier_id, $cart->cash_account, $inv->tran_date, $Refs->get_next(ST_SUPPAYMENT), + $pmt_no = write_supp_payment(0, $inv->supplier_id, $cart->cash_account, $inv->tran_date, $Refs->get_next(ST_SUPPAYMENT, null, $inv->tran_date), $total, 0, _('Payment for:').$inv->supp_reference .' ('.$type_shortcuts[ST_SUPPINVOICE].$inv_no.')'); add_supp_allocation($total, ST_SUPPAYMENT, $pmt_no, ST_SUPPINVOICE, $inv_no, $inv->supplier_id, $inv->tran_date); update_supp_trans_allocation(ST_SUPPINVOICE, $inv_no, $inv->supplier_id); diff --git a/purchasing/includes/ui/grn_ui.inc b/purchasing/includes/ui/grn_ui.inc index 4ac5c5bc..5d2c25a2 100644 --- a/purchasing/includes/ui/grn_ui.inc +++ b/purchasing/includes/ui/grn_ui.inc @@ -60,7 +60,7 @@ function edit_grn_summary(&$po) table_section(2); if (!isset($_POST['ref'])) - $_POST['ref'] = $Refs->get_next(ST_SUPPRECEIVE); + $_POST['ref'] = $Refs->get_next(ST_SUPPRECEIVE, null, array('supplier' => $po->supplier_id, 'date' => Today())); ref_row(_("Reference"), 'ref', '', null); if (!isset($_POST['Location'])) diff --git a/purchasing/includes/ui/invoice_ui.inc b/purchasing/includes/ui/invoice_ui.inc index 1da839bb..6c799b44 100644 --- a/purchasing/includes/ui/invoice_ui.inc +++ b/purchasing/includes/ui/invoice_ui.inc @@ -117,7 +117,10 @@ function invoice_header(&$supp_trans) copy_from_trans($supp_trans); } - ref_row(_("Reference:"), 'reference', '', $Refs->get_next($supp_trans->trans_type)); + date_row(_("Date") . ":", 'tran_date', '', true, 0, 0, 0, "", true); + + ref_row(_("Reference:"), 'reference', '', $Refs->get_next($supp_trans->trans_type, null, + array('supplier' => get_post('supplier_id'), 'date' => get_post('tran_date'))), false, $supp_trans->trans_type); if ($supp_trans->trans_type == ST_SUPPCREDIT) { @@ -133,7 +136,6 @@ function invoice_header(&$supp_trans) table_section(2, "33%"); - date_row(_("Date") . ":", 'tran_date', '', true, 0, 0, 0, "", true); if (isset($_POST['_tran_date_changed'])) { $Ajax->activate('_ex_rate'); $supp_trans->tran_date = $_POST['tran_date']; diff --git a/purchasing/includes/ui/po_ui.inc b/purchasing/includes/ui/po_ui.inc index 67ce8676..ae063b6e 100644 --- a/purchasing/includes/ui/po_ui.inc +++ b/purchasing/includes/ui/po_ui.inc @@ -84,7 +84,8 @@ function create_new_po($trans_type, $trans_no) read_po($trans_no, $cart); $cart->order_no = $trans_no; } else - $cart->reference = $Refs->get_next($trans_type); + $cart->reference = $Refs->get_next($trans_type, null, + array('supplier_id' => $cart->supplier_id, 'date' => get_post('OrderDate'))); $_SESSION['PO'] = &$cart; } diff --git a/purchasing/po_entry_items.php b/purchasing/po_entry_items.php index 17e123f9..a4afb367 100644 --- a/purchasing/po_entry_items.php +++ b/purchasing/po_entry_items.php @@ -353,22 +353,14 @@ function can_commit() if (!$_SESSION['PO']->order_no) { - if (!$Refs->is_valid(get_post('ref'))) + if (!check_reference(get_post('ref'), $_SESSION['PO']->trans_type)) { - display_error(_("There is no reference entered for this purchase order.")); - set_focus('ref'); - return false; - } - - if (!is_new_reference(get_post('ref'), $_SESSION['PO']->trans_type)) - { - display_error(_("The entered reference is already in use.")); set_focus('ref'); return false; } } - if ($_SESSION['PO']->trans_type == ST_SUPPINVOICE && !$Refs->is_valid(get_post('supp_ref'))) + if ($_SESSION['PO']->trans_type == ST_SUPPINVOICE && empty(trim(get_post('supp_ref')))) { display_error(_("You must enter a supplier's invoice reference.")); set_focus('supp_ref'); diff --git a/purchasing/po_receive_items.php b/purchasing/po_receive_items.php index da277b27..0ea2cef1 100644 --- a/purchasing/po_receive_items.php +++ b/purchasing/po_receive_items.php @@ -181,16 +181,8 @@ function can_process() return false; } - if (!$Refs->is_valid($_POST['ref'])) - { - display_error(_("You must enter a reference.")); - set_focus('ref'); - return false; - } - - if (!is_new_reference($_POST['ref'], ST_SUPPRECEIVE)) + if (!check_reference($_POST['ref'], ST_SUPPRECEIVE)) { - display_error(_("The entered reference is already in use.")); set_focus('ref'); return false; } @@ -281,7 +273,8 @@ if (isset($_GET['PONumber']) && $_GET['PONumber'] > 0 && !isset($_POST['Update'] { create_new_po(ST_PURCHORDER, $_GET['PONumber']); $_SESSION['PO']->trans_type = ST_SUPPRECEIVE; - $_SESSION['PO']->reference = $Refs->get_next(ST_SUPPRECEIVE); + $_SESSION['PO']->reference = $Refs->get_next(ST_SUPPRECEIVE, + array('date' => $_SESSION['PO']->tran_date, 'supplier' => $_SESSION['PO']->supplier_id)); copy_from_cart(); } diff --git a/purchasing/supplier_credit.php b/purchasing/supplier_credit.php index c2fe7c61..19337cbe 100644 --- a/purchasing/supplier_credit.php +++ b/purchasing/supplier_credit.php @@ -170,27 +170,12 @@ function check_data() return false; } - if (!$Refs->is_valid($_SESSION['supp_trans']->reference)) + if (!check_reference($_SESSION['supp_trans']->reference, ST_SUPPCREDIT, $_SESSION['supp_trans']->trans_no)) { - display_error(_("You must enter an credit note reference.")); set_focus('reference'); return false; } - if (!is_new_reference($_SESSION['supp_trans']->reference, ST_SUPPCREDIT, $_SESSION['supp_trans']->trans_no)) - { - display_error(_("The entered reference is already in use.")); - set_focus('reference'); - return false; - } - - if (!$Refs->is_valid($_SESSION['supp_trans']->supp_reference)) - { - display_error(_("You must enter a supplier's credit note reference.")); - set_focus('supp_reference'); - return false; - } - if (!is_date($_SESSION['supp_trans']->tran_date)) { display_error(_("The credit note as entered cannot be processed because the date entered is not valid.")); diff --git a/purchasing/supplier_invoice.php b/purchasing/supplier_invoice.php index 696cd6d6..faf540e3 100644 --- a/purchasing/supplier_invoice.php +++ b/purchasing/supplier_invoice.php @@ -178,27 +178,12 @@ function check_data() return false; } - if (!$Refs->is_valid($_SESSION['supp_trans']->reference)) + if (!check_reference($_SESSION['supp_trans']->reference, ST_SUPPINVOICE, $_SESSION['supp_trans']->trans_no)) { - display_error(_("You must enter an invoice reference.")); set_focus('reference'); return false; } - if (!is_new_reference($_SESSION['supp_trans']->reference, ST_SUPPINVOICE, $_SESSION['supp_trans']->trans_no)) - { - display_error(_("The entered reference is already in use.")); - set_focus('reference'); - return false; - } - - if (!$Refs->is_valid($_SESSION['supp_trans']->supp_reference)) - { - display_error(_("You must enter a supplier's invoice reference.")); - set_focus('supp_reference'); - return false; - } - if (!is_date( $_SESSION['supp_trans']->tran_date)) { display_error(_("The invoice as entered cannot be processed because the invoice date is in an incorrect format.")); diff --git a/purchasing/supplier_payment.php b/purchasing/supplier_payment.php index 955bd23c..323ff16e 100644 --- a/purchasing/supplier_payment.php +++ b/purchasing/supplier_payment.php @@ -202,16 +202,8 @@ function check_inputs() return false; } - if (!$Refs->is_valid($_POST['ref'])) - { - display_error(_("You must enter a reference.")); - set_focus('ref'); - return false; - } - - if (!is_new_reference($_POST['ref'], ST_SUPPAYMENT)) + if (!check_reference($_POST['ref'], ST_SUPPAYMENT)) { - display_error(_("The entered reference is already in use.")); set_focus('ref'); return false; } @@ -295,7 +287,9 @@ start_form(); date_row(_("Date Paid") . ":", 'DatePaid', '', true, 0, 0, 0, null, true); - ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_SUPPAYMENT)); + ref_row(_("Reference:"), 'ref', '', $Refs->get_next(ST_SUPPAYMENT, null, + array('supplier'=>get_post('supplier_id'), 'date'=>get_post('DatePaid'))), false, ST_SUPPAYMENT); + table_section(3); diff --git a/sales/create_recurrent_invoices.php b/sales/create_recurrent_invoices.php index 0d71d9d4..de93bd5c 100644 --- a/sales/create_recurrent_invoices.php +++ b/sales/create_recurrent_invoices.php @@ -38,7 +38,8 @@ function create_recurrent_invoices($customer_id, $branch_id, $order_no, $tmpl_no $doc->document_date = $date; $doc->due_date = get_invoice_duedate($doc->payment, $doc->document_date); - $doc->reference = $Refs->get_next($doc->trans_type); + $doc->reference = $Refs->get_next($doc->trans_type, null, array('customer' => $customer_id, 'branch' => $branch_id, + 'date' => $date)); if ($doc->Comments != "") $doc->Comments .= "\n"; $doc->Comments .= sprintf(_("Recurrent Invoice covers period %s - %s."), $from, add_days($to, -1)); @@ -50,7 +51,8 @@ function create_recurrent_invoices($customer_id, $branch_id, $order_no, $tmpl_no } $cart = $doc; $cart->trans_type = ST_SALESINVOICE; - $cart->reference = $Refs->get_next($cart->trans_type); + $cart->reference = $Refs->get_next($cart->trans_type, null, array('customer' => $customer_id, 'branch' => $branch_id, + 'date' => $date)); $invno = $cart->write(1); if ($invno == -1) { diff --git a/sales/credit_note_entry.php b/sales/credit_note_entry.php index 8181f7a3..98fd6c1e 100644 --- a/sales/credit_note_entry.php +++ b/sales/credit_note_entry.php @@ -143,7 +143,7 @@ function can_process() if ($_SESSION['Items']->count_items() == 0 && (!check_num('ChargeFreightCost',0))) return false; if($_SESSION['Items']->trans_no == 0) { - if (!$Refs->is_valid($_POST['ref'])) { + if (!$Refs->is_valid($_POST['ref'], ST_CUSTCREDIT)) { display_error( _("You must enter a reference.")); set_focus('ref'); $input_error = 1; diff --git a/sales/customer_credit_invoice.php b/sales/customer_credit_invoice.php index 7cf3856d..bb1445be 100644 --- a/sales/customer_credit_invoice.php +++ b/sales/customer_credit_invoice.php @@ -97,7 +97,7 @@ function can_process() } if ($_SESSION['Items']->trans_no==0) { - if (!$Refs->is_valid($_POST['ref'])) { + if (!$Refs->is_valid($_POST['ref'], ST_CUSTCREDIT)) { display_error(_("You must enter a reference."));; set_focus('ref'); return false; @@ -241,7 +241,10 @@ function display_credit_items() // $_POST['ref'] = $Refs->get_next(11); if ($_SESSION['Items']->trans_no==0) { - ref_cells(_("Reference"), 'ref', '', null, "class='tableheader2'"); + ref_cells(_("Reference"), 'ref', '', null, "class='tableheader2'", false, ST_CUSTCREDIT, + array('customer' => $_SESSION['Items']->customer_id, + 'branch' => $_SESSION['Items']->Branch, + 'date' => get_post('CreditDate'))); } else { label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'"); } diff --git a/sales/customer_delivery.php b/sales/customer_delivery.php index a49c5c55..767fd7c2 100644 --- a/sales/customer_delivery.php +++ b/sales/customer_delivery.php @@ -173,7 +173,7 @@ function check_data() } if ($_SESSION['Items']->trans_no==0) { - if (!$Refs->is_valid($_POST['ref'])) { + if (!$Refs->is_valid($_POST['ref'], ST_CUSTDELIVERY)) { display_error(_("You must enter a reference.")); set_focus('ref'); return false; @@ -333,7 +333,10 @@ start_row(); // $_POST['ref'] = $Refs->get_next(ST_CUSTDELIVERY); if ($_SESSION['Items']->trans_no==0) { - ref_cells(_("Reference"), 'ref', '', null, "class='tableheader2'"); + ref_cells(_("Reference"), 'ref', '', null, "class='tableheader2'", false, ST_CUSTDELIVERY, + array('customer' => $_SESSION['Items']->customer_id, + 'branch' => $_SESSION['Items']->Branch, + 'date' => get_post('DispatchDate')); } else { label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'"); } diff --git a/sales/customer_invoice.php b/sales/customer_invoice.php index ec423402..10993cc0 100644 --- a/sales/customer_invoice.php +++ b/sales/customer_invoice.php @@ -331,7 +331,7 @@ function check_data() } if ($_SESSION['Items']->trans_no == 0) { - if (!$Refs->is_valid($_POST['ref'])) { + if (!$Refs->is_valid($_POST['ref'], ST_SALESINVOICE)) { display_error(_("You must enter a reference.")); set_focus('ref'); return false; @@ -460,7 +460,10 @@ end_row(); start_row(); if ($_SESSION['Items']->trans_no == 0) { - ref_cells(_("Reference"), 'ref', '', null, "class='tableheader2'"); + ref_cells(_("Reference"), 'ref', '', null, "class='tableheader2'", false, ST_SALESINVOICE, + array('customer' => $_SESSION['Items']->customer_id, + 'branch' => $_SESSION['Items']->Branch, + 'date' => get_post('InvoiceDate'))); } else { label_cells(_("Reference"), $_SESSION['Items']->reference, "class='tableheader2'"); } diff --git a/sales/customer_payments.php b/sales/customer_payments.php index c2f09eff..10742c88 100644 --- a/sales/customer_payments.php +++ b/sales/customer_payments.php @@ -159,22 +159,7 @@ function can_process() return false; } - if (!$Refs->is_valid($_POST['ref'])) { - display_error(_("You must enter a reference.")); - set_focus('ref'); - return false; - } - - //Chaitanya : 13-OCT-2011 - To support Edit feature - if (isset($_POST['trans_no']) && $_POST['trans_no'] == 0 && (!is_new_reference($_POST['ref'], ST_CUSTPAYMENT))) { - display_error(_("The entered reference is already in use.")); - set_focus('ref'); - return false; - } - //Avoid duplicate reference while modifying - elseif ($_POST['ref'] != $_POST['old_ref'] && !is_new_reference($_POST['ref'], ST_CUSTPAYMENT)) - { - display_error( _("The entered reference is already in use.")); + if (!check_reference($_POST['ref'], ST_CUSTPAYMENT, @$_POST['trans_no'])) { set_focus('ref'); return false; } @@ -281,12 +266,12 @@ function read_customer_data() //Chaitanya : 13-OCT-2011 - To support Edit feature //If page is called first time and New entry fetch the nex reference number if (!$_SESSION['alloc']->trans_no && !isset($_POST['charge'])) - $_POST['ref'] = $Refs->get_next(ST_CUSTPAYMENT); + $_POST['ref'] = $Refs->get_next(ST_CUSTPAYMENT, null, array( + 'customer' => get_post('customer_id'), 'date' => get_post('DateBanked'))); } //---------------------------------------------------------------------------------------------- $new = 1; -$old_ref = 0; //Chaitanya : 13-OCT-2011 - To support Edit feature if (isset($_GET['trans_no']) && $_GET['trans_no'] > 0 ) @@ -300,7 +285,6 @@ if (isset($_GET['trans_no']) && $_GET['trans_no'] > 0 ) $_POST['BranchID'] = $myrow["branch_code"]; $_POST['bank_account'] = $myrow["bank_act"]; $_POST['ref'] = $myrow["reference"]; - $old_ref = $myrow["reference"]; $charge = get_cust_bank_charge(ST_CUSTPAYMENT, $_POST['trans_no']); $_POST['charge'] = price_format($charge); $_POST['DateBanked'] = sql2date($myrow['tran_date']); @@ -324,7 +308,6 @@ $new = !$_SESSION['alloc']->trans_no; start_form(); hidden('trans_no'); - hidden('old_ref', $old_ref); start_outer_table(TABLESTYLE2, "width='60%'", 5); diff --git a/sales/includes/cart_class.inc b/sales/includes/cart_class.inc index dbfd5106..3bfb9526 100644 --- a/sales/includes/cart_class.inc +++ b/sales/includes/cart_class.inc @@ -135,7 +135,8 @@ class cart $type = get_child_type($this->trans_type); $this->trans_type = $type; - $this->reference = $Refs->get_next($this->trans_type); + $this->reference = $Refs->get_next($this->trans_type, null, array('date' => $this->document_date, + 'customer' => $this->customer_id, 'branch' => $this->Branch)); if ($type == ST_CUSTCREDIT) $this->src_date = $this->document_date; @@ -244,7 +245,8 @@ class cart $this->document_date = new_doc_date(); if (!is_date_in_fiscalyear($this->document_date)) $this->document_date = end_fiscalyear(); - $this->reference = $Refs->get_next($this->trans_type); + $this->reference = $Refs->get_next($this->trans_type, null, array('date' => Today(), + 'customer' => $this->customer_id)); if ($type != ST_SALESORDER && $type != ST_SALESQUOTE) // Added 2.1 Joe Hunt 2008-11-12 { $dim = get_company_pref('use_dimension'); diff --git a/sales/includes/db/sales_invoice_db.inc b/sales/includes/db/sales_invoice_db.inc index c944c6bf..4028233e 100644 --- a/sales/includes/db/sales_invoice_db.inc +++ b/sales/includes/db/sales_invoice_db.inc @@ -195,7 +195,9 @@ function write_sales_invoice(&$invoice) $discount = 0; // $invoice->cash_discount*$amount; $pmtno = write_customer_payment(0, $invoice->customer_id, $invoice->Branch, $invoice->pos['pos_account'], $date_, - $Refs->get_next(ST_CUSTPAYMENT), $amount-$discount, $discount, + $Refs->get_next(ST_CUSTPAYMENT, null, array('customer' => $invoice->customer_id, + 'branch' => $invoice->Branch, 'date' => $date_)), + $amount-$discount, $discount, _('Cash invoice').' '.$invoice_no); add_cust_allocation($amount, ST_CUSTPAYMENT, $pmtno, ST_SALESINVOICE, $invoice_no, $invoice->customer_id, $date_); diff --git a/sales/includes/db/sales_order_db.inc b/sales/includes/db/sales_order_db.inc index ff61aaa5..9a683f1e 100644 --- a/sales/includes/db/sales_order_db.inc +++ b/sales/includes/db/sales_order_db.inc @@ -98,8 +98,6 @@ function delete_sales_order($order_no, $trans_type) .db_escape($order_no) . " AND trans_type=".db_escape($trans_type); db_query($sql, "order Detail Delete"); - delete_reference($trans_type, $order_no); - add_audit_trail($trans_type, $order_no, Today(), _("Deleted.")); commit_transaction(); } diff --git a/sales/includes/ui/sales_credit_ui.inc b/sales/includes/ui/sales_credit_ui.inc index 0bbd100e..627358ec 100644 --- a/sales/includes/ui/sales_credit_ui.inc +++ b/sales/includes/ui/sales_credit_ui.inc @@ -80,7 +80,8 @@ function display_credit_header(&$order) set_global_customer($_POST['customer_id']); if (!isset($_POST['ref'])) - $_POST['ref'] = $Refs->get_next(ST_CUSTCREDIT); + $_POST['ref'] = $Refs->get_next(ST_CUSTCREDIT, null, array('customer' => get_post('customer_id'), + 'branch' => get_post('branch_id'), 'date' => get_post('OrderDate')); if ($order->trans_no==0) ref_row(_("Reference").':', 'ref'); else diff --git a/sales/includes/ui/sales_order_ui.inc b/sales/includes/ui/sales_order_ui.inc index a515859b..043d2514 100644 --- a/sales/includes/ui/sales_order_ui.inc +++ b/sales/includes/ui/sales_order_ui.inc @@ -361,7 +361,7 @@ function display_order_header(&$order, $editable, $date_text) } } - ref_row(_("Reference").':', 'ref', _('Reference number unique for this document type'), null, ''); + ref_row(_("Reference").':', 'ref', _('Reference number unique for this document type'), null, '', $order->trans_type, array('date'=> @$_POST['OrderDate'])); table_section(2); diff --git a/sales/sales_order_entry.php b/sales/sales_order_entry.php index b608c200..f3e84af7 100644 --- a/sales/sales_order_entry.php +++ b/sales/sales_order_entry.php @@ -431,7 +431,7 @@ function can_process() { return false; } } - if (!$Refs->is_valid($_POST['ref'])) { + if (!$Refs->is_valid($_POST['ref'], $_SESSION['Items']->trans_type)) { display_error(_("You must enter a reference.")); set_focus('ref'); return false; @@ -462,7 +462,7 @@ if (isset($_POST['ProcessOrder']) && can_process()) { if ($ret == -1) { display_error(_("The entered reference is already in use.")); - $ref = get_next_reference($_SESSION['Items']->trans_type); + $ref = $Refs->get_next($_SESSION['Items']->trans_type, null, array('date' => Today())); if ($ref != $_SESSION['Items']->reference) { display_error(_("The reference number field has been increased. Please save the document again.")); @@ -658,7 +658,7 @@ function create_cart($type, $trans_no) $doc->pos = get_sales_point(user_pos()); } else $doc->due_date = $doc->document_date; - $doc->reference = $Refs->get_next($doc->trans_type); + $doc->reference = $Refs->get_next($doc->trans_type, null, array('date' => Today())); //$doc->Comments=''; foreach($doc->line_items as $line_no => $line) { $doc->line_items[$line_no]->qty_done = 0; diff --git a/sql/alter2.4.sql b/sql/alter2.4.sql index 56aa0199..2e765bfb 100644 --- a/sql/alter2.4.sql +++ b/sql/alter2.4.sql @@ -240,3 +240,20 @@ UPDATE `0_salesman` SET `break_pt` = `break_pt`*100.0/`provision` WHERE `provision` != 0; +# reference lines +DROP TABLE IF EXISTS `0_reflines`; +CREATE TABLE `0_reflines` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `trans_type` int(11) NOT NULL, + `prefix` char(5) NOT NULL DEFAULT '', + `pattern` varchar(35) NOT NULL DEFAULT '1', + `description` varchar(60) NOT NULL DEFAULT '', + `default` tinyint(1) NOT NULL DEFAULT '0', + `inactive` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `prefix` (`trans_type`, `prefix`) +) ENGINE=InnoDB; + +INSERT INTO `0_reflines` (`trans_type`, `pattern`, `default`) SELECT `type_id`, `next_reference`, 1 FROM `0_sys_types`; + +DROP TABLE `0_sys_types`; diff --git a/sql/en_US-demo.sql b/sql/en_US-demo.sql index 2540c7bc..ba10cf95 100644 --- a/sql/en_US-demo.sql +++ b/sql/en_US-demo.sql @@ -1465,6 +1465,48 @@ CREATE TABLE IF NOT EXISTS `0_recurrent_invoices` ( -- +--- Structure of table `0_reflines` + +DROP TABLE IF EXISTS `0_reflines`; + +CREATE TABLE `0_reflines` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `trans_type` int(11) NOT NULL, + `prefix` char(5) NOT NULL DEFAULT '', + `pattern` varchar(35) NOT NULL DEFAULT '1', + `description` varchar(60) NOT NULL DEFAULT '', + `default` tinyint(1) NOT NULL DEFAULT '0', + `inactive` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `prefix` (`trans_type`, `prefix`) +) ENGINE=InnoDB AUTO_INCREMENT=23; + +--- Data of table `0_reflines` + +INSERT INTO `0_reflines` VALUES +('1', '0', '', '{001}/{YYYY}', '', '1', '0'), +('2', '1', '', '{001}/{YYYY}', '', '1', '0'), +('3', '2', '', '{001}/{YYYY}', '', '1', '0'), +('4', '4', '', '{001}/{YYYY}', '', '1', '0'), +('5', '10', '', '{001}/{YYYY}', '', '1', '0'), +('6', '11', '', '{001}/{YYYY}', '', '1', '0'), +('7', '12', '', '{001}/{YYYY}', '', '1', '0'), +('8', '13', '', '{001}/{YYYY}', '', '1', '0'), +('9', '16', '', '{001}/{YYYY}', '', '1', '0'), +('10', '17', '', '{001}/{YYYY}', '', '1', '0'), +('11', '18', '', '{001}/{YYYY}', '', '1', '0'), +('12', '20', '', '{001}/{YYYY}', '', '1', '0'), +('13', '21', '', '{001}/{YYYY}', '', '1', '0'), +('14', '22', '', '{001}/{YYYY}', '', '1', '0'), +('15', '25', '', '{001}/{YYYY}', '', '1', '0'), +('16', '26', '', '{001}/{YYYY}', '', '1', '0'), +('17', '28', '', '{001}/{YYYY}', '', '1', '0'), +('18', '29', '', '{001}/{YYYY}', '', '1', '0'), +('19', '30', '', '{001}/{YYYY}', '', '1', '0'), +('20', '32', '', '{001}/{YYYY}', '', '1', '0'), +('21', '35', '', '{001}/{YYYY}', '', '1', '0'), +('22', '40', '', '{001}/{YYYY}', '', '1', '0'); + -- -------------------------------------------------------- -- @@ -2095,48 +2137,6 @@ INSERT INTO `0_sys_prefs` VALUES('print_item_images_on_quote','glsetup.inventory INSERT INTO `0_sys_prefs` VALUES('alternative_tax_include_on_docs','setup.company', 'tinyint', 1, '0'); INSERT INTO `0_sys_prefs` VALUES('suppress_tax_rates','setup.company', 'tinyint', 1, '0'); - --- -------------------------------------------------------- - --- --- Table structure for table `0_sys_types` --- - -DROP TABLE IF EXISTS `0_sys_types`; -CREATE TABLE IF NOT EXISTS `0_sys_types` ( - `type_id` smallint(6) NOT NULL default '0', - `type_no` int(11) NOT NULL default '1', - `next_reference` varchar(100) NOT NULL default '', - PRIMARY KEY (`type_id`) -) ENGINE=InnoDB; - --- --- Dumping data for table `0_sys_types` --- - -INSERT INTO `0_sys_types` VALUES(0, 19, '3'); -INSERT INTO `0_sys_types` VALUES(1, 8, '2'); -INSERT INTO `0_sys_types` VALUES(2, 5, '2'); -INSERT INTO `0_sys_types` VALUES(4, 3, '1'); -INSERT INTO `0_sys_types` VALUES(10, 19, '4'); -INSERT INTO `0_sys_types` VALUES(11, 3, '2'); -INSERT INTO `0_sys_types` VALUES(12, 6, '1'); -INSERT INTO `0_sys_types` VALUES(13, 5, '2'); -INSERT INTO `0_sys_types` VALUES(16, 2, '1'); -INSERT INTO `0_sys_types` VALUES(17, 2, '1'); -INSERT INTO `0_sys_types` VALUES(18, 1, '3'); -INSERT INTO `0_sys_types` VALUES(20, 8, '3'); -INSERT INTO `0_sys_types` VALUES(21, 1, '1'); -INSERT INTO `0_sys_types` VALUES(22, 4, '2'); -INSERT INTO `0_sys_types` VALUES(25, 1, '2'); -INSERT INTO `0_sys_types` VALUES(26, 1, '8'); -INSERT INTO `0_sys_types` VALUES(28, 1, '1'); -INSERT INTO `0_sys_types` VALUES(29, 1, '2'); -INSERT INTO `0_sys_types` VALUES(30, 5, '6'); -INSERT INTO `0_sys_types` VALUES(32, 0, '1'); -INSERT INTO `0_sys_types` VALUES(35, 1, '1'); -INSERT INTO `0_sys_types` VALUES(40, 1, '3'); - -- -------------------------------------------------------- -- diff --git a/sql/en_US-new.sql b/sql/en_US-new.sql index 27ec7b3a..1c21bd9c 100644 --- a/sql/en_US-new.sql +++ b/sql/en_US-new.sql @@ -1290,6 +1290,48 @@ CREATE TABLE IF NOT EXISTS `0_recurrent_invoices` ( -- +--- Structure of table `0_reflines` + +DROP TABLE IF EXISTS `0_reflines`; + +CREATE TABLE `0_reflines` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `trans_type` int(11) NOT NULL, + `prefix` char(5) NOT NULL DEFAULT '', + `pattern` varchar(35) NOT NULL DEFAULT '1', + `description` varchar(60) NOT NULL DEFAULT '', + `default` tinyint(1) NOT NULL DEFAULT '0', + `inactive` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `prefix` (`trans_type`, `prefix`) +) ENGINE=InnoDB AUTO_INCREMENT=23; + +--- Data of table `0_reflines` + +INSERT INTO `0_reflines` VALUES +('1', '0', '', '{001}/{YYYY}', '', '1', '0'), +('2', '1', '', '{001}/{YYYY}', '', '1', '0'), +('3', '2', '', '{001}/{YYYY}', '', '1', '0'), +('4', '4', '', '{001}/{YYYY}', '', '1', '0'), +('5', '10', '', '{001}/{YYYY}', '', '1', '0'), +('6', '11', '', '{001}/{YYYY}', '', '1', '0'), +('7', '12', '', '{001}/{YYYY}', '', '1', '0'), +('8', '13', '', '{001}/{YYYY}', '', '1', '0'), +('9', '16', '', '{001}/{YYYY}', '', '1', '0'), +('10', '17', '', '{001}/{YYYY}', '', '1', '0'), +('11', '18', '', '{001}/{YYYY}', '', '1', '0'), +('12', '20', '', '{001}/{YYYY}', '', '1', '0'), +('13', '21', '', '{001}/{YYYY}', '', '1', '0'), +('14', '22', '', '{001}/{YYYY}', '', '1', '0'), +('15', '25', '', '{001}/{YYYY}', '', '1', '0'), +('16', '26', '', '{001}/{YYYY}', '', '1', '0'), +('17', '28', '', '{001}/{YYYY}', '', '1', '0'), +('18', '29', '', '{001}/{YYYY}', '', '1', '0'), +('19', '30', '', '{001}/{YYYY}', '', '1', '0'), +('20', '32', '', '{001}/{YYYY}', '', '1', '0'), +('21', '35', '', '{001}/{YYYY}', '', '1', '0'), +('22', '40', '', '{001}/{YYYY}', '', '1', '0'); + -- -------------------------------------------------------- -- @@ -1852,47 +1894,6 @@ INSERT INTO `0_sys_prefs` VALUES('suppress_tax_rates','setup.company', 'tinyint' -- -------------------------------------------------------- --- --- Table structure for table `0_sys_types` --- - -DROP TABLE IF EXISTS `0_sys_types`; -CREATE TABLE IF NOT EXISTS `0_sys_types` ( - `type_id` smallint(6) NOT NULL default '0', - `type_no` int(11) NOT NULL default '1', - `next_reference` varchar(100) NOT NULL default '', - PRIMARY KEY (`type_id`) -) ENGINE=InnoDB; - --- --- Dumping data for table `0_sys_types` --- - -INSERT INTO `0_sys_types` VALUES(0, 17, '1'); -INSERT INTO `0_sys_types` VALUES(1, 7, '1'); -INSERT INTO `0_sys_types` VALUES(2, 4, '1'); -INSERT INTO `0_sys_types` VALUES(4, 3, '1'); -INSERT INTO `0_sys_types` VALUES(10, 16, '1'); -INSERT INTO `0_sys_types` VALUES(11, 2, '1'); -INSERT INTO `0_sys_types` VALUES(12, 6, '1'); -INSERT INTO `0_sys_types` VALUES(13, 1, '1'); -INSERT INTO `0_sys_types` VALUES(16, 2, '1'); -INSERT INTO `0_sys_types` VALUES(17, 2, '1'); -INSERT INTO `0_sys_types` VALUES(18, 1, '1'); -INSERT INTO `0_sys_types` VALUES(20, 6, '1'); -INSERT INTO `0_sys_types` VALUES(21, 1, '1'); -INSERT INTO `0_sys_types` VALUES(22, 3, '1'); -INSERT INTO `0_sys_types` VALUES(25, 1, '1'); -INSERT INTO `0_sys_types` VALUES(26, 1, '1'); -INSERT INTO `0_sys_types` VALUES(28, 1, '1'); -INSERT INTO `0_sys_types` VALUES(29, 1, '1'); -INSERT INTO `0_sys_types` VALUES(30, 0, '1'); -INSERT INTO `0_sys_types` VALUES(32, 0, '1'); -INSERT INTO `0_sys_types` VALUES(35, 1, '1'); -INSERT INTO `0_sys_types` VALUES(40, 1, '1'); - --- -------------------------------------------------------- - -- -- Table structure for table `0_tags` -- -- 2.30.2