diff --git a/ajax/process/getEntities.php b/ajax/process/getEntities.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf9c8825b540d1f98573ec3dacd49a76bed6404a
--- /dev/null
+++ b/ajax/process/getEntities.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * This file contains package_quiqqer_erp_ajax_dashboard_process_getEntities
+ */
+
+use QUI\ERP\Process;
+use QUI\ERP\Processes;
+
+QUI::$Ajax->registerFunction(
+    'package_quiqqer_erp_ajax_process_getEntities',
+    function ($globalProcessId, $entityHash) {
+        if (!empty($entityHash)) {
+            $Processes = new Processes();
+            $Entity = $Processes->getEntity($entityHash);
+            $Process = new Process($Entity->getGlobalProcessId());
+        } else {
+            $Process = new Process($globalProcessId);
+        }
+
+        return array_map(function ($Entity) {
+            return $Entity->toArray();
+        }, $Process->getEntities());
+    },
+    ['globalProcessId', 'entityHash'],
+    ['Permission::checkAdminUser']
+);
diff --git a/bin/backend/controls/process/ProcessGrid.js b/bin/backend/controls/process/ProcessGrid.js
new file mode 100644
index 0000000000000000000000000000000000000000..a2d54285dca64ffd17e98c496fbf244176a223b0
--- /dev/null
+++ b/bin/backend/controls/process/ProcessGrid.js
@@ -0,0 +1,169 @@
+/**
+ * @module package/quiqqer/erp/bin/backend/controls/process/ProcessGrid
+ */
+define('package/quiqqer/erp/bin/backend/controls/process/ProcessGrid', [
+
+    'qui/QUI',
+    'qui/controls/Control',
+    'qui/controls/buttons/Button',
+    'qui/controls/loader/Loader',
+    'controls/grid/Grid',
+    'Locale',
+    'Ajax'
+
+], function(QUI, QUIControl, QUIButton, QUILoader, Grid, QUILocale, QUIAjax) {
+    'use strict';
+
+    const lg = 'quiqqer/erp';
+
+    return new Class({
+
+        Extends: QUIControl,
+        Type: 'package/quiqqer/erp/bin/backend/controls/process/ProcessGrid',
+
+        Binds: [
+            '$onInject',
+            'refresh'
+        ],
+
+        options: {
+            globalProcessId: false,
+            entityHash: false
+        },
+
+        initialize: function(options) {
+            this.parent(options);
+
+            this.Loader = new QUILoader();
+            this.$Grid = null;
+
+            this.addEvents({
+                onInject: this.$onInject
+            });
+        },
+
+        create: function() {
+            this.$Elm = this.parent();
+            this.Loader.inject(this.$Elm);
+
+            const Container = new Element('div').inject(this.$Elm);
+
+            this.$Grid = new Grid(Container, {
+                height: 300,
+                columnModel: [
+                    {
+                        header: QUILocale.get(lg, 'erp.process.type'),
+                        dataIndex: 'type',
+                        dataType: 'QUI',
+                        width: 60
+                    }, {
+                        header: QUILocale.get(lg, 'erp.process.state'),
+                        dataIndex: 'status',
+                        dataType: 'node',
+                        width: 100
+                    }, {
+                        header: QUILocale.get(lg, 'erp.process.prefixedNumber'),
+                        dataIndex: 'prefixedNumber',
+                        dataType: 'string',
+                        width: 180
+                    }, {
+                        header: QUILocale.get(lg, 'erp.process.uuid'),
+                        dataIndex: 'uuid',
+                        dataType: 'string',
+                        width: 240
+                    }
+                ],
+                pagination: false
+            });
+
+            return this.$Elm;
+        },
+
+        $onInject: function() {
+            this.refresh();
+        },
+
+        refresh: function() {
+            this.Loader.show();
+
+            QUIAjax.get('package_quiqqer_erp_ajax_process_getEntities', (result) => {
+                const data = [];
+                console.log(result);
+
+                result.forEach((entry) => {
+                    const Type = new QUIButton({
+                        events: {
+                            click: this.$click
+                        },
+                        entityType: entry.entityType,
+                        uuid: entry.uuid,
+                        styles: {
+                            width: 40
+                        }
+                    });
+
+                    switch (entry.entityType) {
+                        case 'QUI\\ERP\\Order\\Order':
+                            Type.setAttribute('icon', 'fa fa-shopping-basket');
+                            Type.setAttribute('title', QUILocale.get(lg, 'processGrid.order.open'));
+                            break;
+
+                        case 'QUI\\ERP\\Invoice\\Invoice':
+                        case 'QUI\\ERP\\Accounting\\Invoice\\InvoiceTemporary':
+                            Type.setAttribute('icon', 'fa fa-file-text-o');
+                            Type.setAttribute('title', QUILocale.get(lg, 'processGrid.invoice.open'));
+                            break;
+                    }
+
+                    data.push({
+                        type: Type,
+                        status: entry.status,
+                        prefixedNumber: entry.prefixedNumber,
+                        uuid: entry.uuid
+                    });
+                });
+
+                this.$Grid.setData({
+                    data: data
+                });
+
+                this.Loader.hide();
+            }, {
+                'package': 'quiqqer/erp',
+                globalProcessId: this.getAttribute('globalProcessId'),
+                entityHash: this.getAttribute('entityHash')
+            });
+        },
+
+        $click: function(Btn) {
+            let panel;
+            const uuid = Btn.getAttribute('uuid');
+
+            switch (Btn.getAttribute('entityType')) {
+                case 'QUI\\ERP\\Order\\Order':
+                    panel = 'package/quiqqer/order/bin/backend/controls/panels/Order';
+                    break;
+
+                case 'QUI\\ERP\\Invoice\\Invoice':
+                    panel = 'package/quiqqer/invoice/bin/backend/controls/panels/Invoice';
+                    break;
+
+                case 'QUI\\ERP\\Accounting\\Invoice\\InvoiceTemporary':
+                    panel = 'package/quiqqer/invoice/bin/backend/controls/panels/TemporaryInvoice';
+                    break;
+
+                default:
+                    console.error('missing', uuid, Btn.getAttribute('entityType'));
+                    return;
+            }
+
+            require(['utils/Panels', panel], (PanelUtils, Panel) => {
+                PanelUtils.openPanelInTasks(
+                    new Panel({
+                        'uuid': uuid
+                    })
+                );
+            });
+        }
+    });
+});
diff --git a/locale.xml b/locale.xml
index 2d5fbd4aaa0f6a41c43d297101fc721b51624826..3923c6ededba0a407138b080916473c682a49888 100644
--- a/locale.xml
+++ b/locale.xml
@@ -272,6 +272,35 @@
             <de><![CDATA[Bankverbindungen verwalten]]></de>
             <en><![CDATA[Manage bank accounts]]></en>
         </locale>
