0 votes

Hi all,

Sorry in advance for this big text :

I customized the PRODUCTS Table (split in 2 entities)
- PRODUCTS = products with FAMILY <> 1
- MISSIONS = products with FAMILY = 1

A Mission Contains some Products (stored in PRODPROD where KPRODUCT is the Missions and K_PRODUCT2 is the Product)

I customized TabContentProds too. The "AddRelationButton" have to link a "Mission" and no more a "Product" (to trigger the workflow event OnInsertDetailOppoMiss)
1. Click the "Add" button
2. The search Window appears (Mission Tab is selected) and click on the Mission
3. Efficy link the mission and call the Workflow OnInsertDetailOppoMiss
4. The Workflow get the Key of the mission and links its Products and Efficy refresh the Edit Window and the Context

After a few search it seems that Efficy don't refresh properly the EditHandle. You can find below the Workflow and the Customs.
The problem is that the Products appears on the page, but not the Missions
The GetRelationGrid tag have "entity=Prod" BUT, because the Products and the Missions are both stored in the PRODUCTS table, the ProdOppo SYSTABLEVIEWS can get all of them order by KSORT. This TABLEVIEWS return all the record in PRODOPPO with the specified K_OPPORTUNITY

I think that Efficy don't refresh correctly the EditHandle because of 2 reasons :

  1. If you click the Save button and reopen, or if you click the "apply" button, the Mission appear
  2. If you add the "Database.CommitChanges(EditHandle, true)" in the workflow, the handle is correctly refresh and the Missions appears on the page, bu if you use "Database.CommitChanges(EditHandle, false)" I have the same issue

Do anyone know why ? This grid use the SYS_TABLEVIEWS to load data ?


TabContentProds.Oppo, TabContentProds.Docu {[
    <div class="content tabs-content-item" id="tab-prod">
        <div class="row">
            <div class="small-12 medium-1 columns">
            <button type="button" class="icon i-add <%IfReadOnly(detail='Prod', then='disabled')%>" title="<%GetLabel('Add Link to Mission')%>" data-msg="addMission"></button>
            <div class="small-12 medium-11 columns">
                <h3 class="section-title"><%GetLabel("Linked missions")%></h3>
        <%OnMultiCurrency(0=, else=|<div id="currcyError"><span class="error"><%GetLabel("Warning: The currency must be set before adding products")%></span></div>|)%>

The Workflow :

var ntMiss = 50;

function OnInsertDetailOppoMiss(EditHandle, Detail, DetailKey) {
  Logger.Write('OnInsertDetailOppoMiss ' + DetailKey);
  InsertBatchChildren(EditHandle, Detail, DetailKey);
  DebugDataSet(EditHandle, Detail, DetailKey);
function DebugDataSet(EditHandle, Detail, DetailKey) {
    Logger.Write('\n\n===============   DEBUGGING   ===============')
    var dataset = Database.GetDetailDataSet(EditHandle, ntProd);
    Logger.Write('filter = ' + dataset.Filter);

    while(!dataset.EoF) {
        var k_product = dataset.FieldByName('K_PRODUCT').AsFloat,
                k_relation = dataset.FieldByName('K_RELATION').AsFloat,
                k_lot = dataset.FieldByName('F_LOT').AsFloat,
                name = dataset.FieldByName('NAME').AsString;

        Logger.Write(name + ' | k_product='+k_product + ' | k_relation='+k_relation + ' | k_lot='+k_lot);
function InsertBatchChildren(EditHandle, Detail, BatchKey) {
    //Database.UpdateDetail(EditHandle, ntMiss, 0, -1, "K_PRODUCT", BatchKey);
    Database.UpdateDetail(EditHandle, ntMiss, 0, -1, "F_LOT", 0);

  /*** DEFINE K_SORT ***/
  // get all products
  var prodDS = Database.GetDetailDataSet(EditHandle, ntProd);

  // Filter dataset on Batch
  FilterDataSet(prodDS, 'FAMILY=1');

  // Get new K_SORT
  var customKSort=GetNewKSort(EditHandle, prodDS, 100);
  Database.UpdateDetail(EditHandle, ntMiss, 0, -1, "K_SORT", customKSort); // define Batch K_SORT

   * https://help.efficy.com/edn/serverjs#Efficy-updateDetail
   * DetailKey = 0 indicates to UpdateDetail to use the "current detail records" ( => InsertDetail which trigger the OnInsertDetailXXXXyyyy event)
   * If the dataset filer is cleared before,
   *  the "current detail records" (which will be used by UpdateDetail)
   *  become the last detail used in GetNewKSort

  var queryHandle = 0,
        batchConsult = Database.OpenConsultContext(ntMiss)

  try {
    // Get batch children
    var childrenDS = Database.ConsultDetail(queryHandle, batchConsult, BatchKey, ntProd, true, true, 0);

    // Insert each of them
      while (!childrenDS.Eof) {
        var k_product = childrenDS.fieldByName("K_PRODUCT2").AsFloat,
                name = childrenDS.fieldByName("NAME").AsString;

        Database.InsertDetail(EditHandle, ntProd, k_product, -1, false);                // insert Batch child on Document
        Database.UpdateDetail(EditHandle, ntProd, 0, -1, "NAME", name);                 // define child NAME
        Database.UpdateDetail(EditHandle, ntProd, 0, -1, "F_LOT", BatchKey);        // define child F_LOT

  finally {
function GetNewKSort(EditHandle, DataSet, Incrementor) {
  var sortKey=0;

  // Loop on Batch to increment K_SORT
  if(!DataSet.IsEmpty) {
    while(!DataSet.Eof) {
      sortKey+=Incrementor; // increment of 100 for each Batch already linked (not necessarily commited in the DB)

  Logger.Write('New K_SORT='+sortKey);
  return sortKey;
function FilterDataSet(DataSet, FilterStr) {
  // unfilter
  if (DataSet.Filter != "") {

  if(DataSet && FilterStr) {
    var CleanFilter = decodeURIComponent(FilterStr).replace(/=/gi, "=").replace(/</gi, "<").replace(/>/gi, ">")
    DataSet.Filtered = false
    if (CleanFilter != "") {
      DataSet.Filter = CleanFilter
      DataSet.FilterOptions = 1
      DataSet.Filtered = true
asked in Efficy/ Client side by (245 points)
edited by

Please log in or register to answer this question.

1,167 questions
1,425 answers
325 users