Stable branch merged up to 2.3.21
[fa-stable.git] / includes / references.inc
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 include_once($path_to_root . "/includes/db/references_db.inc");
13 //---------------------------------------------------------------------------------------------
14 //
15 // For now (2.3) the references system has somewhat inconsistent design scheme.
16 // Most transactions store references in respective table, but this is not the case
17 // for journal entries. All references regardless of type are stored also in refs table. 
18 // Reference uniquness now can be checked with is_new_reference() for all transactions. 
19 // In near future this should be fixed either with removing reference fields 
20 // in transaction tables, or adding ref in bank transaction/journal and removing refs table.
21 //
22
23 class references 
24 {
25         //
26         //      Get reference from refs table for given transaction.
27         //      Used for transactions which do not hold references (journal and bank).
28         //
29         function get($type, $id) 
30         {
31                 return get_reference($type, $id);
32         }
33         //
34         // Check if reference is used for any non voided transaction (used for ST_JOURNALENTRY type)
35         //
36         function exists($type, $reference) 
37         {
38                 return (find_reference($type, $reference) != null);
39         }
40         //
41         // Get default reference on new transaction creation.
42         //
43         function get_next($type) 
44         {
45                 return get_next_reference($type);
46         }
47         //
48         // Check reference is valid before add/update transaction.
49         //
50         function is_valid($reference) 
51         {
52                 return strlen(trim($reference)) > 0;
53         }
54         //
55         //      Save reference (and prepare next) on write transaction.
56         //
57         function save($type, $id, $reference) 
58         {
59                 update_reference($type, $id, $reference); // store in refs table
60                 if ($reference == $this->get_next($type)) { // if reference was bigger or not changed from default
61                         $next = $this->_increment($reference);  // increment default
62                         save_next_reference($type, $next);
63                 }
64         }
65         //
66         // Restore previous reference (if possible) after voiding transaction.
67         //
68         function restore_last($type, $id) 
69         {
70                 $reference = get_reference($type, $id);
71                 $prev = $this->_increment($this->get_next($type), true); //decrement
72                 if ($reference==$prev) {
73                         save_next_reference($type, $prev);
74                 }
75         }
76         //-----------------------------------------------------------------------
77         //
78         //      Increments (or decrements if $back==true) reference template
79         //
80         function _increment($reference, $back=false) 
81         {
82                 // New method done by Pete. So f.i. WA036 will increment to WA037 and so on.
83         // If $reference contains at least one group of digits,
84         // extract first didgits group and add 1, then put all together.
85         // NB. preg_match returns 1 if the regex matches completely 
86         // also $result[0] holds entire string, 1 the first captured, 2 the 2nd etc.
87         //
88         if (preg_match('/^(\D*?)(\d+)(.*)/', $reference, $result) == 1) 
89         {
90                         list($all, $prefix, $number, $postfix) = $result;
91                         $dig_count = strlen($number); // How many digits? eg. 0003 = 4
92                         $fmt = '%0' . $dig_count . 'd'; // Make a format string - leading zeroes
93                         $val = intval($number + ($back ? ($number<1 ? 0 : -1) : 1));
94                         $nextval =  sprintf($fmt, $val); // Add one on, and put prefix back on
95
96                         return $prefix.$nextval.$postfix;
97         }
98         else 
99             return $reference;
100         }
101 }
102
103 //----------------------------------------------------------------------------
104 //
105 //      Check if reference was not used so far (for other transaction than $trans_no)
106 //
107 function is_new_reference($ref, $type, $trans_no=0)
108 {
109         $db_info = get_systype_db_info($type);
110         $db_name = $db_info[0];
111         $db_type = $db_info[1];
112         $db_trans = $db_info[2];
113         $db_ref = $db_info[3];
114         
115         $ref = db_escape(trim($ref));
116         $type = db_escape($type);
117         
118         if ($db_ref == null) { // journal or bank trans store references in refs table
119                 $db_name = TB_PREF."refs";
120                 $db_type = 'type';
121                 $db_trans = 'id';
122                 $db_ref = 'reference';
123         }
124
125         if ($db_type != null) {
126                 $sql = "SELECT $db_ref FROM $db_name tbl
127                         LEFT JOIN ".TB_PREF."voided v ON 
128                                 tbl.$db_type=v.type AND tbl.$db_trans=v.id
129                         WHERE $db_ref=$ref AND ISNULL(v.id)
130                                 AND tbl.$db_type=$type";
131         } else {
132                 $sql = "SELECT $db_ref ref FROM $db_name tbl
133                         LEFT JOIN ".TB_PREF."voided v ON 
134                                 v.type=$type AND tbl.$db_trans=v.id
135                         WHERE $db_ref=$ref AND ISNULL(v.id)";
136         }
137         if ($trans_no)
138                         $sql .= " AND tbl.`$db_trans` != ".db_escape($trans_no);
139
140         $result = db_query($sql, "could not test for unique reference");
141
142         return (db_num_rows($result) == 0);
143
144 }
145
146
147 ?>