+
+        <locale name="processGrid.order.open">
+            <de><![CDATA[Bestellung öffnen]]></de>
+            <en><![CDATA[Open order]]></en>
+        </locale>
+        <locale name="processGrid.invoice.open">
+            <de><![CDATA[Rechnung öffnen]]></de>
+            <en><![CDATA[Open invoice]]></en>
+        </locale>
+        <locale name="erp.process.type">
+            <de><![CDATA[Typ]]></de>
+            <en><![CDATA[Type]]></en>
+        </locale>
+        <locale name="erp.process.type">
+            <de><![CDATA[Typ]]></de>
+            <en><![CDATA[Type]]></en>
+        </locale>
+        <locale name="erp.process.state">
+            <de><![CDATA[Status]]></de>
+            <en><![CDATA[State]]></en>
+        </locale>
+        <locale name="erp.process.prefixedNumber">
+            <de><![CDATA[Entitäts-Nr]]></de>
+            <en><![CDATA[Entity number]]></en>
+        </locale>
+        <locale name="erp.process.uuid">
+            <de><![CDATA[Entitäts UUID]]></de>
+            <en><![CDATA[Entity uuid]]></en>
+        </locale>
     </groups>
 
     <groups name="quiqqer/erp" datatype="php">
diff --git a/src/QUI/ERP/Accounting/ArticleList.php b/src/QUI/ERP/Accounting/ArticleList.php
index 6e955942638889b62bf180316f1c3d11a03fe597..598b871fce346575143c059df32414828a944970 100644
--- a/src/QUI/ERP/Accounting/ArticleList.php
+++ b/src/QUI/ERP/Accounting/ArticleList.php
@@ -40,7 +40,7 @@ class ArticleList extends ArticleListUnique implements IteratorAggregate
     /**
      * @var QUI\Interfaces\Users\User
      */
-    protected $User = null;
+    protected QUI\Users\User|QUI\Interfaces\Users\User|null $User = null;
 
     /**
      * @var ?QUI\ERP\Order\AbstractOrder
diff --git a/src/QUI/ERP/Accounting/ArticleListUnique.php b/src/QUI/ERP/Accounting/ArticleListUnique.php
index 66acc16bcda2e04b7f5c46b35ec83138e49c1b23..13946880b8bcd2b72dd602abdcecb2f08a6db95c 100644
--- a/src/QUI/ERP/Accounting/ArticleListUnique.php
+++ b/src/QUI/ERP/Accounting/ArticleListUnique.php
@@ -39,12 +39,12 @@ class ArticleListUnique implements IteratorAggregate
     /**
      * @var array
      */
