Subversion Repositories SmartDukaan

Rev

Blame | Last modification | View Log | RSS feed

package com.spice.profitmandi.dao.enumuration.dtr;

/**
 * Lifecycle of one LMS dial attempt, normalised across dialer providers.
 *
 * <p>Providers use their own vocabularies (Vonage: {@code ringing/answered/completed/busy/unanswered/
 * rejected/failed}; Knowlarity pushes a free-text {@code call_status}). Each
 * {@code LmsDialerProvider} maps its vendor status onto this set so the LMS — the trail, the SLA
 * clock, the BGC Daily report — never has to know which dialer placed the call.
 *
 * <p>{@link #ANSWERED} is the one that matters for the 5-hr first-contact SLA (SOP §11): a call that
 * merely rang is not contact.
 */
public enum LeadCallStatus {

    /** Placed with the provider; the retailer's phone has not rung yet. */
    INITIATED,
    /** Ringing at the retailer. */
    RINGING,
    /** Retailer picked up — this is what closes the first-contact SLA. */
    ANSWERED,
    /** Answered and then hung up normally. Terminal. */
    COMPLETED,
    /** Rang out with no answer. Terminal. */
    UNANSWERED,
    /** Retailer's line was busy. Terminal. */
    BUSY,
    /** Actively declined. Terminal. */
    REJECTED,
    /** Never connected — carrier/provider error, bad number, agent leg died. Terminal. */
    FAILED,
    /** Agent abandoned before the retailer answered. Terminal. */
    CANCELLED;

    /** No further provider events are expected for this call. */
    public boolean isTerminal() {
        return this != INITIATED && this != RINGING && this != ANSWERED;
    }

    /** Did the retailer actually pick up? Only these may stamp {@code Lead.firstContactedAt}. */
    public boolean isConnected() {
        return this == ANSWERED || this == COMPLETED;
    }

    /**
     * How far through the call this state is. Providers do not guarantee webhook ordering, so a
     * {@code ringing} event can land after {@code answered}; comparing ranks is what stops a
     * late-arriving earlier event from walking the call backwards.
     */
    public int progressRank() {
        switch (this) {
            case INITIATED:
                return 0;
            case RINGING:
                return 1;
            case ANSWERED:
                return 2;
            default:
                // Every terminal state sits at the end.
                return 3;
        }
    }

    /** Would moving from {@code current} to this state be a forward step? Null current always is. */
    public boolean advancesFrom(LeadCallStatus current) {
        return current == null || progressRank() >= current.progressRank();
    }
}