Merged last changes from stable.
[fa-stable.git] / includes / references.inc
index 6f3bd8916ec9b61e5357a2e4312896bbd62f30eb..6a8c7af2d0f87044206bc2fb0f243697e90b1051 100644 (file)
     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
 ***********************************************************************/
 include_once($path_to_root . "/includes/db/references_db.inc");
+//---------------------------------------------------------------------------------------------
+//
+// 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.
+//
 
 class references 
 {
-       
-       function save($type, $id, $reference) 
-       {
-               add_reference($type, $id, $reference);
-               
-               references::save_last($reference, $type);
-       }
-       
+       //
+       //      Get reference from refs table for given transaction.
+       //      Used for transactions which do not hold references (journal and bank).
+       //
        function get($type, $id) 
        {
                return get_reference($type, $id);
-       }       
-       
-       function delete($type, $id) 
-       {
-               delete_reference($type, $id);
-       }       
-       
+       }
+       //
+       // Check if reference is used for any non voided transaction (used for ST_JOURNALENTRY type)
+       //
        function exists($type, $reference) 
        {
                return (find_reference($type, $reference) != null);
        }
-       
-       function save_last($reference, $type) 
-       {
-               $next = references::increment($reference);
-               save_next_reference($type, $next);
-       }
-       
+       //
+       // Get default reference on new transaction creation.
+       //
        function get_next($type) 
        {
                return get_next_reference($type);
        }
-       
-       //------------------------------------
-
+       //
+       // Check reference is valid before add/update transaction.
+       //
        function is_valid($reference) 
        {
                return strlen(trim($reference)) > 0;
        }
-       
-       function increment($reference) 
+       //
+       //      Save reference (and prepare next) on write transaction.
+       //
+       function save($type, $id, $reference) 
        {
-        if (is_numeric($reference))
-               return $reference + 1;
+               update_reference($type, $id, $reference); // store in refs table
+               if ($reference == $this->get_next($type)) { // if reference was bigger or not changed from default
+                       $next = $this->_increment($reference);  // increment default
+                       save_next_reference($type, $next);
+               }
+       }
+       //
+       // Restore previous reference (if possible) after voiding transaction.
+       //
+       function restore_last($type, $id) 
+       {
+               $reference = get_reference($type, $id);
+               $prev = $this->_increment($this->get_next($type), true); //decrement
+               if ($reference==$prev) {
+                       save_next_reference($type, $prev);
+               }
+       }
+       //-----------------------------------------------------------------------
+       //
+       //      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.
+               // 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 
+        // also $result[0] holds entire string, 1 the first captured, 2 the 2nd etc.
+        //
+        if (preg_match('/^(\D*?)(\d+)(.*)/', $reference, $result) == 1) 
+        {
+                       list($all, $prefix, $number, $postfix) = $result;
+                       $dig_count = strlen($number); // How many digits? eg. 0003 = 4
+                       $fmt = '%0' . $dig_count . 'd'; // Make a format string - leading zeroes
+                       $val = intval($number + ($back ? ($number<1 ? 0 : -1) : 1));
+                       $nextval =  sprintf($fmt, $val); // Add one on, and put prefix back on
+
+                       return $prefix.$nextval.$postfix;
+        }
         else 
-               return $reference;
+            return $reference;
        }
-       
-       //------------------------------------
 }
 
 //----------------------------------------------------------------------------
-
-function is_new_reference($ref, $type)
+//
+//     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];
        
-       if ($db_ref != null) 
-       {
-               $sql = "SELECT $db_ref FROM $db_name WHERE $db_ref='$ref'";
-               if ($db_type != null)
-                       $sql .= " AND $db_type=$type";
-                        
-               $result = db_query($sql, "could not test for unique reference");
-               
-               return (db_num_rows($result) == 0);
-       }
+       $ref = db_escape(trim($ref));
+       $type = db_escape($type);
        
-       // it's a type that doesn't use references - shouldn't be calling here, but say yes anyways
-       return true;
+       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 
+                       LEFT JOIN ".TB_PREF."voided v ON 
+                               $db_name.$db_type=v.type AND $db_name.$db_trans=v.id
+                       WHERE $db_name.$db_ref=$ref AND ISNULL(v.id)
+                               AND $db_name.$db_type=$type";
+       } else {
+               $sql = "SELECT $db_ref FROM $db_name 
+                       LEFT JOIN ".TB_PREF."voided v ON 
+                               v.type=$type AND $db_name.$db_trans=v.id
+                       WHERE $db_ref=$ref AND ISNULL(v.id)";
+       }
+
+       $result = db_query($sql, "could not test for unique reference");
+
+       return (db_num_rows($result) == 0);
+
 }
 
+
 ?>
\ No newline at end of file