Wiki

Clone wiki

User Apps / Steuersystem

Was ist das Steuersystem?

Mit dem Steuersystem erhält Knuddels Knuddel, wenn eine App Knuddel an einen Nutzer auszahlt.

Es gilt: Generell werden alle Knuddel versteuert, die ein User zum Spielen in einer App genutzt hat. Wieviele der eingezahlten Knuddel ein User wirklich genutzt hat, entscheidet die App. Durch dieses Konzept ist sichergestellt, dass ein User nicht 1.000 Knuddel einzahlt, 1.000 Knuddel auszahlt und diese wieder versteuert werden ohne dass die App sie benötigt hat.

Jede App sollte bis dahin angepasst werden, da sonst alle Knuddel versteuert werden!

Die Klasse KnuddelAccount

Dies ist das Konto eines jeden Users. Hierbei wird jedoch zwischen bereits genutzten Knuddel und ungenutzten Knuddel unterschieden. Ungenutze Knuddel sind alle Knuddel, die ein Nutzer mit /appknuddel an den AppBot überwiesen hat. Diese können jederzeit wieder steuerfrei ausgezahlt werden. Die genutzten Knuddel sind die Knuddel, die eine App zum Spielen angefordert hat. Die Auszahlung dieser Knuddel sind steuerpflichtig. Mit getKnuddelAmountUsed() und getKnuddelAmountUnused() können die Anzahl an Knuddel abgefragt werden.

Weitere Informationen zur Klasse KnuddelAccount findest du in der API-Dokumentation.

Das Event App.onAccountReceivedKnuddel

Mit diesem Event wird signalisiert, dass die App die KnuddelAccounts nutzt. Diese Funktion ist strukturell App.onKnuddelReceived angelehnt, sodass die Umstellung auf das KnuddelAccount-System einfacher möglich ist.

Wenn diese Funktion nicht bereitgestellt wird, sondern nur App.onKnuddelReceived, werden alle Knuddel als genutze Knuddel im KnuddelAccount des Users gespeichert und somit auch versteuert!

Weitere Informationen zum Event App.onAccountReceivedKnuddel findest du in der API-Dokumentation.

Wie läuft das nun in der App ab?

Wenn ein User /appknuddel im Chat eingibt, werden die Knuddel im KnuddelAccount des Users als ungenutzte Knuddel gespeichert. Wichtig hierfür ist die Implementierung von App.onAccountReceivedKnuddel. Dem AppBot stehen diese Knuddel noch nicht zur Verfügung!

Die App kann nun die eingezahlten Knuddel anfordern und als Einsatz des Users werten. Dafür steht die Funktion KnuddelAccount.use zur Verfügung. Diese Knuddel werden dann als genutzt gewertet und später versteuert. Zusätzlich muss ein Grund angegeben werden. Dieser ist später für den User sichtbar, sodass er nachvollziehen kann, welche Knuddel er eingezahlt hat und welche für ein Spiel tatsächlich genutzt wurden.

Erst jetzt wird der bisherige Workflow durchlaufen, um dem AppBot die Knuddel gutzuschreiben. Wird App.onBeforeKnuddelReceived implementiert, wird diese Funktion nun aufgerufen und die App kann entscheiden, ob die Knuddel an den AppBot übertragen, abgelehnt oder in den KnuddelPot verschoben werden sollen. Wurden die Knuddel angenommen, wird auch wie bisher App.onKnuddelReceived aufgerufen.

Die Auszahlung an den User erfolgt über BotUser.transferKnuddel. Statt eines Users kann hier jetzt aber auch ein KnuddelAccount angegeben werden. Die Auszahlung erfolgt dann nicht an den User, sondern die Knuddel werden dem Account als genutzte Knuddel gutgeschrieben.

Rechnen mit dem Steuersystem

appInfo.getTaxRate() liest den aktuellen Steuersatz aus, z.B. 15, wenn der aktuelle Steuersatz bei 15% liegt. Die anfallenden Steuern kann man wie folgt berechnen: <amount> / 100 * <taxRate>. Das heißt, wenn ein Nutzer 8.000 Knuddel hätte und der Steuersatz bei 15% liegt, müsste der AppBot 1.200 Knuddel Steuern zahlen.

appInfo.getTotalTaxKnuddelAmount() addiert die genutzen Knuddel aller User und berechnet die zu zahlende Steuer für die Knuddel. Somit kann man bestimmen, wie viele Knuddel dem Bot abgezogen werden, wenn alle User ihre Knuddel auszahlen würden.

appInfo.getMaxPayoutKnuddelAmount() berechnet die Knuddel, die der AppBot auszahlen könnte unter Berücksichtigung des aktuellen Steuersatzes und der genutzen Knuddel aller User. Das kann man auch wie folgt selbst berechnen: (<amount> - <totalUsed>) * 100 / (100 + <taxRate>). Das heißt, wenn der Bot 10.000 Knuddel hätte, die genutzten Knuddel alle User 2.000 Knuddel wären und der Steuersatz bei 15% liegt, können maximal 6.956,52 Knuddel vom Bot abgebucht werden. Die Differenz bilden die Steuern.

Kann ich das auch irgendwie testen?

Finomosec hat hierfür extra eine kleine App gebaut, um das Steuersystem zu testen. Eine Anleitung zur Installation und einer Beschreibung zur Nutzung findest du im Knuddels-Forum.

Beispiel-Code

Wenn du selbst eine App bauen willst, kannst du dich an folgendem Beispiel orientieren:

