<% /*
    $Revision$
    $Id$

    File:           model_appointments.inc

    Description:    Afspraken model.
    Parameters:
    Context:

    Notes:
*/

%>
<!-- #include file="../Shared/discxalg3d.inc"-->
<!-- #include file="../bez/bez.inc" -->
<!-- #include file="./model_visitors.inc" -->
<!-- #include file="./model_tracking.inc"-->
<%
function afs_alg_onrgoed_keys(jsondata)
{
    // TODO: key-check, auth check
    if (jsondata.room > 0)
        return jsondata.room;
    if (jsondata.floor > 0)
        return jsondata.floor;
    if (jsondata.building > 0)
        return jsondata.building;
    return null;
};

function model_appointments()
{
    this.module = "BEZ";
    this.table = "bez_afspraak";
    this.primary = "bez_afspraak_key";
    this.records_name = "appointments";
    this.record_name = "appointment";
    this.fields =
            {"id"         : { dbs: "bez_afspraak_key",         typ: "key",      label: L("lcl_vis_appointment"), filter: "exact" },
             "from"       : { dbs: "bez_afspraak_datum",       typ: "datetime", label: L("lcl_vis_start_date"),  track: true},
             "to"         : { dbs: "bez_afspraak_eind",        typ: "datetime", label: L("lcl_vis_end_date"),    track: true },
             "description": { dbs: "bez_afspraak_opmerking",   typ: "varchar",  label: L("lcl_remark"),          track: true},
             "action"     : { dbs: "bez_actie_key",            typ: "key",      foreign: "bez_actie", label: L("lcl_action"), track: true},
             "location"   : { dbs: "alg_locatie_key",          typ: "key",      foreign: "alg_locatie"},
             "_alg_keys"  : { dbs: "alg_onrgoed_keys",         typ: "key",      fnval: afs_alg_onrgoed_keys },
             "contact"    : { dbs: "bez_afspraak_contact_key", typ: "key",      foreign: "prs_perslid", label: L("lcl_vis_contactperson"), track: true},
             "reservation": { dbs: "res_rsv_ruimte_key",       typ: "key",      foreign: "res_rsv_ruimte", label: L("lcl_reservation"), track: true}
            };

    if (S("vis_afspraak_onrgoed_uses_keys"))
    {
        this.fields["building"] = { dbs: "alg_v_allonroerendgoed.alg_gebouw_key",     typ: "key", foreign: "alg_gebouw" };
        this.fields["floor"]    = { dbs: "alg_v_allonroerendgoed.alg_verdieping_key", typ: "key", foreign: "alg_verdieping" };
        this.fields["room"]     = { dbs: "alg_v_allonroerendgoed.alg_ruimte_key",     typ: "key", foreign: "alg_ruimte" };
    }
    else if (S("vis_mandatory_alg_level") != "L")
    {
        this.fields["room"]     = { dbs: "bez_afspraak_ruimte",     typ: "varchar", label: L("lcl_room"), track: true};
    }

    if (S("vis_afspraak_host_uses_keys") & 1)
    {
        this.fields["host"] = { dbs: "bez_afspraak_host_key",   typ: "key",     foreign: "prs_perslid", label: L("lcl_vis_visit"), track: true };
    }
    else
    {
        this.fields["host"]  = { dbs: "bez_afspraak_gastheer", typ: "varchar", label: L("lcl_vis_visit"), track: true};
        this.fields["phone"] = { dbs: "bez_afspraak_telefoonnr", typ: "varchar", label: L("lcl_phone"), track: true};
    }

    this.list = { columns: ["id", "from", "to"] },
    this.includes =
               {"visitors": { model: model_visitors,
                             joinfield: "appointment",
                             enable_update: true
                           },
                "tracking": {
                                  model: new model_tracking(['afspraak']),
                                  joinfield: "fac_tracking_refkey"
                            }
              };
    this.impersonate_auth = "WEB_BEZFOF";
    this.REST_GET = function _GET(params)
        {
            var scope = params.filter.scope || "fe";
            var autfunction = { fe : "WEB_BEZUSE", fo : "WEB_BEZFOF", bo : "WEB_BEZBOF", mi : "WEB_RESBAC" } [scope];
            params.authparams = user.checkAutorisation(autfunction, null, null, true); // pessimistisch

            var query = api2.sqlfields(params, this );

            if (params.filter.id)
            {
                var this_bez = bez.func_enabled_afspraak(params.filter.id);
                user.auth_required_or_abort(this_bez.canReadAny);
            }
            else if (scope == "fe")
            {
                query.wheres.push("(bez_afspraak_contact_key = " + user_key
                                + "     OR bez_afspraak_host_key = " + user_key + ")");
                query.wheres.push("bez_afspraak_datum BETWEEN SYSDATE - " + S("facilitiespast_bez") + " AND SYSDATE + " + S("facilitiesfuture_bez"));
            }
            else // TODO: Add authorization
            {
                if (!params.filter.start_from && !params.filter.end_from && !params.filter.start_to && !params.filter.end_to)
                    query.wheres.push("bez_afspraak_datum >= TRUNC(SYSDATE)"); // afspraken van vandaag en komende dagen!
            }

            query.tables.push("alg_v_allonroerendgoed");
            query.wheres.push("alg_v_allonroerendgoed.alg_onroerendgoed_keys(+) = bez_afspraak.alg_onrgoed_keys");

            var wheres = api2.sqlfilter(params, this);
            query.wheres = query.wheres.concat(wheres);

            var sql = "SELECT " + query.selects.join(", ")
                    + "  FROM " + query.tables.join(", ")
                    + " WHERE " + query.wheres.join(" AND " )
                    + " ORDER BY bez_afspraak.bez_afspraak_key";
            if (query.orderbys.length)
                sql += ", " + query.orderbys.join(", ");

            var json = api2.sql2json (params, sql, this );

            return json;
        };

    this._validate_fields = function (dbfields, params, jsondata) /* valideer dbfields, alle constraints die niet door de database worden afgevangen */
    {
        // TODO: vis_fe_afspraak_limiet en vis_afspraak_limiet controleren
        if (jsondata.from < new Date().midnight())
            abort_with_warning(L("lcl_vis_error_date"));
        if (jsondata.from >= jsondata.to)
            abort_with_warning(L("lcl_vis_error_date"));

        if ("action" in jsondata)
        {
            // TODO: mag hij? Of controleren we dat in _validate_fields
        }
        else
        {
            if (!params.isNew)
            {
                // Pak de default actie of de alfabetisch eerste
                var sqla = "SELECT bsez_actie_key"
                         + "     , bez_actie_omschrijving"
                         + "  FROM bez_actie"
                         + " ORDER BY bez_actie_default DESC NULLS LAST, bez_actie_omschrijving";

                var oRs = Oracle.Execute(sqla);
                dbfields["action"] = { dbs: "bez_actie_key",  typ: "key", val: oRs("bez_actie_key").Value };
                oRs.Close()
            }
        }
    };

    this.REST_PUT = function (params, jsondata, the_key) /* update appointment */
        {
            var dbfields = api2.update_fields(params, this, jsondata); // Build updater
            this._validate_fields(dbfields, params, jsondata);

            var this_bez = bez.func_enabled_afspraak(the_key);
            user.auth_required_or_abort(this_bez.canChange);

            // bezUpd heeft na afloop eventueel oldjsvals
            var wheres = [" bez_afspraak_key = " + the_key];
            var bezUpd = buildTrackingUpdate("bez_afspraak", wheres.join(" AND " ), dbfields, { noValidateToken: true });
            Oracle.Execute(bezUpd.sql);

            var beztrack = api2.process_includes(params, this, jsondata, the_key);

            // TODO: Tracking
            // Merk op dat beztrack helemaal niet zinvol gevuld is.
            //var result = saveBezoekers(afspr_key, -1, { urole: urole, loctimechanged: changed });
            //if (result.beztrack && result.beztrack.length > 0)
            //bezUpd.trackarray.push(result.beztrack.join("\n"));
            if (bezUpd && bezUpd.trackarray && (bezUpd.trackarray.length)) {
                bez.trackafspraakupdate(the_key, L("lcl_bez_is_bezupdtrack").format(the_key) + "\n" + bezUpd.trackarray.join("\n"));
            }

            return { key: the_key };
        };

    this.REST_POST = function (params, jsondata) /* new appointment */
        {
            params.isNew = true; // negeer eventuele bestaande keys

            var dbfields = api2.update_fields(params, this, jsondata); // Build updater
            this._validate_fields(dbfields, params, jsondata);

            dbfields["id"] = { dbs: "bez_afspraak_key",      typ: "key",     seq: "bez_s_bez_afspraak_key" };
            dbfields["contact"] = { dbs: "bez_afspraak_contact_key", typ: "key",  val: jsondata.contact || user_key };
            // trigger doet de host eventueel wel

            var bezIns = buildInsert("bez_afspraak", dbfields, { noValidateToken: true });
            var afs_key = bezIns.sequences["bez_afspraak_key"];
            Oracle.Execute(bezIns.sql);

            var beztrack = api2.process_includes(params, this, jsondata, afs_key);

            shared.trackaction("BEZMUT", afs_key); // Er bestaat geen echte BEZNEW tracking

            return { key: afs_key };
        };

    this.REST_DELETE = function (params, the_key) /* delete appointment */
        {
            var wheres = [" bez_afspraak_key = " + the_key];
            wheres.push("(bez_afspraak_contact_key = " + user_key // Altijd fe vooralnog
                               + "     OR bez_afspraak_host_key = " + user_key + ")");
            var sql = "DELETE FROM bez_afspraak"
                    + " WHERE " + wheres.join(" AND " );

            Oracle.Execute(sql);
            // Geen tracking (mogelijk) omdat het record echt is verwijderd
        };
}
%>