Der Abschlags-Agent ist spezialisiert auf die automatisierte Bearbeitung von Kundenwünschen zur Anpassung von Abschlagszahlungen. Er analysiert, validiert und verarbeitet Änderungsanfragen für monatliche Zahlungen und sorgt für eine nahtlose Umsetzung im Abrechnungssystem. Durch intelligente Prüfmechanismen werden Abschlagsänderungen im Rahmen sinnvoller Parameter ermöglicht, während gleichzeitig die Zahlungssicherheit gewährleistet bleibt.

Kernfunktionalitäten

Der Abschlags-Agent übernimmt den gesamten Prozess der Abschlagsanpassung und bietet dabei folgende zentrale Leistungen:

  • Bedarfsanalyse: Bewertung der gewünschten Änderung im Kontext des tatsächlichen Verbrauchs
  • Plausibilitätsprüfung: Automatische Validierung, ob die angeforderte Änderung innerhalb sinnvoller Grenzen liegt
  • Umsetzung: Direkte Anpassung der Abschlagshöhe in allen relevanten Systemen
  • Kommunikation: Automatisierte Bestätigung der Änderung mit Angabe des Gültigkeitszeitpunkts

Prozessablauf

Der Agent folgt einem strukturierten Ablauf, der sowohl Kundenzufriedenheit als auch finanzielle Stabilität sicherstellt:

  1. Erkennung des Anliegens und Extraktion relevanter Informationen (gewünschte Abschlagshöhe, Zeitpunkt)
  2. Abgleich mit Verbrauchsdaten zur Prüfung der Angemessenheit der angeforderten Änderung
  3. Bewertung des Änderungswunsches anhand vordefinierter Regeln und Grenzwerte
  4. Durchführung der Anpassung bei positiver Bewertung oder Vorschlag alternativer Beträge
  5. Transparente Kommunikation mit dem Kunden über das Ergebnis und weitere Schritte

Durch die Kombination aus Datenanalyse und klaren Entscheidungsregeln ermöglicht der Abschlags-Agent eine schnelle, konsistente und kundenorientierte Bearbeitung von Änderungswünschen bei gleichzeitiger Entlastung des Kundenservice-Teams.

<?php

use EnneoSDK\Api;
use EnneoSDK\IntentInfo;
use EnneoSDK\IntentOption;
use EnneoSDK\Interaction;

require(getenv()['SDK'] ?? 'sdk.php');
/** @var stdClass $in */

######### Expected Input:
// contractId -> ID of the contract (required)
// requestedDeposit -> Amount of the deposit (required)
// channel -> ticket channel. Voice and chat can be handled synchronously (required)

######### Possible Actions:
// For better readability, actions can be prefixed with "base_", if they are handled in main agent business logic
// Increase requested deposit to minimum allowed
const BASE_INCREASE_DEPOSIT = 'base_increase_deposit';
// Decrease requested deposit to maximum allowed
const BASE_DECREASE_DEPOSIT = 'base_decrease_deposit';
// Deposit is not valid. Inform customer.
const DEPOSIT_INVALID = 'deposit_invalid';
// Save valid deposit
const SAVE_DEPOSIT = 'save_deposit';


$interaction = new Interaction($in);
$deposit = getCurrentDeposit($in->contractId);


######### ACTION: Deposit already validated, "save deposit" action selected
if ($in->_action === SAVE_DEPOSIT) {
    $params = [
        'contractId' => $in->contractId,
        'depositValue' => $in->requestedDeposit,
    ];
    try {
        saveDeposit($in->contractId, $in->requestedDeposit);
        stopProcessing($interaction);
    } catch (Throwable $t) {
        $interaction->infos[] = new IntentInfo(
            type: 'danger',
            message: sprintf('API-Aufruf fehlgeschlagen: %s', $t->getMessage())
        );
        // add the "try again" option using an empty action type.
        $interaction->options[] = new IntentOption(
            type: '',
            name: 'Erneut versuchen',
            recommended: true
        );
    }
}


