You are currently viewing Zoho Books, Zoho Catalyst und Zoho Cliq: Asynchrone Lagerbestandsprüfung automatisieren

Zoho Books, Zoho Catalyst und Zoho Cliq: Asynchrone Lagerbestandsprüfung automatisieren

  • Post author:

Robuste Lagerbestandsprüfung: Wenn Zoho Flow und Custom Functions an ihre Grenzen stoßen

Die Automatisierung von Geschäftsprozessen ist eine der größten Stärken des Zoho-Ökosystems. Mit Werkzeugen wie Workflow-Regeln im Zoho CRM oder visuellen Automatisierungen in Zoho Flow kannst du schnell beeindruckende Ergebnisse erzielen. Doch was passiert, wenn diese Prozesse geschäftskritisch werden und die Komplexität zunimmt? Oftmals stößt man auf subtile, aber schwerwiegende Probleme wie sogenannte „Race Conditions“ – ein Wettlauf von gleichzeitig ablaufenden Skripten, der zu unvorhersehbaren Fehlern führt. In diesem Artikel zeigen wir dir eine typische Herausforderung aus der Praxis – die automatisierte Lagerbestandsprüfung bei Auftragsbestätigung – und wie du sie mit einem robusten, asynchronen Ansatz unter Verwendung von Zoho Catalyst zuverlässig und skalierbar löst.

Praxisbeispiel: Die Tücken der synchronen Lagerbestandsprüfung

Stell dir ein typisches Szenario in einem Handelsunternehmen oder E-Commerce-Shop vor, der sein operatives Geschäft mit Zoho Books oder Zoho Inventory verwaltet. Der gewünschte Prozess ist einfach und logisch:

  1. Ein Kundenauftrag (Sales Order) wird erstellt und vom Vertriebsteam auf den Status „bestätigt“ gesetzt.
  2. In diesem Moment soll ein automatisierter Prozess starten.
  3. Der Prozess prüft für jeden Artikel im Auftrag den verfügbaren Lagerbestand in Zoho Inventory.
  4. Fall A: Sind alle Artikel in ausreichender Menge vorhanden, wird automatisch eine E-Mail an das Logistikteam gesendet, um den Versand vorzubereiten.
  5. Fall B: Fehlt mindestens ein Artikel, geht stattdessen eine Benachrichtigung an den Einkauf, um die fehlenden Waren nachzubestellen.

Das Problem in der Praxis: Dieser scheinbar simple Prozess ist extrem fehleranfällig, wenn er mit herkömmlichen, event-getriggerten Workflows (z.B. „Bei Auftragsänderung ausführen“) umgesetzt wird. Oft laufen auf denselben Trigger – die Statusänderung eines Auftrags – mehrere Workflows gleichzeitig. Das System versucht dann, den Datensatz mehrfach in Millisekunden zu lesen und zu schreiben, was zu unzuverlässigen Ausführungen führt. Die Folge ist ein hohes Geschäftsrisiko: Aufträge werden nicht an die Logistik gemeldet, Kunden warten vergeblich auf ihre Lieferung und die Kundenzufriedenheit sinkt.

Schritt-für-Schritt Anleitung: Der Weg zur asynchronen Lösung mit Zoho Catalyst

Anstatt direkt und synchron auf das Ereignis zu reagieren, entkoppeln wir den Prozess. Wir bauen einen Scheduler, der in regelmäßigen Abständen nach „neuen“ Aufgaben sucht und sie kontrolliert abarbeitet. Zoho Catalyst, Zohos Serverless-Plattform, ist dafür das perfekte Werkzeug.

Schritt 1: Vorbereitung in Zoho Books / Inventory

Zuerst benötigen wir ein Hilfsfeld im Modul „Sales Orders“, um den Verarbeitungsstatus unseres neuen Prozesses zu verfolgen. Dieses Feld verhindert, dass ein Auftrag mehrfach bearbeitet wird.

  • Gehe zu Einstellungen > Anpassung > Sales Orders > Feld anpassen.
  • Erstelle ein neues Feld vom Typ „Dropdown“ (Auswahlliste).
  • Nenne es zum Beispiel Verarbeitungsstatus Lagerprüfung.
  • Definiere die folgenden Optionen:
    • Neu (als Standardwert festlegen)
    • In Bearbeitung
    • Erfolgreich
    • Fehlgeschlagen

Jeder neue, bestätigte Auftrag startet nun automatisch mit dem Status „Neu“.

