function createDataset(fields, constraints, sortFields) {
    var ds = DatasetBuilder.newDataset();
    ds.addColumn("documentid");
    ds.addColumn("dataAuditoria");
    ds.addColumn("dataLimite");
    ds.addColumn("ciclo");
    ds.addColumn("auditor");
    ds.addColumn("usuarioRetorno");
    ds.addColumn("responsavelLoja");
    ds.addColumn("loja");
    ds.addColumn("regional");
    ds.addColumn("saidaAnalise");
    ds.addColumn("status");
    ds.addColumn("qtdNaoConforme");
    ds.addColumn("listaNaoConforme");

    try {
        var filtros = parseConstraints(constraints);
        var formDs = DatasetFactory.getDataset("checklist", null, null, null);
        if (!formDs || formDs.rowsCount < 1) {
            return ds;
        }

        var linhas = [];

        for (var i = 0; i < formDs.rowsCount; i++) {
            var status = val(formDs, i, "saidaAnalise").toUpperCase();
            if (status !== "CONFORME" && status !== "NAO_CONFORME") {
                continue;
            }

            var dataAuditoria = val(formDs, i, "dataAuditoria");
            var dataLimite = val(formDs, i, "dataLimite");
            var ciclo = val(formDs, i, "ciclo");
            var regional = val(formDs, i, "regional");
            var loja = val(formDs, i, "loja");

            if (filtros.loja && norm(loja).indexOf(norm(filtros.loja)) === -1) {
                continue;
            }
            if (filtros.ciclo && norm(ciclo).indexOf(norm(filtros.ciclo)) === -1) {
                continue;
            }
            if (filtros.regional && norm(regional).indexOf(norm(filtros.regional)) === -1) {
                continue;
            }
            if (filtros.dataInicio || filtros.dataFim) {
                var faixaAuditoria = dataNaFaixa(dataAuditoria, filtros.dataInicio, filtros.dataFim);
                var faixaLimite = dataNaFaixa(dataLimite, filtros.dataInicio, filtros.dataFim);
                if (!faixaAuditoria && !faixaLimite) {
                    continue;
                }
            }

            linhas.push({
                documentid: val(formDs, i, "documentid"),
                dataAuditoria: dataAuditoria,
                dataLimite: dataLimite,
                ciclo: ciclo,
                auditor: val(formDs, i, "auditor"),
                usuarioRetorno: val(formDs, i, "usuarioRetorno"),
                responsavelLoja: val(formDs, i, "responsavelLoja"),
                loja: loja,
                regional: regional,
                saidaAnalise: status,
                status: status,
                qtdNaoConforme: val(formDs, i, "qtdNaoConforme"),
                listaNaoConforme: val(formDs, i, "listaNaoConforme")
            });
        }

        linhas.sort(function (a, b) {
            if (a.dataAuditoria < b.dataAuditoria) return 1;
            if (a.dataAuditoria > b.dataAuditoria) return -1;
            if (a.documentid < b.documentid) return 1;
            if (a.documentid > b.documentid) return -1;
            return 0;
        });

        for (var j = 0; j < linhas.length; j++) {
            var r = linhas[j];
            ds.addRow([
                r.documentid,
                r.dataAuditoria,
                r.dataLimite,
                r.ciclo,
                r.auditor,
                r.usuarioRetorno,
                r.responsavelLoja,
                r.loja,
                r.regional,
                r.saidaAnalise,
                r.status,
                r.qtdNaoConforme,
                r.listaNaoConforme
            ]);
        }
    } catch (e) {
        ds = DatasetBuilder.newDataset();
        ds.addColumn("ERRO");
        ds.addRow([String(e)]);
    }

    return ds;
}

function parseConstraints(constraints) {
    var out = {
        dataInicio: "",
        dataFim: "",
        loja: "",
        ciclo: "",
        regional: ""
    };

    if (!constraints) return out;

    for (var i = 0; i < constraints.length; i++) {
        var c = constraints[i];
        if (!c) continue;

        var name = String(c.fieldName || c._field || "");
        var value = String(c.initialValue || c._initialValue || "").trim();
        if (!name || !value) continue;

        if (name === "dataInicio") out.dataInicio = value;
        if (name === "dataFim") out.dataFim = value;
        if (name === "loja") out.loja = value;
        if (name === "ciclo") out.ciclo = value;
        if (name === "regional") out.regional = value;
    }

    return out;
}

function val(ds, row, col) {
    var v = ds.getValue(row, col);
    return String(v == null ? "" : v).trim();
}

function norm(v) {
    return String(v || "").toLowerCase().trim();
}

function dataNaFaixa(data, inicio, fim) {
    var d = String(data || "").trim();
    if (!d) return false;
    if (inicio && d < inicio) return false;
    if (fim && d > fim) return false;
    return true;
}
