diff --git a/bin/backend/utils/Dialogs.js b/bin/backend/utils/Dialogs.js
index 17e9b43aa600700ab66f3b61db2fc1ec75e53d88..27189b115b39a29c4576d1032590a6ef3421d19f 100644
--- a/bin/backend/utils/Dialogs.js
+++ b/bin/backend/utils/Dialogs.js
@@ -14,10 +14,10 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
 
     'css!package/quiqqer/invoice/bin/backend/utils/Dialogs.css'
 
-], function (QUI, QUILocale, Invoices, QUIConfirm) {
-    "use strict";
+], function(QUI, QUILocale, Invoices, QUIConfirm) {
+    'use strict';
 
-    var lg = 'quiqqer/invoice';
+    const lg = 'quiqqer/invoice';
 
     return {
 
@@ -28,18 +28,18 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
          * @param {String} [entityType]
          * @return {Promise}
          */
-        openPrintDialog: function (invoiceId, entityType) {
+        openPrintDialog: function(invoiceId, entityType) {
             entityType = entityType || 'Invoice';
 
-            return Invoices.getInvoiceHistory(invoiceId).then(function (comments) {
-                return new Promise(function (resolve) {
+            return Invoices.getInvoiceHistory(invoiceId).then(function(comments) {
+                return new Promise(function(resolve) {
                     require([
                         'package/quiqqer/erp/bin/backend/controls/OutputDialog'
-                    ], function (OutputDialog) {
+                    ], function(OutputDialog) {
                         new OutputDialog({
-                            entityId  : invoiceId,
+                            entityId: invoiceId,
                             entityType: entityType,
-                            comments  : comments.length ? comments : false
+                            comments: comments.length ? comments : false
                         }).open();
 
                         resolve();
@@ -54,72 +54,83 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
          * @param {String} invoiceId - Invoice ID or Hash
          * @return {Promise}
          */
-        openStornoDialog: function (invoiceId) {
-            return Invoices.get(invoiceId).then(function (result) {
-                var id = result.id_prefix + result.id;
+        openStornoDialog: function(invoiceId) {
+            return Invoices.get(invoiceId).then(function(result) {
+                const id = result.id_prefix + result.id;
 
-                return new Promise(function (resolve, reject) {
+                return new Promise(function(resolve, reject) {
                     new QUIConfirm({
-                        icon       : 'fa fa-ban',
-                        texticon   : 'fa fa-ban',
-                        title      : QUILocale.get(lg, 'dialog.invoice.reversal.title', {
+                        icon: 'fa fa-ban',
+                        texticon: 'fa fa-ban',
+                        title: QUILocale.get(lg, 'dialog.invoice.reversal.title', {
                             invoiceId: id
                         }),
-                        text       : QUILocale.get(lg, 'dialog.invoice.reversal.text', {
+                        text: QUILocale.get(lg, 'dialog.invoice.reversal.text', {
                             invoiceId: id
                         }),
                         information: QUILocale.get(lg, 'dialog.invoice.reversal.information', {
                             invoiceId: id
                         }),
-                        autoclose  : false,
-                        ok_button  : {
-                            text     : QUILocale.get(lg, 'dialog.invoice.reversal.submit'),
+                        autoclose: false,
+                        ok_button: {
+                            text: QUILocale.get(lg, 'dialog.invoice.reversal.submit'),
                             textimage: 'fa fa-ban'
                         },
-                        maxHeight  : 500,
-                        maxWidth   : 750,
-                        events     : {
-                            onOpen: function (Win) {
-                                var Container = Win.getContent().getElement('.textbody');
+                        maxHeight: 500,
+                        maxWidth: 750,
+                        events: {
+                            onOpen: function(Win) {
+                                const Container = Win.getContent().getElement('.textbody');
 
                                 // #locale
-                                var Label = new Element('label', {
-                                    html  : '<span>' + QUILocale.get(lg, 'dialog.invoice.reversal.reason.title') + '</span>',
+                                const Label = new Element('label', {
+                                    html: '<span>' + QUILocale.get(
+                                        lg,
+                                        'dialog.invoice.reversal.reason.title'
+                                    ) + '</span>',
                                     styles: {
-                                        display   : 'block',
+                                        display: 'block',
                                         fontWeight: 'bold',
-                                        marginTop : 20,
-                                        width     : 'calc(100% - 100px)'
+                                        marginTop: 20,
+                                        width: 'calc(100% - 100px)'
                                     }
                                 }).inject(Container);
 
-                                var Reason = new Element('textarea', {
-                                    name       : 'reason',
-                                    autofocus  : true,
+                                const Reason = new Element('textarea', {
+                                    name: 'reason',
+                                    autofocus: true,
                                     placeholder: QUILocale.get(lg, 'dialog.invoice.reversal.reason.placeholder'),
-                                    styles     : {
-                                        height   : 160,
+                                    styles: {
+                                        height: 160,
                                         marginTop: 10,
-                                        width    : '100%'
+                                        width: '100%'
                                     }
                                 }).inject(Label);
 
                                 Reason.focus();
                             },
 
-                            onSubmit: function (Win) {
-                                var value = Win.getContent().getElement('[name="reason"]').value;
+                            onSubmit: function(Win) {
+                                const Reason = Win.getContent().getElement('[name="reason"]');
+                                const value = Reason.value;
 
                                 if (value === '') {
+                                    Reason.focus();
+                                    Reason.required = true;
+                                    
+                                    if ('reportValidity' in Reason) {
+                                        Reason.reportValidity();
+                                    }
+
                                     return;
                                 }
 
                                 Win.Loader.show();
 
-                                Invoices.reversalInvoice(result.hash, value).then(function (result) {
+                                Invoices.reversalInvoice(result.hash, value).then(function(result) {
                                     Win.close();
                                     resolve(result);
-                                }).catch(function (Exception) {
+                                }).catch(function(Exception) {
                                     Win.close();
                                     reject(Exception);
                                 });
@@ -138,7 +149,7 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
          * @param {String} invoiceId - Invoice ID or Hash
          * @return {*|Promise}
          */
-        openCancellationDialog: function (invoiceId) {
+        openCancellationDialog: function(invoiceId) {
             return this.openStornoDialog(invoiceId);
         },
 
@@ -148,7 +159,7 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
          * @param {String} invoiceId - Invoice ID or Hash
          * @return {*|Promise}
          */
-        openReversalDialog: function (invoiceId) {
+        openReversalDialog: function(invoiceId) {
             return this.openStornoDialog(invoiceId);
         },
 
@@ -158,34 +169,34 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
          * @param {String} invoiceId - Invoice ID or Hash
          * @return {Promise}
          */
-        openCopyDialog: function (invoiceId) {
-            return Invoices.get(invoiceId).then(function (result) {
-                var id = result.id_prefix + result.id;
+        openCopyDialog: function(invoiceId) {
+            return Invoices.get(invoiceId).then(function(result) {
+                const id = result.id_prefix + result.id;
 
-                return new Promise(function (resolve) {
+                return new Promise(function(resolve) {
                     new QUIConfirm({
-                        title      : QUILocale.get(lg, 'dialog.invoice.copy.title'),
-                        text       : QUILocale.get(lg, 'dialog.invoice.copy.text'),
+                        title: QUILocale.get(lg, 'dialog.invoice.copy.title'),
+                        text: QUILocale.get(lg, 'dialog.invoice.copy.text'),
                         information: QUILocale.get(lg, 'dialog.invoice.copy.information', {
                             id: id
                         }),
-                        icon       : 'fa fa-copy',
-                        texticon   : 'fa fa-copy',
-                        maxHeight  : 400,
-                        maxWidth   : 600,
-                        autoclose  : false,
-                        ok_button  : {
-                            text     : QUILocale.get('quiqqer/system', 'copy'),
+                        icon: 'fa fa-copy',
+                        texticon: 'fa fa-copy',
+                        maxHeight: 400,
+                        maxWidth: 600,
+                        autoclose: false,
+                        ok_button: {
+                            text: QUILocale.get('quiqqer/system', 'copy'),
                             textimage: 'fa fa-copy'
                         },
-                        events     : {
-                            onSubmit: function (Win) {
+                        events: {
+                            onSubmit: function(Win) {
                                 Win.Loader.show();
 
-                                Invoices.copyInvoice(result.hash).then(function (newId) {
+                                Invoices.copyInvoice(result.hash).then(function(newId) {
                                     Win.close();
                                     resolve(newId);
-                                }).then(function () {
+                                }).then(function() {
                                     Win.Loader.hide();
                                 });
                             }
@@ -201,38 +212,38 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
          * @param {String} invoiceId - Invoice ID or Hash
          * @return {Promise}
          */
-        openCreateCreditNoteDialog: function (invoiceId) {
-            var self = this;
+        openCreateCreditNoteDialog: function(invoiceId) {
+            const self = this;
 
-            return Invoices.get(invoiceId).then(function (result) {
-                var paymentHasRefund = false;
-                var id               = result.id_prefix + result.id;
+            return Invoices.get(invoiceId).then(function(result) {
+                let paymentHasRefund = false;
+                const id = result.id_prefix + result.id;
 
-                return new Promise(function (resolve, reject) {
+                return new Promise(function(resolve, reject) {
                     new QUIConfirm({
-                        icon       : 'fa fa-clipboard',
-                        texticon   : 'fa fa-clipboard',
-                        title      : QUILocale.get(lg, 'dialog.invoice.createCreditNote.title', {
+                        icon: 'fa fa-clipboard',
+                        texticon: 'fa fa-clipboard',
+                        title: QUILocale.get(lg, 'dialog.invoice.createCreditNote.title', {
                             invoiceId: id
                         }),
-                        text       : QUILocale.get(lg, 'dialog.invoice.createCreditNote.text', {
+                        text: QUILocale.get(lg, 'dialog.invoice.createCreditNote.text', {
                             invoiceId: id
                         }),
                         information: QUILocale.get(lg, 'dialog.invoice.createCreditNote.information', {
                             invoiceId: id
                         }),
-                        autoclose  : false,
-                        ok_button  : {
-                            text     : QUILocale.get(lg, 'dialog.invoice.createCreditNote.submit'),
+                        autoclose: false,
+                        ok_button: {
+                            text: QUILocale.get(lg, 'dialog.invoice.createCreditNote.submit'),
                             textimage: 'fa fa-clipboard'
                         },
-                        maxHeight  : 400,
-                        maxWidth   : 600,
-                        events     : {
-                            onOpen: function (Win) {
+                        maxHeight: 400,
+                        maxWidth: 600,
+                        events: {
+                            onOpen: function(Win) {
                                 Win.Loader.show();
 
-                                Invoices.hasRefund(id).then(function (hasRefund) {
+                                Invoices.hasRefund(id).then(function(hasRefund) {
                                     paymentHasRefund = hasRefund;
 
                                     QUI.fireEvent('quiqqerInvoiceCreateCreditNoteDialogOpen', [id, Win]);
@@ -242,15 +253,18 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
                                         return;
                                     }
 
-                                    var Content = Win.getContent(),
-                                        Body    = Content.getElement('.textbody');
+                                    const Content = Win.getContent(),
+                                        Body = Content.getElement('.textbody');
 
                                     new Element('label', {
                                         'class': 'quiqqer-invoice-dialog-refund-label',
-                                        html   : '<input type="checkbox" name="refund" />' + QUILocale.get(lg, 'dialog.invoice.createCreditNote.refund'),
-                                        styles : {
-                                            cursor   : 'pointer',
-                                            display  : 'block',
+                                        html: '<input type="checkbox" name="refund" />' + QUILocale.get(
+                                            lg,
+                                            'dialog.invoice.createCreditNote.refund'
+                                        ),
+                                        styles: {
+                                            cursor: 'pointer',
+                                            display: 'block',
                                             marginTop: 20
                                         }
                                     }).inject(Body);
@@ -259,16 +273,16 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
                                 });
                             },
 
-                            onSubmit: function (Win) {
+                            onSubmit: function(Win) {
                                 Win.Loader.show();
 
-                                var Content = Win.getContent(),
-                                    Refund  = Content.getElement('[name="refund"]');
+                                const Content = Win.getContent(),
+                                    Refund = Content.getElement('[name="refund"]');
 
-                                var createInvoice = function (values) {
+                                const createInvoice = function(values) {
                                     values = values || {};
 
-                                    Invoices.createCreditNote(result.hash, values).then(function (newId) {
+                                    Invoices.createCreditNote(result.hash, values).then(function(newId) {
                                         QUI.fireEvent(
                                             'quiqqerInvoiceCreateCreditNoteDialogSubmit',
                                             [newId, Win]
@@ -276,7 +290,7 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
 
                                         resolve(newId);
                                         Win.close();
-                                    }).catch(function (Err) {
+                                    }).catch(function(Err) {
                                         Win.Loader.hide();
                                         console.error(Err);
 
@@ -285,7 +299,7 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
                                 };
 
                                 if (paymentHasRefund && Refund.checked) {
-                                    self.openRefundWindow(invoiceId).then(function (RefundWindow) {
+                                    self.openRefundWindow(invoiceId).then(function(RefundWindow) {
                                         if (!RefundWindow) {
                                             Win.Loader.hide();
                                             return;
@@ -294,7 +308,7 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
                                         createInvoice({
                                             refund: RefundWindow.getValues()
                                         });
-                                    }).catch(function (Err) {
+                                    }).catch(function(Err) {
                                         Win.Loader.hide();
                                         console.error(Err);
                                     });
@@ -304,7 +318,7 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
                                 createInvoice();
                             },
 
-                            onCancel: function () {
+                            onCancel: function() {
                                 resolve(false);
                             }
                         }
@@ -318,17 +332,17 @@ define('package/quiqqer/invoice/bin/backend/utils/Dialogs', [
          * @param invoiceId
          * @return {Promise}
          */
-        openRefundWindow: function (invoiceId) {
-            return new Promise(function (resolve) {
+        openRefundWindow: function(invoiceId) {
+            return new Promise(function(resolve) {
                 require([
                     'package/quiqqer/invoice/bin/backend/controls/panels/refund/Window'
-                ], function (RefundWindow) {
+                ], function(RefundWindow) {
                     new RefundWindow({
-                        invoiceId : invoiceId,
+                        invoiceId: invoiceId,
                         autoRefund: false,
-                        events    : {
+                        events: {
                             onSubmit: resolve,
-                            onCancel: function () {
+                            onCancel: function() {
                                 resolve(false);
                             }
                         }
diff --git a/locale.xml b/locale.xml
index 5748b3f42e53f1e3ce74311de56c23375a539a7a..7885e89163129065a631e2b818068e5e4dbf14ae 100644
--- a/locale.xml
+++ b/locale.xml
@@ -666,7 +666,7 @@
             </ul>
             ]]></de>
             <en><![CDATA[
-            <p>Subject of the cancelletion Invoice mail. Available placeholders:</p>
+            <p>Subject of the cancellation invoice mail. Available placeholders:</p>
             <ul>
                 <li><b>[invoiceId]:</b> Invoice no.</li>
                 <li><b>[cancelledInvoiceId]:</b> Invoice no. of the <b>cancelled</b> invoice</li>
@@ -706,7 +706,7 @@
             </ul>
             ]]></de>
             <en><![CDATA[
-            <p>Content of the cancellation Invoice mail. Available placeholders:</p>
+            <p>Content of the cancellation invoice mail. Available placeholders:</p>
             <ul>
                 <li><b>[invoiceId]:</b> Invoice no.</li>
                 <li><b>[cancelledInvoiceId]:</b> Invoice no. of the <b>cancelled</b> invoice</li>
@@ -1739,9 +1739,25 @@
             <de><![CDATA[Gutschrift zu Rechnung #[id] vom [date]]]></de>
             <en><![CDATA[Credit Note to invoice #[id] from [date]]]></en>
         </locale>
+        <locale name="message.create.reversal.from">
+            <de><![CDATA[Storno-Rechnung erstellt aus Rechnung #[invoiceId]]]></de>
+            <en><![CDATA[Created cancellation invoice from Invoice #[invoiceId]]]></en>
+        </locale>
+        <locale name="message.invoice.reversal.additionalInvoiceText" html="true">
+            <de><![CDATA[Storno-Rechnung zu Rechnung #[id] vom [date]]]></de>
+            <en><![CDATA[Cancellation invoice to invoice #[id] from [date]]]></en>
+        </locale>
+        <locale name="message.invoice.reversal.additionalInvoiceText.creditNote" html="true">
+            <de><![CDATA[Storno-Rechnung zu Gutschrift #[id] vom [date]]]></de>
+            <en><![CDATA[Cancellation invoice to Credit Note #[id] from [date]]]></en>
+        </locale>
+        <locale name="message.create.reversal">
+            <de><![CDATA[Storno-Rechnung erstellt. Neue Storno-Rechnungs-ID #[invoiceId]]]></de>
+            <en><![CDATA[Cancellation invoice invoice. New Cancelletion invoice ID #[invoiceId]]]></en>
+        </locale>
         <locale name="message.invoice.cancellationInvoice.additionalInvoiceText" html="true">
             <de><![CDATA[Storno-Rechnung zu Rechnung #[id] vom [date]]]></de>
-            <en><![CDATA[Cancelletion invoice to invoice #[id] from [date]]]></en>
+            <en><![CDATA[Cancellation invoice to invoice #[id] from [date]]]></en>
         </locale>
         <locale name="message.add.history.sent.to">
             <de><![CDATA[Rechnung wurde versendet an [recipient]]]></de>
@@ -1765,7 +1781,7 @@
         </locale>
         <locale name="invoice.cancelled.title">
             <de><![CDATA[Storno-Rechnungsmail]]></de>
-            <en><![CDATA[Cancelletion Invoice mail]]></en>
+            <en><![CDATA[Cancellation invoice mail]]></en>
         </locale>
         <locale name="invoice.cancelled.description">
             <de><![CDATA[ ]]></de>
@@ -1821,7 +1837,7 @@
 
         <locale name="invoice.cancelled.send.mail.subject">
             <de><![CDATA[Ihre Storno-Rechnung - [invoiceId]]]></de>
-            <en><![CDATA[Your Cancelletion Invoice - [invoiceId]]]></en>
+            <en><![CDATA[Your cancellation invoice - [invoiceId]]]></en>
         </locale>
         <locale name="invoice.cancelled.send.mail.message">
             <de><![CDATA[
diff --git a/src/QUI/ERP/Accounting/Invoice/Handler.php b/src/QUI/ERP/Accounting/Invoice/Handler.php
index 94c59dff783fbc8bdccdea9a16f2f9f70bc30b2d..c1db6e441c3e66c03d91848cd75ae443973211ff 100644
--- a/src/QUI/ERP/Accounting/Invoice/Handler.php
+++ b/src/QUI/ERP/Accounting/Invoice/Handler.php
@@ -10,6 +10,7 @@
 
 use function array_flip;
 use function explode;
+use function is_numeric;
 use function is_string;
 use function mb_strtoupper;
 use function str_replace;
@@ -383,21 +384,48 @@ public function getInvoiceByHash(string $hash)
     /**
      * Return the data from an invoice
      *
-     * @param string|integer $id
+     * @param integer|string $id
      * @return array
      *
      * @throws Exception
      * @throws QUI\Exception
      */
-    public function getInvoiceData($id): array
+    public function getInvoiceData(int|string $id): array
     {
+        // check invoice via hash
+        $result = QUI::getDataBase()->fetch([
+            'from' => self::invoiceTable(),
+            'where' => [
+                'hash' => $id
+            ],
+            'limit' => 1
+        ]);
+
+        if (!empty($result)) {
+            $result[0]['id'] = (int)$result[0]['id'];
+            $result[0]['customer_id'] = (int)$result[0]['customer_id'];
+            $result[0]['order_id'] = (int)$result[0]['order_id'];
+            $result[0]['isbrutto'] = (int)$result[0]['isbrutto'];
+            $result[0]['paid_status'] = (int)$result[0]['paid_status'];
+            $result[0]['canceled'] = (int)$result[0]['canceled'];
+            $result[0]['c_user'] = (int)$result[0]['c_user'];
+
+            $result[0]['nettosum'] = (float)$result[0]['nettosum'];
+            $result[0]['subsum'] = (float)$result[0]['subsum'];
+            $result[0]['sum'] = (float)$result[0]['sum'];
+            $result[0]['processing_status'] = (int)$result[0]['processing_status'];
+
+            return $result[0];
+        }
+
+        // check invoice via old ids
         $whereOr = [
             'id_with_prefix' => $id
         ];
 
-        $idSanitized = \str_replace(Settings::getInstance()->getInvoicePrefix(), '', $id);
+        $idSanitized = str_replace(Settings::getInstance()->getInvoicePrefix(), '', $id);
 
-        if (\is_numeric($idSanitized)) {
+        if (is_numeric($idSanitized)) {
             $whereOr['id'] = (int)$idSanitized;
         }
 
@@ -491,13 +519,13 @@ public function getTemporaryInvoiceByHash(string $hash): InvoiceTemporary
     /**
      * Return the data from a temporary invoice
      *
-     * @param string|int $id
+     * @param int|string $id
      * @return array
      *
      * @throws Exception
      * @throws QUI\Exception
      */
-    public function getTemporaryInvoiceData($id): array
+    public function getTemporaryInvoiceData(int|string $id): array
     {
         $prefix = Settings::getInstance()->getTemporaryInvoicePrefix();
 
diff --git a/src/QUI/ERP/Accounting/Invoice/Invoice.php b/src/QUI/ERP/Accounting/Invoice/Invoice.php
index b46f060fe4cbafaa4b25487820f0d87ebdad06ff..4089b0990d03b5320b07fd64744fa8a533552dc2 100644
--- a/src/QUI/ERP/Accounting/Invoice/Invoice.php
+++ b/src/QUI/ERP/Accounting/Invoice/Invoice.php
@@ -603,12 +603,12 @@ public function reversal(string $reason, $PermissionUser = null): int
             )
         );
 
-        $CreditNote = $this->createCreditNote(
+        $Reversal = $this->createReversal(
             QUI::getUsers()->getSystemUser(),
             $this->getGlobalProcessId()
         );
 
-        $CreditNote->setInvoiceType(Handler::TYPE_INVOICE_REVERSAL);
+        //$CreditNote->setInvoiceType(Handler::TYPE_INVOICE_REVERSAL);
 
         // Cancellation invoice extra text
         $localeCode = QUI::getLocale()->getLocalesByLang(
@@ -643,14 +643,14 @@ public function reversal(string $reason, $PermissionUser = null): int
         }
 
         // saving copy
-        $CreditNote->setAttribute('additional_invoice_text', $message);
+        $Reversal->setAttribute('additional_invoice_text', $message);
 
-        $CreditNote->save(QUI::getUsers()->getSystemUser());
+        $Reversal->save(QUI::getUsers()->getSystemUser());
 
         try {
             Permission::checkPermission('quiqqer.invoice.canEditCancelInvoice', $PermissionUser);
         } catch (QUI\Exception $Exception) {
-            $CreditNote->post(QUI::getUsers()->getSystemUser());
+            $Reversal->post(QUI::getUsers()->getSystemUser());
         }
 
         $this->addHistory(
@@ -660,7 +660,7 @@ public function reversal(string $reason, $PermissionUser = null): int
                 [
                     'username' => $User->getName(),
                     'uid' => $User->getId(),
-                    'creditNoteId' => $CreditNote->getId()
+                    'creditNoteId' => $Reversal->getId()
                 ]
             )
         );
@@ -668,9 +668,9 @@ public function reversal(string $reason, $PermissionUser = null): int
         // set the invoice status
         $this->type = Handler::TYPE_INVOICE_CANCEL;
 
-        $CreditNote = $CreditNote->post(QUI::getUsers()->getSystemUser());
+        $Reversal = $Reversal->post(QUI::getUsers()->getSystemUser());
 
-        $this->data['canceledId'] = $CreditNote->getCleanId();
+        $this->data['canceledId'] = $Reversal->getCleanId();
 
         QUI::getDataBase()->update(
             Handler::getInstance()->invoiceTable(),
@@ -686,10 +686,10 @@ public function reversal(string $reason, $PermissionUser = null): int
 
         QUI::getEvents()->fireEvent(
             'quiqqerInvoiceReversalEnd',
-            [$this, $CreditNote]
+            [$this, $Reversal]
         );
 
-        return $CreditNote->getCleanId();
+        return $Reversal->getCleanId();
     }
 
     /**
@@ -1029,6 +1029,178 @@ public function createCreditNote($PermissionUser = null, $globalProcessId = fals
         return $CreditNote;
     }
 
+    /**
+     * Create a credit note, set the invoice to credit note
+     * - Gutschrift
+     *
+     * @param null|QUI\Interfaces\Users\User $PermissionUser
+     * @param bool|string $globalProcessId
+     * @return InvoiceTemporary
+     *
+     * @throws Exception
+     * @throws QUI\Exception
+     * @throws QUI\Permissions\Exception
+     */
+    public function createReversal($PermissionUser = null, $globalProcessId = false): InvoiceTemporary
+    {
+        Permission::checkPermission('quiqqer.invoice.reversal', $PermissionUser);
+
+        QUI::getEvents()->fireEvent('quiqqerInvoiceCreateReversal', [$this]);
+
+        $Copy = $this->copy(QUI::getUsers()->getSystemUser(), $globalProcessId);
+        $articles = $Copy->getArticles()->getArticles();
+
+        // change all prices
+        $ArticleList = $Copy->getArticles();
+        $ArticleList->clear();
+        $ArticleList->setCurrency($this->getCurrency());
+
+        $priceKeyList = [
+            'price',
+            'basisPrice',
+            'nettoPriceNotRounded',
+            'sum',
+            'nettoSum',
+            'nettoSubSum',
+            'nettoPrice',
+            'nettoBasisPrice',
+            'unitPrice',
+        ];
+
+        foreach ($articles as $Article) {
+            $article = $Article->toArray();
+
+            foreach ($priceKeyList as $priceKey) {
+                if (isset($article[$priceKey])) {
+                    $article[$priceKey] = $article[$priceKey] * -1;
+                }
+            }
+
+            if (isset($article['calculated'])) {
+                foreach ($priceKeyList as $priceKey) {
+                    if (isset($article['calculated'][$priceKey])) {
+                        $article['calculated'][$priceKey] = $article['calculated'][$priceKey] * -1;
+                    }
+                }
+            }
+
+            if (isset($article['calculated']['vatArray'])) {
+                $article['calculated']['vatArray']['sum'] = $article['calculated']['vatArray']['sum'] * -1;
+            }
+
+            $Clone = new QUI\ERP\Accounting\Article($article);
+            $ArticleList->addArticle($Clone);
+        }
+
+        $PriceFactors = $ArticleList->getPriceFactors();
+        $Currency = $this->getCurrency();
+
+        /* @var $PriceFactor QUI\ERP\Accounting\PriceFactors\Factor */
+        foreach ($PriceFactors as $PriceFactor) {
+            $PriceFactor->setNettoSum($PriceFactor->getNettoSum() * -1);
+            $PriceFactor->setSum($PriceFactor->getSum() * -1);
+            $PriceFactor->setValue($PriceFactor->getValue() * -1);
+
+            $PriceFactor->setNettoSumFormatted($Currency->format($PriceFactor->getNettoSum()));
+            $PriceFactor->setSumFormatted($Currency->format($PriceFactor->getSum()));
+            $PriceFactor->setValueText($Currency->format($PriceFactor->getValue()));
+        }
+
+        $Copy->addHistory(
+            QUI::getLocale()->get('quiqqer/invoice', 'message.create.reversal.from', [
+                'invoiceParentId' => $this->getId(),
+                'invoiceId' => $this->getId()
+            ])
+        );
+
+        // credit note extra text
+        $localeCode = QUI::getLocale()->getLocalesByLang(
+            QUI::getLocale()->getCurrent()
+        );
+
+        $Formatter = new IntlDateFormatter(
+            $localeCode[0],
+            IntlDateFormatter::SHORT,
+            IntlDateFormatter::NONE
+        );
+
+        $currentDate = $this->getAttribute('date');
+
+        if (!$currentDate) {
+            $currentDate = time();
+        } else {
+            $currentDate = strtotime($currentDate);
+        }
+
+        if ($this->getInvoiceType() === Handler::TYPE_INVOICE_CREDIT_NOTE) {
+            $message = $this->getCustomer()->getLocale()->get(
+                'quiqqer/invoice',
+                'message.invoice.reversal.additionalInvoiceText.creditNote',
+                [
+                    'id' => $this->getId(),
+                    'date' => $Formatter->format($currentDate)
+                ]
+            );
+        } else {
+            $message = $this->getCustomer()->getLocale()->get(
+                'quiqqer/invoice',
+                'message.invoice.reversal.additionalInvoiceText',
+                [
+                    'id' => $this->getId(),
+                    'date' => $Formatter->format($currentDate)
+                ]
+            );
+        }
+
+
+        $additionalText = $Copy->getAttribute('additional_invoice_text');
+
+        if (!empty($additionalText)) {
+            $additionalText .= '<br />';
+        }
+
+        $additionalText .= $message;
+
+        // saving copy
+        $Copy->setData('originalId', $this->getCleanId());
+        $Copy->setData('originalIdPrefixed', $this->getId());
+
+        $Copy->setAttribute('date', date('Y-m-d H:i:s'));
+        $Copy->setAttribute('additional_invoice_text', $additionalText);
+        $Copy->setAttribute('currency_data', $this->getAttribute('currency_data'));
+        $Copy->setInvoiceType(Handler::TYPE_INVOICE_REVERSAL);
+
+        if ($this->getAttribute('invoice_address')) {
+            try {
+                $address = json_decode($this->getAttribute('invoice_address'), true);
+                $Address = new QUI\ERP\Address($address);
+
+                $invoiceAddressId = $Address->getId();
+                $invoiceAddress = $Address->toJSON();
+
+                $Copy->setAttribute('invoice_address_id', $invoiceAddressId);
+                $Copy->setAttribute('invoice_address', $invoiceAddress);
+            } catch (\Exception $Exception) {
+                QUI\System\Log::addDebug($Exception->getMessage());
+            }
+        }
+
+        $Copy->save(QUI::getUsers()->getSystemUser());
+
+        $this->addHistory(
+            QUI::getLocale()->get('quiqqer/invoice', 'message.create.reversal', [
+                'invoiceParentId' => $this->getId(),
+                'invoiceId' => $Copy->getId()
+            ])
+        );
+
+        $Reversal = Handler::getInstance()->getTemporaryInvoice($Copy->getId());
+
+        QUI::getEvents()->fireEvent('quiqqerInvoiceCreateReversalEnd', [$this, $Reversal]);
+
+        return $Reversal;
+    }
+
     /**
      * Links an existing transaction (i.e. a transaction that was originally created for a different entity than
      * this invoice) to this invoice.