diff --git a/module/finc/src/finc/Controller/CustomTraits/GviRecordTrait.php b/module/finc/src/finc/Controller/CustomTraits/GviRecordTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..c09d8d5c65b3bce56d762ae5ac09c9ffa33187d6
--- /dev/null
+++ b/module/finc/src/finc/Controller/CustomTraits/GviRecordTrait.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * finc specific model for MARC records with a fullrecord in Solr.
+ *
+ * PHP version 7
+ *
+ * Copyright (C) Leipzig University Library 2023.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category VuFind
+ * @package  RecordDrivers
+ * @author   JP Kanter <kanter@ub.uni-leipzig.de>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:record_drivers Wiki
+ */
+namespace finc\Controller\CustomTraits;
+
+/**
+ * fid specific model for MARC records with a fullrecord in Solr.
+ *
+ * @category VuFind
+ * @package  Controller
+ * @author   JP Kanter <kanter@ub.uni-leipzig.de>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:record_drivers Wiki
+ */
+trait GviRecordTrait
+{
+    /**
+     * returns all ctrlnums from either the solr field or marc data
+     *
+     * @return array might be an empty array if nothing can be found
+     * @throws \File_MARC_Exception
+     */
+    public function getCtrlnum()//php_8//: array
+    {
+        $ctrls = [];
+        // trying to source ctrlnums from either direct solr fields or the corresponding marc set
+        if (isset($this->fields['ctrlnum'])) {
+            $ctrls = $this->fields['ctrlnum'];
+        } elseif ($field = $this->getMarcRecord()->getFields('35')) {
+            foreach ($field as $item) {
+                if ($subfield = $item->getSubfield('a')) {
+                    $ctrls[] = $subfield->getData();
+                }
+            }
+        }
+        return $ctrls;
+    }
+
+    /**
+     * Extracts a GVI-ID from the data we got, there might be none available or even more than one, in case of
+     * multiple instances, the most fitting one gets chosen
+     *
+     * @param string $isil ISIL of the Network the user is residing in, can be empty
+     *
+     * @return false|string complete GVI ID, eg. (DE-627)452235435
+     */
+    public function getGviId($isil="")//php_8//: false|string
+    {
+        if (empty($ctrls = $this->getCtrlnum())) { //abort misssion without ctrlnum
+            return false;
+        }
+
+        // extracts all possible GVI ids out of the ctrlnum field, it's nothing more than creating a dictionary
+        $ctrl_arr = [];
+        foreach ($ctrls as $row) {
+            if (preg_match('{(\(.+\))(.+)}', $row, $re)) {
+                $ctrl_arr[$re[1]] = $re[0]; # '(DE-602)' => "(DE-602)452235435"
+            }
+        }
+
+        // Special Case for 604 because those BV-Numbers seem to work a bit
+        foreach ($ctrl_arr as $value) {
+            if (preg_match('{(\(DE-604\)BV)(\d+)}', $value, $re)) {
+                if ($isil == "bvb") {
+                    return $re[0];
+                }
+            }
+            if (preg_match('{(\(DE-605\)HT)(\d+)}', $value, $re)) {
+                if ($isil == "hbz") {
+                    return $re[0];
+                }
+            }
+        }
+        if (isset($ctrl_arr['(DE-627)'])) {
+            return $ctrl_arr['(DE-627)'];
+        }
+
+        return false; // default false in case we get here
+    }
+}