-    protected $calculations = [];
+    protected mixed $calculations = [];
 
     /**
      * @var bool|mixed
      */
-    protected $showHeader;
+    protected mixed $showHeader;
 
     /**
      * PriceFactor List
@@ -59,9 +59,9 @@ class ArticleListUnique implements IteratorAggregate
     protected ?QUI\Locale $Locale = null;
 
     /**
-     * @var QUI\Interfaces\Users\User
+     * @var ?QUI\Interfaces\Users\User
      */
-    protected $User = null;
+    protected ?QUI\Interfaces\Users\User $User = null;
 
     /**
      * @var bool
@@ -82,10 +82,10 @@ class ArticleListUnique implements IteratorAggregate
      * ArticleList constructor.
      *
      * @param array $attributes
-     * @param null|QUI\Interfaces\Users\User|QUI\Users\User $User
-     * @throws QUI\ERP\Exception
+     * @param ?QUI\Interfaces\Users\User $User
+     * @throws QUI\ERP\Exception|QUI\Exception
      */
-    public function __construct(array $attributes = [], $User = null)
+    public function __construct(array $attributes = [], QUI\Interfaces\Users\User $User = null)
     {
         $this->Locale = QUI::getLocale();
 
@@ -257,7 +257,7 @@ public function calc($Calc = null): ArticleListUnique
      *
      * @param QUI\Locale $Locale
      */
-    public function setLocale(QUI\Locale $Locale)
+    public function setLocale(QUI\Locale $Locale): void
     {
         $this->Locale = $Locale;
     }
@@ -265,12 +265,12 @@ public function setLocale(QUI\Locale $Locale)
     /**
      * Creates a list from a stored representation
      *
-     * @param string|array $data
+     * @param array|string $data
      * @return ArticleListUnique
      *
      * @throws QUI\Exception
      */
-    public static function unserialize($data): ArticleListUnique
+    public static function unserialize(array|string $data): ArticleListUnique
     {
         if (is_string($data)) {
             $data = json_decode($data, true);
@@ -355,7 +355,7 @@ public function toArray(): array
     /**
      * Display of the header = true
      */
-    public function displayHeader()
+    public function displayHeader(): void
     {
         $this->showHeader = true;
     }
@@ -363,7 +363,7 @@ public function displayHeader()
     /**
      * Display of the header = false
      */
-    public function hideHeader()
+    public function hideHeader(): void
     {
         $this->showHeader = false;
     }
@@ -371,7 +371,7 @@ public function hideHeader()
     /**
      * @param QUI\ERP\Currency\Currency $Currency
      */
-    public function setExchangeCurrency(QUI\ERP\Currency\Currency $Currency)
+    public function setExchangeCurrency(QUI\ERP\Currency\Currency $Currency): void
     {
         $this->ExchangeCurrency = $Currency;
     }
@@ -379,7 +379,7 @@ public function setExchangeCurrency(QUI\ERP\Currency\Currency $Currency)
     /**
      * @param float $rate
      */
-    public function setExchangeRate(float $rate)
+    public function setExchangeRate(float $rate): void
     {
         $this->exchangeRate = $rate;
     }
@@ -387,12 +387,12 @@ public function setExchangeRate(float $rate)
     /**
      * Return the Article List as HTML, without CSS
      *
-     * @param string|bool $template - custom template
+     * @param bool|string $template - custom template
      * @return string
      *
      * @throws QUI\Exception
      */
-    public function toHTML($template = false): string
+    public function toHTML(bool|string $template = false): string
     {
         $Engine = QUI::getTemplateManager()->getEngine();
         $vatArray = [];
@@ -602,7 +602,7 @@ public function getPriceFactors(): ErpFactorList
      *
      * @return ArrayIterator|Traversable
      */
-    public function getIterator()
+    public function getIterator(): Traversable|ArrayIterator
     {
         return new ArrayIterator($this->articles);
     }
diff --git a/src/QUI/ERP/ErpEntityInterface.php b/src/QUI/ERP/ErpEntityInterface.php
index 275ec8199885a41b750aee7bf61d72435828050d..b8d71b2196c754a114092c25d65367da6b8b5432 100644
--- a/src/QUI/ERP/ErpEntityInterface.php
+++ b/src/QUI/ERP/ErpEntityInterface.php
@@ -36,6 +36,13 @@ public function getId(): int;
      */
     public function getUUID(): string;
 
+    /**
+     * Return the process of the entity (global process id))
+     *
+     * @return string
+     */
+    public function getGlobalProcessId(): string;
+
     /**
      * Return the entity number
      * returns the number that this entity has. a number is, for example, an invoice number or booking number. this number is not the id.
@@ -85,4 +92,30 @@ public function getDeliveryAddress(): ?ErpAddress;
      * @param array|User $User
      */
     public function setCustomer(array|QUI\Interfaces\Users\User $User);
+
+    /**
+     * Returns the erp entity as an array
+     *
+     * @return array
+     */
+    public function toArray(): array;
+
+    /**
+     * Cancel the entity
+     * (Reversal, Storno, Cancel)
+     *
+     * @param string $reason
+     * @param User|null $PermissionUser
+     * @return ?ErpEntityInterface
+     */
+    public function reversal(
+        string $reason = '',
+        QUI\Interfaces\Users\User $PermissionUser = null
+    ): ?ErpEntityInterface;
+
+    public function addCustomerFile(string $fileHash, array $options = []): void;
+
+    public function clearCustomerFiles(): void;
+
+    public function getCustomerFiles(): array;
 }
diff --git a/src/QUI/ERP/ErpTransactionsInterface.php b/src/QUI/ERP/ErpTransactionsInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..71c9fb185c3f7b8628663f7479d670b2f891a7cd
--- /dev/null
+++ b/src/QUI/ERP/ErpTransactionsInterface.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace QUI\ERP;
+
+use QUI;
+use QUI\ERP\Accounting\ArticleList;
+use QUI\ERP\Accounting\ArticleListUnique;
+use QUI\ERP\Accounting\Calculations;
+use QUI\ERP\Accounting\Payments\Transactions\Transaction;
+use QUI\ERP\Address as ErpAddress;
+use QUI\ERP\User as ErpUser;
+use QUI\Interfaces\Users\User;
+
+interface ErpTransactionsInterface
+{
+    public function linkTransaction(Transaction $Transaction): void;
+
+    public function addTransaction(Transaction $Transaction): void;
+}
diff --git a/src/QUI/ERP/EventHandler.php b/src/QUI/ERP/EventHandler.php
index 1c226462d2629b5f6212a24a5958e76e5686d371..72b9f095fa4b21bfabe691a8e3b8831d498f6e55 100644
--- a/src/QUI/ERP/EventHandler.php
+++ b/src/QUI/ERP/EventHandler.php
@@ -10,7 +10,7 @@
 use QUI\ERP\BankAccounts\Handler as BankAccounts;
 use QUI\ERP\Products\Handler\Fields as ProductFields;
 use QUI\Package\Package;
-use Quiqqer\Engine\Collector;
+use QUI\Smarty\Collector;
 
 use function array_flip;
 use function class_exists;
@@ -30,7 +30,7 @@ class EventHandler
     /**
      * event : on admin load footer
      */
-    public static function onAdminLoadFooter()
+    public static function onAdminLoadFooter(): void
     {
         echo '<script src="' . URL_OPT_DIR . 'quiqqer/erp/bin/load.js"></script>';
     }
@@ -38,7 +38,7 @@ public static function onAdminLoadFooter()
     /**
      * @param QUI\Template $Template
      */
-    public static function onTemplateGetHeader(QUI\Template $Template)
+    public static function onTemplateGetHeader(QUI\Template $Template): void
     {
         try {
             $Package = QUI::getPackage('quiqqer/erp');
@@ -49,11 +49,11 @@ public static function onTemplateGetHeader(QUI\Template $Template)
             }
 
             $areas = explode(',', $areas);
-        } catch (\QUI\Exception $exception) {
+        } catch (\QUI\Exception) {
             return;
         }
 
-        if (!empty($areas)) {
+        if (count($areas)) {
             $Template->extendHeaderWithJavaScriptFile(
                 URL_OPT_DIR . 'quiqqer/erp/bin/frontend.js'
             );
@@ -66,7 +66,7 @@ public static function onTemplateGetHeader(QUI\Template $Template)
      * @param Package $Package
      * @throws QUI\Exception
      */
-    public static function onPackageSetup(Package $Package)
+    public static function onPackageSetup(Package $Package): void
     {
         if ($Package->getName() !== 'quiqqer/erp') {
             return;
@@ -81,7 +81,7 @@ public static function onPackageSetup(Package $Package)
      *
      * @return void
      */
-    public static function createDefaultManufacturerGroup()
+    public static function createDefaultManufacturerGroup(): void
     {
         try {
             $Conf = QUI::getPackage('quiqqer/erp')->getConfig();
@@ -132,7 +132,7 @@ public static function createDefaultManufacturerGroup()
      * @return void
      * @throws QUI\Exception
      */
-    public static function patchBankAccount()
+    public static function patchBankAccount(): void
     {
         $Conf = QUI::getPackage('quiqqer/erp')->getConfig();
         $bankAccountPatched = $Conf->getValue('bankAccounts', 'isPatched');
@@ -191,7 +191,7 @@ public static function patchBankAccount()
      * @param Package $Package
      * @param array $params
      */
-    public static function onPackageConfigSave(QUI\Package\Package $Package, array $params)
+    public static function onPackageConfigSave(QUI\Package\Package $Package, array $params): void
     {
         if ($Package->getName() !== 'quiqqer/erp') {
             return;
@@ -233,7 +233,7 @@ public static function onPackageConfigSave(QUI\Package\Package $Package, array $
      * @todo prüfung auch für steuernummer
      *
      */
-    public static function onUserSave(QUI\Interfaces\Users\User $User)
+    public static function onUserSave(QUI\Interfaces\Users\User $User): void
     {
         if (!QUI::getUsers()->isUser($User)) {
             return;
@@ -245,7 +245,7 @@ public static function onUserSave(QUI\Interfaces\Users\User $User)
             $validate = $Package->getConfig()->getValue('shop', 'validateVatId');
             $vatId = $User->getAttribute('quiqqer.erp.euVatId');
 
-            if ($validate && $vatId && !empty($vatId)) {
+            if ($validate && !empty($vatId)) {
                 try {
                     $vatId = QUI\ERP\Tax\Utils::validateVatId($vatId);
                 } catch (QUI\ERP\Tax\Exception $Exception) {
@@ -284,7 +284,7 @@ public static function onUserSave(QUI\Interfaces\Users\User $User)
      * @param QUI\Users\User $User
      * @throws QUI\Exception
      */
-    public static function onUserSaveBegin(QUI\Users\User $User)
+    public static function onUserSaveBegin(QUI\Users\User $User): void
     {
         if (!QUI::getUsers()->isUser($User)) {
             return;
@@ -344,7 +344,7 @@ class_exists('QUI\ERP\Tax\Utils')
      * @param QUI\Users\Address $Address
      * @param QUI\Users\User $User
      */
-    public static function onUserAddressSave(QUI\Users\Address $Address, QUI\Users\User $User)
+    public static function onUserAddressSave(QUI\Users\Address $Address, QUI\Users\User $User): void
     {
         if (!QUI::getUsers()->isUser($User)) {
             return;
@@ -388,11 +388,14 @@ class_exists('QUI\ERP\Tax\Utils')
 
     /**
      * @param Collector $Collector
-     * @param QUI\Users\User $User
+     * @param QUI\Interfaces\Users\User $User
      * @param QUI\Users\Address $Address
      */
-    public static function onFrontendUserCustomerBegin(Collector $Collector, $User, $Address)
-    {
+    public static function onFrontendUserCustomerBegin(
+        Collector $Collector,
+        QUI\Interfaces\Users\User $User,
+        QUI\Users\Address $Address
+    ): void {
         if (!QUI::getUsers()->isUser($User)) {
             return;
         }
@@ -440,11 +443,14 @@ public static function onFrontendUserCustomerBegin(Collector $Collector, $User,
 
     /**
      * @param Collector $Collector
-     * @param QUI\Users\User $User
+     * @param QUI\Interfaces\Users\User $User
      * @param QUI\Users\Address $Address
      */
-    public static function onFrontendUserDataMiddle(Collector $Collector, $User, $Address)
-    {
+    public static function onFrontendUserDataMiddle(
+        Collector $Collector,
+        QUI\Interfaces\Users\User $User,
+        QUI\Users\Address $Address
+    ): void {
         if (!QUI::getUsers()->isUser($User)) {
             return;
         }
@@ -478,9 +484,9 @@ public static function onFrontendUserDataMiddle(Collector $Collector, $User, $Ad
 
     /**
      * @param Collector $Collector
-     * @param QUI\Users\User $User
+     * @param QUI\Interfaces\Users\User $User
      */
-    public static function onFrontendUserAddressCreateBegin(Collector $Collector, $User)
+    public static function onFrontendUserAddressCreateBegin(Collector $Collector, QUI\Interfaces\Users\User $User): void
     {
         if (!QUI::getUsers()->isUser($User)) {
             return;
@@ -505,7 +511,7 @@ public static function onFrontendUserAddressCreateBegin(Collector $Collector, $U
             }
 
             $Engine->assign('settings', QUI\FrontendUsers\Controls\Address\Address::checkSettingsArray($settings));
-        } catch (QUI\Exception $Exception) {
+        } catch (QUI\Exception) {
             $Engine->assign('settings', QUI\FrontendUsers\Controls\Address\Address::checkSettingsArray([]));
         }
 
@@ -530,9 +536,9 @@ public static function onFrontendUserAddressCreateBegin(Collector $Collector, $U
 
     /**
      * @param Collector $Collector
-     * @param QUI\Users\User $User
+     * @param QUI\Interfaces\Users\User $User
      */
-    public static function onFrontendUserAddressCreateEnd(Collector $Collector, $User)
+    public static function onFrontendUserAddressCreateEnd(Collector $Collector, QUI\Interfaces\Users\User $User): void
     {
         if (!QUI::getUsers()->isUser($User)) {
             return;
@@ -557,7 +563,7 @@ public static function onFrontendUserAddressCreateEnd(Collector $Collector, $Use
             }
 
             $Engine->assign('settings', QUI\FrontendUsers\Controls\Address\Address::checkSettingsArray($settings));
-        } catch (QUI\Exception $Exception) {
+        } catch (QUI\Exception) {
             $Engine->assign('settings', QUI\FrontendUsers\Controls\Address\Address::checkSettingsArray([]));
         }
 
@@ -582,11 +588,14 @@ public static function onFrontendUserAddressCreateEnd(Collector $Collector, $Use
 
     /**
      * @param Collector $Collector
-     * @param QUI\Users\User $User
+     * @param QUI\Interfaces\Users\User $User
      * @param QUI\Users\Address $Address
      */
-    public static function onFrontendUserAddressEditBegin(Collector $Collector, $User, $Address)
-    {
+    public static function onFrontendUserAddressEditBegin(
+        Collector $Collector,
+        QUI\Interfaces\Users\User $User,
+        QUI\Users\Address $Address
+    ): void {
         if (!QUI::getUsers()->isUser($User)) {
             return;
         }
@@ -610,7 +619,7 @@ public static function onFrontendUserAddressEditBegin(Collector $Collector, $Use
             }
 
             $Engine->assign('settings', QUI\FrontendUsers\Controls\Address\Address::checkSettingsArray($settings));
-        } catch (QUI\Exception $Exception) {
+        } catch (QUI\Exception) {
             $Engine->assign('settings', QUI\FrontendUsers\Controls\Address\Address::checkSettingsArray([]));
         }
 
@@ -650,11 +659,14 @@ public static function onFrontendUserAddressEditBegin(Collector $Collector, $Use
 
     /**
      * @param Collector $Collector
-     * @param $User
-     * @param $Address
+     * @param QUI\Interfaces\Users\User $User
+     * @param QUI\Users\Address $Address
      */
-    public static function onFrontendUserAddressEditEnd(Collector $Collector, $User, $Address)
-    {
+    public static function onFrontendUserAddressEditEnd(
+        Collector $Collector,
+        QUI\Interfaces\Users\User $User,
+        QUI\Users\Address $Address
+    ): void {
         if (!QUI::getUsers()->isUser($User)) {
             return;
         }
@@ -678,7 +690,7 @@ public static function onFrontendUserAddressEditEnd(Collector $Collector, $User,
             }
 
             $Engine->assign('settings', QUI\FrontendUsers\Controls\Address\Address::checkSettingsArray($settings));
-        } catch (QUI\Exception $Exception) {
+        } catch (QUI\Exception) {
             $Engine->assign('settings', QUI\FrontendUsers\Controls\Address\Address::checkSettingsArray([]));
         }
 
diff --git a/src/QUI/ERP/Process.php b/src/QUI/ERP/Process.php
index 791361ba63f90d8a2f7b609227e270ca707f9b15..175f4be28b5c94915c6e86cdf6ace2c471077d5b 100644
--- a/src/QUI/ERP/Process.php
+++ b/src/QUI/ERP/Process.php
@@ -7,11 +7,9 @@
 namespace QUI\ERP;
 
 use QUI;
-use QUI\ERP\Accounting\Offers\Handler as OfferHandler;
-use QUI\ERP\Booking\Table as BookingTable;
-use QUI\ERP\Purchasing\Processes\Handler as PurchasingHandler;
-use QUI\ERP\SalesOrders\Handler as SalesOrdersHandler;
 
+use function array_merge;
+use function class_exists;
 use function count;
 use function strtotime;
 
@@ -59,6 +57,25 @@ protected function table(): string
         return QUI::getDBTableName('process');
     }
 
+    /**
+     * Return all entities which are connected to this process
+     *
+     * @return ErpEntityInterface[]
+     */
+    public function getEntities(): array
+    {
+        $entities = array_merge(
+            $this->getInvoices(),
+            $this->getOrders(),
+            $this->getOffers(),
+            $this->getBookings(),
+            $this->getPurchasing(),
+            $this->getSalesOrders()
+        );
+
+        return array_filter($entities);
+    }
+
     //region messages
 
     /**
@@ -165,13 +182,13 @@ protected function parseInvoices(Comments $History): void
         foreach ($invoices as $Invoice) {
             $History->addComment(
                 QUI::getLocale()->get('quiqqer/erp', 'process.history.invoice.created', [
-                    'hash' => $Invoice->getHash()
+                    'hash' => $Invoice->getUUID()
                 ]),
                 strtotime($Invoice->getAttribute('date')),
                 'quiqqer/invoice',
                 'fa fa-file-text-o',
                 false,
-                $Invoice->getHash()
+                $Invoice->getUUID()
             );
 
             $history = $Invoice->getHistory()->toArray();
@@ -191,7 +208,7 @@ protected function parseInvoices(Comments $History): void
                     $entry['source'],
                     $entry['sourceIcon'],
                     $entry['id'],
-                    $Invoice->getHash()
+                    $Invoice->getUUID()
                 );
             }
         }
@@ -244,7 +261,7 @@ public function getInvoices(): array
 
         try {
             return QUI\ERP\Accounting\Invoice\Handler::getInstance()->getInvoicesByGlobalProcessId($this->processId);
-        } catch (\QUI\Exception $Exception) {
+        } catch (\QUI\Exception) {
             return [];
         }
     }
@@ -262,7 +279,7 @@ protected function parseOrders(Comments $History): void
             $history = $Order->getHistory()->toArray();
             $hasCreateMessage = false;
             $createMessage = QUI::getLocale()->get('quiqqer/erp', 'process.history.order.created', [
-                'hash' => $Order->getHash()
+                'hash' => $Order->getUUID()
             ]);
 
             foreach ($history as $entry) {
@@ -296,7 +313,7 @@ protected function parseOrders(Comments $History): void
                     $entry['source'],
                     $entry['sourceIcon'],
                     $entry['id'],
-                    $Order->getHash()
+                    $Order->getUUID()
                 );
             }
         }
@@ -341,7 +358,7 @@ public function getOrder(): Order\OrderInProcess|Order\Order|null
     /**
      * Return all orders from the process
      *
-     * @return array|Order\Order|Order\Order[]|Order\OrderInProcess[]
+     * @return array
      */
     public function getOrders(): array
     {
@@ -351,7 +368,7 @@ public function getOrders(): array
 
         try {
             return QUI\ERP\Order\Handler::getInstance()->getOrdersByGlobalProcessId($this->processId);
-        } catch (QUI\Exception $Exception) {
+        } catch (QUI\Exception) {
             return [];
         }
     }
@@ -415,7 +432,7 @@ public function getOffers(): array
         try {
             $offers = QUI::getDatabase()->fetch([
                 'select' => 'id,hash,global_process_id,date',
-                'from' => OfferHandler::getInstance()->offersTable(),
+                'from' => QUI\ERP\Accounting\Offers\Handler::getInstance()->offersTable(),
                 'where_or' => [
                     'global_process_id' => $this->processId,
                     'hash' => $this->processId
@@ -426,7 +443,7 @@ public function getOffers(): array
         }
 
         $result = [];
-        $Offers = OfferHandler::getInstance();
+        $Offers = QUI\ERP\Accounting\Offers\Handler::getInstance();
 
         foreach ($offers as $offer) {
             try {
@@ -490,10 +507,18 @@ public function getBookings(): array
             return [];
         }
 
+        if (!class_exists('QUI\ERP\Booking\Repository\BookingRepository')) {
+            return [];
+        }
+
+        if (!class_exists('QUI\ERP\Booking\Table')) {
+            return [];
+        }
+
         try {
             $bookings = QUI::getDatabase()->fetch([
                 'select' => 'uuid,globalProcessId,createDate',
-                'from' => BookingTable::BOOKINGS->tableName(),
+                'from' => QUI\ERP\Booking\Table::BOOKINGS->tableName(),
                 'where_or' => [
                     'globalProcessId' => $this->processId,
                     'uuid' => $this->processId
@@ -560,7 +585,7 @@ protected function parsePurchasing(Comments $History): void
     }
 
     /**
-     * @return QUI\ERP\Purchasing\Processes\PurchasingProcess[]
+     * @return array
      */
     public function getPurchasing(): array
     {
@@ -568,10 +593,18 @@ public function getPurchasing(): array
             return [];
         }
 
+        if (!class_exists('QUI\ERP\Purchasing\Processes\PurchasingProcess')) {
+            return [];
+        }
+
+        if (!class_exists('QUI\ERP\Purchasing\Processes\Handler')) {
+            return [];
+        }
+
         try {
             $purchasing = QUI::getDatabase()->fetch([
                 'select' => 'id,hash,global_process_id,date',
-                'from' => PurchasingHandler::getTablePurchasingProcesses(),
+                'from' => QUI\ERP\Purchasing\Processes\Handler::getTablePurchasingProcesses(),
                 'where_or' => [
                     'global_process_id' => $this->processId,
                     'hash' => $this->processId
@@ -585,7 +618,7 @@ public function getPurchasing(): array
 
         foreach ($purchasing as $process) {
             try {
-                $result[] = PurchasingHandler::getPurchasingProcess($process['id']);
+                $result[] = QUI\ERP\Purchasing\Processes\Handler::getPurchasingProcess($process['id']);
             } catch (\Exception) {
             }
         }
@@ -637,7 +670,7 @@ protected function parseSalesOrders(Comments $History): void
     }
 
     /**
-     * @return QUI\ERP\Purchasing\Processes\PurchasingProcess[]
+     * @return array
      */
     public function getSalesOrders(): array
     {
@@ -648,7 +681,7 @@ public function getSalesOrders(): array
         try {
             $salesOrders = QUI::getDatabase()->fetch([
                 'select' => 'id,hash,global_process_id,date',
-                'from' => SalesOrdersHandler::getTableSalesOrders(),
+                'from' => QUI\ERP\SalesOrders\Handler::getTableSalesOrders(),
                 'where_or' => [
                     'global_process_id' => $this->processId,
                     'hash' => $this->processId
@@ -662,7 +695,7 @@ public function getSalesOrders(): array
 
         foreach ($salesOrders as $salesOrder) {
             try {
-                $result[] = SalesOrdersHandler::getSalesOrder($salesOrder['id']);
+                $result[] = QUI\ERP\SalesOrders\Handler::getSalesOrder($salesOrder['id']);
             } catch (\Exception) {
             }
         }
diff --git a/src/QUI/ERP/Processes.php b/src/QUI/ERP/Processes.php
index 0047273ac2171fccb64daec9958b0490aadc856f..6b2bc038b362f6387d39caa65b79abd966192131 100644
--- a/src/QUI/ERP/Processes.php
+++ b/src/QUI/ERP/Processes.php
@@ -14,6 +14,7 @@
 use QUI\ERP\Order\Handler as OrderHandler;
 use QUI\ERP\Purchasing\Processes\Handler as PurchasingHandler;
 use QUI\ERP\SalesOrders\Handler as SalesOrdersHandler;
+use QUI\Exception;
 
 /**
  *
@@ -33,6 +34,67 @@ class Processes
 {
     protected array $list = [];
 
+    /**
+     * @throws Exception
+     */
+    public function getEntity($entityHash): ErpEntityInterface
+    {
+        //'quiqqer/booking',
+        try {
+        } catch (\Exception) {
+        }
+
+        //'quiqqer/contracts',
+        try {
+        } catch (\Exception) {
+        }
+
+        //'quiqqer/delivery-notes',
+        try {
+        } catch (\Exception) {
+        }
+
+        //'quiqqer/invoice',
+        try {
+            return QUI\ERP\Accounting\Invoice\Handler::getInstance()->getInvoiceByHash($entityHash);
+        } catch (\Exception) {
+        }
+
+        //'quiqqer/offers',
+        try {
+            return QUI\ERP\Accounting\Offers\Handler::getInstance()->getOfferByHash($entityHash);
+        } catch (\Exception) {
+        }
+
+        //'quiqqer/order',
+        try {
+            return QUI\ERP\Order\Handler::getInstance()->getOrderByHash($entityHash);
+        } catch (\Exception) {
+        }
+
+        //'quiqqer/purchasing',
+        try {
+        } catch (\Exception) {
+        }
+
+        //'quiqqer/salesorders'
+        try {
+            return QUI\ERP\SalesOrders\Handler::getSalesOrderByHash($entityHash);
+        } catch (\Exception) {
+        }
+
+        throw new Exception(
+            [
+                'quiqqer/erp',
+                'exception.entity.not.found',
+                [
+                    'hash' => $entityHash
+                ]
+            ],
+            404
+        );
+    }
+
     /**
      * @return array
      */