######### STEP: Fetch current deposit value
$currentDepositValue = getCurrentDeposit($in->contractId);
$minAllowed = round($currentDepositValue * 0.95, 2);
$maxAllowed = round($currentDepositValue * 2.5, 2);
$interaction->infos[] = new IntentInfo(
    type: 'neutral',
    message: sprintf('Aktueller Abschlag: %s. Min.: %s  Max.: %s', $currentDepositValue, $minAllowed, $maxAllowed)
);

######### ACTION: Set Deposit to the minimum
if ($in->_action === BASE_INCREASE_DEPOSIT) {
    $interaction->infos[] = new IntentInfo(
        type: 'neutral',
        message: sprintf('Abschlag auf %s hochgesetzt', $currentDepositValue)
    );
    $in->requestedDeposit = $minAllowed;
}

######### ACTION: Set Deposit to the maximum
if ($in->_action === BASE_DECREASE_DEPOSIT) {
    $interaction->infos[] = new IntentInfo(
        type: 'neutral',
        message: sprintf('Abschlag auf %s reduziert', $currentDepositValue)
    );
    $in->requestedDeposit = $maxAllowed;
}

######### STEP: Validate deposit
// this is a sample validation with a tolerance while decreasing and increasing the allowed deposit values
// you can adjust this to your needs
$isDepositValid = true;
if ($in->requestedDeposit < $minAllowed) {
    $interaction->infos[] = new IntentInfo(
        type: 'warning',
        message: sprintf('Gewünschter Abschlag zu niedrig. Mindestabschlag: %s', $minAllowed)
    );
    $interaction->options[] = new IntentOption(
        type: BASE_INCREASE_DEPOSIT,
        name: 'Auf Mindestabschlag erhöhen',
        recommended: isSyncChannel($in)
    );
    $isDepositValid = false;
}
if ($in->requestedDeposit > $maxAllowed) {
    $interaction->infos[] = new IntentInfo(
        type: 'warning',
        message: sprintf('Abschlag zu hoch. Max: %s €', $maxAllowed)
    );
    $interaction->options[] = new IntentOption(
        type: BASE_DECREASE_DEPOSIT,
        name: 'Auf Maximalabschlag reduzieren',
        recommended: isSyncChannel($in)
    );
    $isDepositValid = false;
}
// If asking the customer for an adjusted deposit amount is not possible (email / letter etc),
// recommended action would be to stop processing and let the customer know that the deposit can't be adjusted
if (!$isDepositValid && !isSyncChannel($in)) {
    $interaction->options[] = new IntentOption(
        type: DEPOSIT_INVALID,
        name: 'Kunden informieren',
        recommended: true
    );
}
if (!$isDepositValid) {
    stopProcessing($interaction);
}

######### STEP: Add Action to save deposit in the system
$interaction->infos[] = new IntentInfo(
    type: 'success',
    message: 'Angefragter Abschlag nicht valid'
);
$interaction->options[] = new IntentOption(
    type: SAVE_DEPOSIT,
    name: 'Abschlag speichern',
    recommended: true
);
stopProcessing($interaction);


######### HELPER FUNCTIONS #########

/**
 * Function simulating a request to an external API and returning the current deposit value
 */
function getCurrentDeposit(int $contractId): float
{
    $response = Api::call(
        method: 'POST',
        url: 'https://echo.enneo.ai',
        params: ['value' => 123.45]
    );

    return $response->vlaue ?? 123.45;
}

function saveDeposit(int $contractId, float $requestedDeposit): void
{
    $response = Api::call(
        method: 'POST',
        url: 'https://echo.enneo.ai',
        params: [
            'contractId' => $contractId,
            'depositValue' => $requestedDeposit,
        ]
    );
}

function isSyncChannel(stdClass $in): bool
{
    return in_array($in->channel, ['chat', 'phone']);
}

/**
 * Business logic execution should always return an Interaction object in JSON format
 */
function stopProcessing(Interaction $interaction): void
{
    echo json_encode($interaction);
    exit();
}