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);
$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_);
$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)
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;
-}
-
See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************/
$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
"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);
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;
}
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);
$_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;
}
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);
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;
}
$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);
$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);
$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();
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;
}
$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
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_;
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;
}
{
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);
}
}
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_);
}
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_);
}
// display_error($sql);
return db_query($sql,"Cannot retrieve tax summary");
}
+
//--------------------------------------------------------------------------------------------------
function exists_gl_trans($type, $trans_id)
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%");
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;
}
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);
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;
+}
--- /dev/null
+<?php
+/**********************************************************************
+ Copyright (C) FrontAccounting, LLC.
+ Released under the terms of the GNU General Public License, GPL,
+ as published by the Free Software Foundation, either version 3
+ of the License, or (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
+***********************************************************************/
+
+// 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);
+ }
+}
+
--- /dev/null
+<?php
+/**********************************************************************
+ Copyright (C) FrontAccounting, LLC.
+ Released under the terms of the GNU General Public License, GPL,
+ as published by the Free Software Foundation, either version 3
+ of the License, or (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
+***********************************************************************/
+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");
+ }
+}
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)
+++ /dev/null
-<?php
-/**********************************************************************
- Copyright (C) FrontAccounting, LLC.
- Released under the terms of the GNU General Public License, GPL,
- as published by the Free Software Foundation, either version 3
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
-***********************************************************************/
-//--------------------------------------------------------------------------------------------------
-
-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);
-
-}
-
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************/
-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
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);
+}
--- /dev/null
+<?php
+/**********************************************************************
+ Copyright (C) FrontAccounting, LLC.
+ Released under the terms of the GNU General Public License, GPL,
+ as published by the Free Software Foundation, either version 3
+ of the License, or (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
+***********************************************************************/
+
+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 "<center>";
+
+ 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 "</center>";
+ 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 "<td align='center' $params>"
+ .button( "{$this->name}$name"
+ .($selected_id === null || $selected_id === $this->_none ? '': "[$selected_id]"),
+ $b[0], $b[1], $b[2], $b[3])."</td>";
+ }
+ //
+ // 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 '<td>';
+ echo $ctrls[$key];
+ echo '</td>';
+ }
+
+ if ($this->options['edit']) {
+ echo '<td>';
+ $this->tool_button($this->selected_id==$id ? 'UPDATE' : 'Edit', $id);
+ echo '</td>';
+ }
+ if ($this->options['delete']$this->selected_id==$id) {
+ echo '<td>';
+ $this->tool_button( ? 'Cancel' : 'Delete', $id);
+ echo '</td>';
+ }
+ 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();
+ }
+
+};
--- /dev/null
+<?php
+/**********************************************************************
+ Copyright (C) FrontAccounting, LLC.
+ Released under the terms of the GNU General Public License, GPL,
+ as published by the Free Software Foundation, either version 3
+ of the License, or (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
+***********************************************************************/
+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);
+ }
+}
echo "</tr>\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."<input name='".$name."' "
+ .(check_edit_access($name) ? '' : 'disabled ')
+ ."value='".@$_POST[$name]."' size=10 maxlength=35>");
+ }
+ 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 "<tr><td class='label'>$label</td>";
- ref_cells(null, $name, $title, $init, null, $submit_on_change);
+ ref_cells(null, $name, $title, $init, null, $submit_on_change, $type, $context);
echo "</tr>\n";
}
tax_algorithm_list_cells(null, $name, $value, $submit_on_change);
echo "</tr>\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 "<tr>";
+ if ($label != null)
+ echo "<td class='label'>$label</td>\n";
+ echo "<td>";
+
+ echo refline_list($name, $type, $selected_id, $spec_option);
+ echo "</td></tr>\n";
+}
+
+
//----------------------------------------------------------------------------------------------
function subledger_list($name, $account, $selected_id=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);
}
//--------------------------------------------------------------------------------------
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;
}
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
}
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
}
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;
}
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;
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);
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);
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);
echo "<br>";
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;
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);
{
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;
}
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;
small_qty_row(_("Quantity:"), 'quantity', null, null, null, $dec);
-date_row(_("Date:"), 'date_');
-
textarea_row(_("Memo:"), 'memo_', null, 40, 3);
end_table(1);
//-------------------------------------------------------------------------------------
if (!isset($_POST['ref']))
- $_POST['ref'] = $Refs->get_next(ST_JOURNAL);
+ $_POST['ref'] = $Refs->get_next(ST_JOURNAL, null, get_post('date_'));
start_form();
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;
}
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);
}
{
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;
}
//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);
$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);
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']))
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)
{
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'];
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;
}
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');
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;
}
{
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();
}
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."));
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."));
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;
}
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);
$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));
}
$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)
{
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;
}
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;
// $_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'");
}
}
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;
// $_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'");
}
}
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;
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'");
}
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;
}
//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 )
$_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']);
start_form();
hidden('trans_no');
- hidden('old_ref', $old_ref);
start_outer_table(TABLESTYLE2, "width='60%'", 5);
$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;
$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');
$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_);
.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();
}
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
}
}
- 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);
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;
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."));
$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;
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`;
--
+--- 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');
+
-- --------------------------------------------------------
--
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');
-
-- --------------------------------------------------------
--
--
+--- 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');
+
-- --------------------------------------------------------
--
-- --------------------------------------------------------
---
--- 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`
--