Schritt 2: Das Grundgerüst in Zoho Catalyst aufsetzen

Nun richten wir die ausführende Logik in Catalyst ein. Falls du noch kein Catalyst-Projekt hast, erstelle eines über die Catalyst-Konsole.

  1. Navigiere in deinem Projekt zu Compute > Functions.
  2. Erstelle eine neue Funktion. Wähle als Typ „Scheduled Function“. Dies ist eine Funktion, die nicht durch einen API-Aufruf, sondern durch einen Zeitplan ausgelöst wird.
  3. Vergib einen aussagekräftigen Namen, z.B. processPendingSalesOrders. Wähle deine bevorzugte Programmierumgebung, z.B. Node.js.
  4. Im nächsten Schritt definierst du den Zeitplan (CRON Job). Um die Funktion alle 5 Minuten auszuführen, gibst du den folgenden CRON-Ausdruck ein: 0 */5 * * * *.
  5. Erstelle und deploye die Funktion.

Schritt 3: Die Logik in der Catalyst-Funktion

Jetzt füllen wir die Funktion mit Leben. Der Code wird die Aufträge abrufen, die Bestände prüfen und die entsprechenden Aktionen auslösen. Das folgende Beispiel ist in Node.js geschrieben und nutzt das Zoho Catalyst SDK zur Authentifizierung und für API-Aufrufe.

A) Aufträge abfragen
Zuerst fragen wir alle bestätigten Aufträge ab, die noch nicht verarbeitet wurden.


// Node.js Beispiel für eine Zoho Catalyst Scheduled Function
const catalyst = require('zcatalyst-sdk-node');

module.exports = async (cronDetails, context) => {
    const app = catalyst.initialize(context);
    const zcql = app.zcql();

    try {
        // ZCQL-Query, um relevante Aufträge zu finden
        const query = `
            SELECT 
                Salesorder.salesorder_id, 
                Salesorder.customer_name,
                Salesorder.salesorder_number,
                LineItems.item_id,
                LineItems.quantity
            FROM 
                SalesOrders AS Salesorder 
            LEFT JOIN 
                LineItems AS LineItems ON Salesorder.salesorder_id = LineItems.salesorder_id
            WHERE 
                Salesorder.status = 'confirmed' 
            AND 
                Salesorder.cf_verarbeitungsstatus_lagerpruefung = 'Neu'
            LIMIT 200
        `;
        
        const salesOrders = await zcql.executeZCQLQuery(query);

        //... die weitere Verarbeitung folgt hier
        
    } catch (err) {
        console.error("Fehler bei der Abfrage der Aufträge:", err);
        context.close();
    }
    context.close();
};

B) Verarbeitungsschleife und Status-Updates
Wir iterieren durch die gefundenen Aufträge. Der allerwichtigste erste Schritt in der Schleife ist es, den Status auf „In Bearbeitung“ zu setzen. Das ist unser „Locking-Mechanismus“, der verhindert, dass der nächste Scheduler-Lauf in 5 Minuten denselben Auftrag erneut verarbeitet.


// ... innerhalb des try-Blocks nach der Abfrage

for (const order of salesOrders) {
    const salesorderId = order.Salesorder.salesorder_id;
    
    try {
        // SCHRITT 1: Auftrag als "in Bearbeitung" markieren (Locking)
        await updateOrderStatus(app, salesorderId, 'In Bearbeitung');

        // SCHRITT 2: Lagerbestand für alle Artikel prüfen
        let allItemsInStock = true;
        for (const item of order.LineItems) {
            const stock = await getInventoryStock(app, item.item_id);
            if (stock < item.quantity) {
                allItemsInStock = false;
                break; // Schleife abbrechen, ein Artikel reicht
            }
        }

        // SCHRITT 3: Benachrichtigung senden
        if (allItemsInStock) {
            await sendNotification(app, 'logistics', `Auftrag ${order.Salesorder.salesorder_number} versandbereit.`);
        } else {
            await sendNotification(app, 'purchasing', `Waren für Auftrag ${order.Salesorder.salesorder_number} nachbestellen.`);
        }

        // SCHRITT 4: Finalen Status setzen
        await updateOrderStatus(app, salesorderId, 'Erfolgreich');
        
    } catch (err) {
        console.error(`Fehler bei der Verarbeitung von Auftrag ${salesorderId}:`, err);
        // Bei Fehler den Status auf "Fehlgeschlagen" setzen
        await updateOrderStatus(app, salesorderId, 'Fehlgeschlagen');
    }
}