// So beginnt jede App
var App = new (function() {

  // Steuersystem nutzen
  // Diese Funktion wird aufgerufen, wenn jemand /appknuddel nutzt.
  this.onAccountReceivedKnuddel = function(sender, receiver, knuddelAmount, transferReason, knuddelAccount) {
    // Die Knuddel sind nun als ungenutzt vorgemerkt.
    sender.sendPrivateMessage('Du hast ' + knuddelAmount.asNumber() + ' Knuddel eingezahlt.');
  }

  // Der Bot hat nach dem Aufruf von KnuddelAccount.use die Knuddel erhalten.
  this.onKnuddelReceived = function(sender, receiver, knuddelAmount, transferReason) {
    sender.sendPrivateMessage('Dir wurden ' + knuddelAmount.asNumber() + ' zum Spielen abgezogen.');
  }

  // App-Befehle
  this.chatCommands = {
    // Mit dem Befehl "/spielen" nimmt der User an einer Runde teil.
    'spielen': function(user, param, command) {
      // 1 Knuddel vom User anfordern
      var knuddelAmount = new KnuddelAmount(1);
      var knuddelAccount = user.getKnuddelAccount();

      // Hat der Nutzer überhaupt so viele Knuddel?
      if (!knuddelAccount.hasEnough(knuddelAmount)) {
        // Nein, also darf er nicht spielen.
        user.sendPrivateMessage('Du musst mindestens einen Knuddel einzahlen!');
        // nicht weiter machen
        return;
      }

      // Er hat genug, sie werden angefordert und auf den Bot übertragen.
      knuddelAccount.use(knuddelAmount, 'Eine Runde spielen', {
        'onError': function() {
          // Das hat doch nicht geklappt.
          // Vermutlich hat der User gerade eben alle Knuddel ausgezahlt.
          user.sendPrivateMessage('Du kannst derzeit nicht spielen!');
          // Hier endet die Runde automatisch.
        },
        'onSuccess': function() {
          // Es hat alles geklappt, nun kann gespielt werden.
          // ...

          // Nehmen wir an, er hat gewonnen und erhält seinen Einsatz zurück.
          // Die Auszahlung sollte zunächst immer an den Account erfolgen,
          // so kann man Steuern sparen, da eine Überweisung von Knuddel
          // vom Bot an einen Account immer steuerfrei sind.
          // Der User kann dann selbst entscheiden, ob er damit wieder spielen
          // möchte oder sie auf seinem Nick haben möchte.
          KnuddelsServer.getDefaultBotUser().transferKnuddel(knuddelAccount, knuddelAmount, {
            'displayReasonText': 'Du hast gewonnen!'
          });
        }
      });
    },

    // Mit dem Befehl /auszahlen <ZAHL> kann der User sich Knuddel auszahlen lassen.
    // <ZAHL> ist hierbei die Anzahl der Knuddel, die der Nutzer haben will.
    // <ZAHL> kann auch eine Kommazahl sein, also "1" oder "1.23"
    // Diese werden dann versteuert und auf seinen Nick übertragen.
    'auszahlen': function(user, param, command) {
      // Wurde der Befehl korrekt verwendet?
      if (param === '') {
        // Der Nutzer hat keine Zahl angegeben.
        user.sendPrivateMessage('Wieviele Knuddel möchtest du haben?');
        // nicht weiter machen
        return;
      }

      // Hat der Nutzer eine gültige Zahl angegeben?
      var amountAsNumber = parseFloat(param);
      if (isNaN(amountAsNumber)) {
        // Er hat etwas anderes angegeben, zum Beispiel "abc" oder "1.2.3"
        user.sendPrivateMessage('Das ist keine gültige Zahl.');
        // nicht weiter machen
        return;
      }

      // 1.234567 wäre auch eine gültige Zahl.
      // Daher sollte zunächst auf 2 Stellen gerundet werden.
      // Das ist auch gleich eine Optimierung für die Ausgabe.
      amountAsNumber = amountAsNumber.toFixed(2);

      // Aus der Zahl muss ein KnuddelAmount Objekt gebaut werden.
      var knuddelAmount = new KnuddelAmount(amountAsNumber);

      // Hat der Nutzer überhaupt so viele Knuddel?
      var knuddelAccount = user.getKnuddelAccount();
      if (!knuddelAccount.hasEnough(knuddelAmount)) {
        // Nein, er hat weniger Knuddel als angegeben.
        user.sendPrivateMessage('So viele Knuddel hast du nicht.');
        // nicht weiter machen
        return;
      }

      // Hat der Bot so viele Knuddel?
      // Hier kann nicht der KnuddelAmount des Bots abgefragt werden,
      // da die Auszahlungen versteuert werden.
      // AppInfo.getMaxPayoutKnuddelAmount ist hierfür der richtige Weg.
      var appInfo = KnuddelsServer.getAppAccess().getOwnInstance().getAppInfo();
      if (appInfo.getMaxPayoutKnuddelAmount().asNumber() < knuddelAmount.asNumber()) {
        // Der Bot kann derzeit nicht so viele Knuddels auszahlen.
        user.sendPrivateMessage('Die Auszahlung ist derzeit nicht möglich.');
        // nicht weiter machen
        return;
      }

      // Die Knuddel werden nun vom Bot auf den Nick übertragen.
      // Hier muss nun der User als Parameter angegeben werden.
      KnuddelsServer.getDefaultBotUser().transferKnuddel(user, knuddelAmount, {
        'displayReasonText': 'Hier sind deine ' + amountAsNumber + ' Knuddel'
      });
    }
  };

})();

Updated