+1 vote

Hello Efficy Team,

I got a complex process where I need to do something with the "new element" of a detailDataSet, or the deleted elements of the detailDataSet during the edit context.

What is the best way retrieve only those element ?

Here is what I did :

    var k_project = Efficy.getEditKey(editHandle);
var relationTable = Efficy.entityCatalog.getRelationEntityTableName(ntProj, TEntityHandle);
var kElement = Efficy.entityCatalog.keyFieldName(TEntityHandle);

var dsDetails = Efficy.sqlQueryDataSet('select * from ' + relationTable + ' where k_project = :param1', k_project, 45);
var newDetails = Efficy.getDetailDataSet(editHandle, TEntityHandle);

var changesInTheEditContext = [];

if(dsDetails || !dsDetails.isEmpty()) {

    // the project is already committed. We need to get only the "new" one
    // for that, we filter the "new one" based on the "old one"

    var existing = [];
    dsDetails.first();
    while (!dsDetails.eof()) {
        existing.push(dsDetails.fieldByName(kElement).asFloat);
        dsDetails.next();
    }

    // ho yeah it is ugly. But seems that "not in ()" does not work
    newDetails.filter = kElement +' <> ' + existing.join(' AND ' +  kElement +  ' <> ');
    newDetails.FilterOptions = existing.length;
    newDetails.Filtered = true;

}

// then we get, for each "new one", useful information's : entity, key, name

if(newDetails.isEmpty() || !newDetails) return false;
newDetails.first();

while(!newDetails.eof()) {

    changesInTheEditContext.push({
        entity : Efficy.entityCatalog.getEntityName(TEntityHandle),
        key : newDetails.fieldByName(kElement).asFloat,
        name : getName(newDetails.fieldByName(kElement).asFloat, TEntityHandle),
        operation : 'add'
    })

    newDetails.next();
}

newDetails.Filtered = false;

// we also need to detect the opposite : a contact deleted during the edit context
// we use the same ticks, but in the opposite (current detailDataSet filter the SQL)

if(dsDetails || !dsDetails.isEmpty()) {

    var fromRelationTable = [];

    newDetails.first();
    while (!newDetails.eof()) {

        fromRelationTable.push(newDetails.fieldByName(kElement).asFloat);
        newDetails.next();

    }

    // ho yeah it is ugly. But seems that "not in ()" does not work
    dsDetails.filter = kElement +' <> ' + fromRelationTable.join(' AND ' +  kElement +  ' <> ');
    dsDetails.FilterOptions = fromRelationTable.length;
    dsDetails.Filtered = true;

    if(dsDetails.isEmpty() || !dsDetails) return false;
    dsDetails.first();

    while(!dsDetails.eof()) {

        changesInTheEditContext.push({
            entity : Efficy.entityCatalog.getEntityName(TEntityHandle),
            key : dsDetails.fieldByName(kElement).asFloat,
            // name : getName(newDetails.fieldByName(kElement).asFloat, TEntityHandle), -- we don't need the name, he's already displayed
            operation : 'delete'
        })

        dsDetails.next();
    }

    dsDetails.Filtered = true;

}

return changesInTheEditContext;

Is there, by any chance, a way to get those change in a more "Efficy way" than comparing two dataSet ?

Regards,

Loïc

asked in WorkFlow / Serverscript by (531 points)

2 Answers

0 votes
Best answer

I might worst a suggestion to the R&D in my opinion. Something like"TDataSet.getChanges()" or "Efficy.getChangeDataSet(editHandle, TEntityHandle)"

I really would like to get rid of this SQL query.

Regards,

Loïc

answered by (531 points)
selected by
Interesting suggestions should preferrably be created as an Incident in Efficy (type suggestion) and with a detailed description of what the tag or method should return.

I do support the suggestion!
0 votes

Hi Loic,

If it's in the before commit, you could make a function which uses the Efficy.fieldModified()
and return the field name and the result of the the function.

Then you make a query on sys_fields to get the field names, and pass them to the function you've created.

Kr,

answered by (147 points)
1,249 questions
1,519 answers
1,859 comments
328 users