From caa7d8badbf0b46f8120c5bb2a8360a13ff3e8db Mon Sep 17 00:00:00 2001
From: Dominik Hebeler <dominik@hebeler.club>
Date: Thu, 15 Jun 2023 12:55:13 +0200
Subject: [PATCH] added zammad notifications

---
 pass/app/Key.js                               |  2 +-
 pass/app/Payment.js                           |  3 +-
 pass/app/PaymentReference.js                  | 11 ++--
 pass/app/Zammad.js                            | 53 +++++++++++++++++++
 pass/app/payment_processor/Manual.js          |  4 ++
 .../app/payment_processor/PaymentProcessor.js |  3 ++
 pass/config/default.json                      | 12 ++---
 pass/routes/checkout/micropayment.js          |  2 +-
 8 files changed, 77 insertions(+), 13 deletions(-)
 create mode 100644 pass/app/Zammad.js

diff --git a/pass/app/Key.js b/pass/app/Key.js
index ff875a4..1fb5480 100644
--- a/pass/app/Key.js
+++ b/pass/app/Key.js
@@ -287,7 +287,7 @@ class Key {
       );
     }
 
-    return redis_commands.exec().then(async () => {
+    return redis_commands.exec().then(() => {
       this.#changes = [];
       return this;
     });
diff --git a/pass/app/Payment.js b/pass/app/Payment.js
index 8f0cf6d..16be80e 100644
--- a/pass/app/Payment.js
+++ b/pass/app/Payment.js
@@ -149,10 +149,11 @@ class Payment {
     insert_data.created_at = dayjs().format("YYYY-MM-DD HH:mm:ss");
     return Payments()
       .insert(insert_data, "*")
-      .then((result) => {
+      .then(async (result) => {
         if (result.length !== 1) {
           return Promise.reject("Error creating payment.");
         }
+
         return new Payment(result[0]);
       });
   }
diff --git a/pass/app/PaymentReference.js b/pass/app/PaymentReference.js
index 787ce1a..4fcd47a 100644
--- a/pass/app/PaymentReference.js
+++ b/pass/app/PaymentReference.js
@@ -5,6 +5,7 @@ const Key = require("./Key");
 
 const dayjs = require("dayjs");
 const Payment = require("./Payment");
+const Zammad = require("./Zammad");
 
 /**
  * @typedef {Object} PaymentReferenceDB
@@ -285,12 +286,12 @@ class PaymentReference {
    * @param {string} [data.payment_processor_id]
    * @param {Object} [data.payment_processor_data]
    *
-   * @returns {Payment}
+   * @returns {Promise<Payment>}
    */
   async createPayment(data) {
     data.payment_reference_id = this.id;
     return Payment.CREATE_NEW_PAYMENT(data).then((payment) => {
-      this.getKey(true).then(async (key) => {
+      return this.getKey(true).then(async (key) => {
         await this.setExpiration(dayjs().add(10, "year"));
         let charge_amount = Math.round(
           (payment.price / this.price) * this.amount
@@ -308,7 +309,9 @@ class PaymentReference {
             dayjs().add(config.get("keys.expiration_years"), "year")
           );
         }
-        return key.save().then(() => payment);
+        return Zammad.CREATE_NOTIFICATION(charge_amount, payment.price, payment.payment_processor.serialize().processor_name)
+          .then(() => key.save())
+          .then(key => payment);
       });
     });
   }
@@ -323,7 +326,7 @@ class PaymentReference {
       let expiration = dayjs().add(config.get("keys.expiration_years"), "year");
       return this.setExpiration(expiration).then(() => {
         key.charge_key_order(this.amount, this.id, expiration);
-        return key.save();
+        return Zammad.CREATE_NOTIFICATION(this.amount, 0, "Manual").then(() => key.save());
       });
     });
   }
diff --git a/pass/app/Zammad.js b/pass/app/Zammad.js
new file mode 100644
index 0000000..c4f693a
--- /dev/null
+++ b/pass/app/Zammad.js
@@ -0,0 +1,53 @@
+const config = require("config");
+
+class Zammad {
+
+    /**
+     * Creates a notification in the configured Zammad instance
+     * 
+     * @param {number} token_amount
+     * @param {number} $price
+     * @param {string} $payment_method
+     * 
+     * @returns {Promise<boolean>}
+     */
+    static async CREATE_NOTIFICATION(token_amount, price, payment_method) {
+        // Check if notifications are turned on
+        try {
+            if (config.get("app.zammad.enabled")) {
+                let zammad_url = config.get("app.zammad.url") + "/api/v1/ticket_articles";
+
+                let zammad_data = {
+                    "ticket_id": config.get("app.zammad.notification_ticket_id"),
+                    "subject": "Neue Bestellung",
+                    "body": `Tokens: ${token_amount}\nBetrag: ${price.toFixed(2)}€\nZahlungsart: ${payment_method}`,
+                    "content_type": "text/plain",
+                    "type": "web",
+                    "internal": false,
+                    "sender": "Agent",
+                    "time_unit": "15"
+                }
+                return fetch(zammad_url, {
+                    method: "POST",
+                    headers: {
+                        "Content-Type": "application/json",
+                        "Authorization": `Token ${config.get("app.zammad.api_key")}`
+                    },
+                    body: JSON.stringify(zammad_data)
+                }).then(response => {
+                    return true;
+                }).catch(e => {
+                    console.error(e);
+                    return false;
+                })
+            } else {
+                return true;
+            }
+        } catch (e) {
+            console.error(e);
+            return false;
+        }
+    }
+}
+
+module.exports = Zammad;
\ No newline at end of file
diff --git a/pass/app/payment_processor/Manual.js b/pass/app/payment_processor/Manual.js
index 780b58a..6cd083c 100644
--- a/pass/app/payment_processor/Manual.js
+++ b/pass/app/payment_processor/Manual.js
@@ -4,6 +4,10 @@ const i18next = require("i18next");
 class Manual extends PaymentProcessor {
   #note;
 
+  static get NAME() {
+    return "Manual";
+  }
+
   /**
    *
    * Constructs a new manual Payment
diff --git a/pass/app/payment_processor/PaymentProcessor.js b/pass/app/payment_processor/PaymentProcessor.js
index 704ed09..7c83197 100644
--- a/pass/app/payment_processor/PaymentProcessor.js
+++ b/pass/app/payment_processor/PaymentProcessor.js
@@ -2,6 +2,9 @@ const i18next = require("i18next");
 const PaymentReference = require("../PaymentReference");
 
 class PaymentProcessor {
+  static get NAME() {
+    throw new Error("Function NAME() must be implemented");
+  }
   constructor() {
     if (this.constructor === PaymentProcessor) {
       throw new Error("Cannot instantiate abstract class");
diff --git a/pass/config/default.json b/pass/config/default.json
index ff9d71e..9c6bac7 100644
--- a/pass/config/default.json
+++ b/pass/config/default.json
@@ -17,17 +17,17 @@
       "app_id": "<OPEN ID APP ID>",
       "app_secret": "<OPEN ID APP SECRET>"
     },
-    "civicrm": {
-      "enabled": false,
-      "url": "<ENTER_CIVICRM_URL_HERE>",
-      "user_id": "<USER_ID_THAT_GETS_CONTRIBUTIONS>",
-      "api_key": "<ENTER_CIVICRM_API_KEY_HERE>"
-    },
     "osticket": {
       "enabled": true,
       "url": "<OSTICKET_URL>",
       "api_key": "<OSTICKET_API_KEY>"
     },
+    "zammad": {
+      "enabled": false,
+      "url": "<ZAMMAD_URL>",
+      "api_key": "<ZAMMAD_API_KEY>",
+      "notification_ticket_id": "0"
+    },
     "accent": {
       "apiUrl": "https://translate.metager.de",
       "apiKey": "",
diff --git a/pass/routes/checkout/micropayment.js b/pass/routes/checkout/micropayment.js
index 71bedbc..c663fe8 100644
--- a/pass/routes/checkout/micropayment.js
+++ b/pass/routes/checkout/micropayment.js
@@ -34,7 +34,7 @@ router.get("/event", (req, res) => {
             payment_processor_id: req.query.auth,
             payment_processor_data: req.query,
           })
-          .then(() => redirect_url);
+          .then(async payment => redirect_url);
       } else {
         return redirect_url;
       }
-- 
GitLab