// Hilfsfunktionen (Beispiele)
async function updateOrderStatus(app, orderId, status) {
    const connector = app.connector('zohobooks'); // Connector muss in Catalyst konfiguriert sein
    const url = `/api/v3/salesorders/${orderId}`;
    const body = {
        custom_fields: [
            {
                api_name: 'cf_verarbeitungsstatus_lagerpruefung',
                value: status
            }
        ]
    };
    await connector.put({ url, body: JSON.stringify(body) });
}

async function getInventoryStock(app, itemId) {
    const connector = app.connector('zohobooks');
    const url = `/api/v3/items/${itemId}`;
    const response = await connector.get({ url });
    const itemDetails = JSON.parse(response.body);
    return itemDetails.item.stock_on_hand;
}

async function sendNotification(app, recipient, message) {
    // Hier Logik für Benachrichtigungen implementieren, z.B. via
    // Zoho ZeptoMail API für E-Mails oder
    // Zoho Cliq Incoming Webhook für Chat-Nachrichten
    console.log(`NOTIFICATION an ${recipient}: ${message}`);
}

Tipps und Best Practices

  • Umfassendes Logging: Nutze die Logging-Funktionen von Zoho Catalyst (console.log, console.error), um den Ablauf jeder Funktion nachvollziehbar zu machen. So findest du Fehlerquellen deutlich schneller.
  • Fehlerbehandlung: Setze den Status auf „Fehlgeschlagen“, wenn etwas schiefläuft. Du kannst dann in Zoho Analytics ein Dashboard erstellen, das dir alle fehlgeschlagenen Aufträge anzeigt, damit du sie manuell prüfen kannst.
  • Skalierbarkeit und API-Limits: Die Abfrage ist auf 200 Datensätze limitiert (LIMIT 200). Bei sehr hohem Auftragsvolumen stellt dies sicher, dass deine Funktion nicht in ein Timeout läuft und die API-Limits von Zoho Books nicht überschritten werden. Der nächste Scheduler-Lauf wird einfach die nächsten 200 Aufträge bearbeiten.
  • Professionelles Deployment: Verwalte deinen Catalyst-Code in einem Git-Repository (z.B. bei GitHub oder Bitbucket). Nutze die Deployment-Pipelines von Catalyst, um Änderungen sicher von einer Staging- in eine Produktivumgebung zu übertragen.

Zusätzliche Hinweise und Integrationen

Dieser asynchrone Ansatz ist ein mächtiges Muster, das du für viele andere geschäftskritische Prozesse nutzen kannst:

  • Automatisierte Rechnungsstellung: Ein täglicher Scheduler könnte alle abrechenbaren Stunden aus Zoho Projects und Zoho Desk sammeln und automatisch Rechnungsentwürfe in Zoho Books erstellen.
  • Daten-Synchronisation mit Drittsystemen: Verbinde deine Zoho-Umgebung über Catalyst mit externen APIs, z.B. von Logistikdienstleistern wie DHL, um direkt Versandlabels zu erzeugen, oder mit ERP-Systemen wie SAP.
  • Komplexe Datenvalidierung: Führe nächtliche Jobs aus, die Datenqualitätsprobleme in deinem Zoho CRM identifizieren und Berichte für dein Team erstellen.

Für Benachrichtigungen kannst du statt einer einfachen E-Mail auch gezielt Kanäle in Zoho Cliq über Webhooks ansteuern oder transaktionale E-Mails über Zoho ZeptoMail versenden, was eine bessere Zustellbarkeit und Nachverfolgung gewährleistet.

Fazit

Wenn deine automatisierten Prozesse an die Grenzen von Standard-Workflows stoßen, ist das kein Grund zur Sorge, sondern ein Zeichen dafür, dass dein Unternehmen wächst und die Anforderungen komplexer werden. Der Wechsel von einem synchronen, event-getriggerten Modell zu einem asynchronen, geplanten Prozess mit Zoho Catalyst ist ein entscheidender Schritt zur Schaffung robuster, skalierbarer und transparenter Systemlandschaften. Du eliminierst Race Conditions, verbesserst die Fehlerbehandlung und schaffst eine solide Grundlage für zukünftige Integrationen. Dieser Paradigmenwechsel erfordert anfangs eine kleine Lernkurve, zahlt sich aber durch eine massiv gesteigerte Zuverlässigkeit deiner kritischsten Geschäftsprozesse langfristig aus.


Verwendete Zoho Apps in diesem Szenario: