Error: Record on parent tab was changed by another user, please navigate to tab and ReQuery:

98 views
Skip to first unread message

shiju01

unread,
Jun 25, 2018, 2:03:01 AM6/25/18
to iDempiere
Dear Community

Need to total the LineQty in line and update TotalQty in parent tab whenever the line is modified

Wrote  following AfterSave to do this  and it works fine but if after updated one line and navigated to next line

the error will be generated

Error: Record on parent tab was changed by another user, please navigate to tab and ReQuery:

forcing the user to navigate to the header tab each time after updating any line before going for updating next line

Any solution to auto - refresh the header tab after it gets pro-grammatically updated  


protected boolean afterSave (boolean newRecord, boolean success)
    {
        if (!success)
            return success;
        if (is_ValueChanged("PlannedQty"))
        {
            BigDecimal plannedqty = BigDecimal.ZERO;
 
             int p_M_DistributionList_ID = this.getM_DistributionList_ID();
            MDistributionList drplist = new MDistributionList(getCtx(),p_M_DistributionList_ID,get_TrxName());
            MDistributionListLine[] drplstlines = drplist.getLines();

            for (int i = 0; i < drplstlines.length; i++)
            {
                MDistributionListLine drplstline = drplstlines[i];

                plannedqty = plannedqty.add(drplstline.getPlannedQty());
            }    // for

            drplist.setPlannedQty(plannedqty);
            success=drplist.save(get_TrxName());
        }       
        return success;
    }    //    afterSave
   



Nicolas Micoud

unread,
Jun 25, 2018, 2:53:11 AM6/25/18
to iDempiere
Hi,

The message appears when the value of column updated changed in DB.

I faced same issue some times ago and i use this workaround :

private static void updateFieldOnParentTab(Properties ctx, int parentTabID, String trxName) {
        if (parentTabID > 0) {
            X_Class parentTabObject = new X_Class(ctx, parentTabID, trxName);

            Timestamp oldUpdated = parentTabObject.getUpdated();
            parentTabObject.set_Value(...);
            if (parentTabObject.save())
                DB.executeUpdateEx("UPDATE ParentTable SET Updated = " + DB.TO_DATE(oldUpdated, false) + " WHERE ParentTable_ID = " + parentTabID, parentTabObject.get_TrxName());
        }
    }

Nicolas

shiju01

unread,
Jun 25, 2018, 6:53:34 AM6/25/18
to iDempiere
Dear Nicolas

Thank You!

It Worked, only X_Class will work not M_Class

Any change in the line qty seamless totaled and updates to header tab

Pasted the code for any reference


/******************************************************************************
 * Product: Adempiere ERP & CRM Smart Business Solution                       *
 * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.                *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program is distributed in the hope   *
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.           *
 * See the GNU General Public License for more details.                       *
 * You should have received a copy of the GNU General Public License along    *
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.                     *
 * For the text or an alternative of this public license, you may reach us    *
 * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA        *
 * or via in...@compiere.org or http://www.compiere.org/license.html           *
 *****************************************************************************/
package org.compiere.model;
 
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.Properties;
import java.util.logging.Level;
 
import org.compiere.util.DB;
import org.compiere.util.Env;
 
 
/**
 *    Distribution List Line
 *     
 *  @author Jorg Janke
 *  @version $Id: MDistributionListLine.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $
 */
public class MDistributionListLine extends X_M_DistributionListLine
{
    /**
     * 
     */
    private static final long serialVersionUID = -8227610572847013425L;
 
    /**
     *     Standard Constructor
     *    @param ctx context
     *    @param M_DistributionListLine_ID id
     *    @param trxName transaction
     */
    public MDistributionListLine (Properties ctx, int M_DistributionListLine_ID, String trxName)
    {
        super (ctx, M_DistributionListLine_ID, trxName);
    }    //    MDistributionListLine
 
    /**
     *     Load Constructor
     *    @param ctx context
     *    @param rs result set
     *    @param trxName transaction
     */
    public MDistributionListLine (Properties ctx, ResultSet rs, String trxName)
    {
        super(ctx, rs, trxName);
    }    //    MDistributionListLine
     
     
    
 
    /**
     *     Called after Save for Post-Save Operation
     *     @param newRecord new record
     *    @param success true if save operation was success
     *    @return if save was a success
     */
    protected boolean afterSave (boolean newRecord, boolean success)
    {
        if (!success)
            return success;
         
        if (is_ValueChanged("PlannedQty") || 
            is_ValueChanged("CancelledQty") || 
            is_ValueChanged("QtyOrdered") || 
            is_ValueChanged("QtyInTransit") ||  
            is_ValueChanged("QtyDelivered") || 
            is_ValueChanged("ConfirmedQty") || 
            is_ValueChanged("DifferenceQty") 
            )
            summarize(getCtx(), this.getM_DistributionList_ID(), get_TrxName());
 
        return success;
    }    //    afterSave
     
    private static void  summarize(Properties ctx, int p_M_DistributionList_ID, String trxName) {
         
        if (p_M_DistributionList_ID > 0) 
        {
            BigDecimal plannedqty = BigDecimal.ZERO;
            BigDecimal cancelledqty = BigDecimal.ZERO;
            BigDecimal qtyordered = BigDecimal.ZERO;
            BigDecimal qtyintransit = BigDecimal.ZERO;
            BigDecimal qtydelivered = BigDecimal.ZERO;
            BigDecimal confirmedqty = BigDecimal.ZERO;
            BigDecimal differenceqty = BigDecimal.ZERO;
            //
            BigDecimal targetqty = BigDecimal.ZERO;
            BigDecimal totalqty = BigDecimal.ZERO;
     
            X_M_DistributionList parent = new X_M_DistributionList(ctx, p_M_DistributionList_ID, trxName);
            MDistributionList mparent = new MDistributionList(ctx, p_M_DistributionList_ID, trxName);
            MDistributionListLine[] drplstlines = mparent.getLines();
            for (int i = 0; i < drplstlines.length; i++)
            {
                MDistributionListLine drplstline = drplstlines[i];
                    
                plannedqty = plannedqty.add(drplstline.getPlannedQty());
                cancelledqty = cancelledqty.add(drplstline.getCancelledQty());
                qtyordered = qtyordered.add(drplstline.getQtyOrdered());
                qtyintransit = qtyintransit.add(drplstline.getQtyInTransit());
                qtydelivered = qtydelivered.add(drplstline.getQtyDelivered());
                confirmedqty = confirmedqty.add(drplstline.getConfirmedQty());
                differenceqty = differenceqty.add(drplstline.getDifferenceQty());
            }    // for
 
            parent.set_ValueOfColumn(COLUMNNAME_PlannedQty, plannedqty);
            parent.set_ValueOfColumn(COLUMNNAME_CancelledQty, cancelledqty);
            parent.set_ValueOfColumn(COLUMNNAME_QtyOrdered, qtyordered);
            parent.set_ValueOfColumn(COLUMNNAME_QtyInTransit, qtyintransit);
            parent.set_ValueOfColumn(COLUMNNAME_QtyDelivered, qtydelivered);
            parent.set_ValueOfColumn(COLUMNNAME_ConfirmedQty, confirmedqty);
            parent.set_ValueOfColumn(COLUMNNAME_DifferenceQty, differenceqty);
            
            Timestamp oldUpdated = parent.getUpdated();                 
 
            if (parent.save())
                DB.executeUpdateEx("UPDATE M_DistributionList SET Updated = " + DB.TO_DATE(oldUpdated, false) + " WHERE M_DistributionList_ID = " + p_M_DistributionList_ID, parent.get_TrxName());
        }    // if (p_M_DistributionList_ID > 0)
        
    }    // summarize
 

    /**
     *     Executed after Delete operation.
     *     @param success true if record deleted
     *    @return true if delete is a success
     */
    protected boolean afterDelete (boolean success)
    {
        if (!success)
            return success;
     
        summarize(getCtx(), this.getM_DistributionList_ID(), get_TrxName());
         
/*
 * 
//        {
//            String total_sql = " UPDATE M_DistributionList dl "
//            + " SET ( PlannedQty, CancelledQty, QtyOrdered, QtyInTransit, QtyDelivered, ConfirmedQty, DifferenceQty ) = "
//            + "( SELECT SUM(PlannedQty), SUM(CancelledQty), SUM(QtyOrdered), SUM(QtyInTransit), SUM(QtyDelivered), SUM(ConfirmedQty ), SUM(DifferenceQty) "
//            + " FROM M_DistributionListLine dll WHERE dl.M_DistributionList_ID=dll.M_DistributionList_ID ) "
//            + " WHERE dl.M_DistributionList_ID = " + getM_DistributionList_ID() ;
//            int no = DB.executeUpdateEx(total_sql, get_TrxName());
//            if (log.isLoggable(Level.FINE)) log.fine("Distribution Lines totalled -> #" + no);
//        }     
 * 
*/         
        return success;
    }     //    afterDelete
 
}    //    MDistributionListLine










Nicolas Micoud

unread,
Jun 25, 2018, 7:24:36 AM6/25/18
to iDempiere
Hi,

Happy it also worked for you !

Wondering if this kind of method can be put in the trunk - as it seems it can be used in several use cases ?

shiju01

unread,
Jun 25, 2018, 9:20:08 AM6/25/18
to iDempiere

Awaiting the attention of  Carlos or
hengsin 

Heng Sin Low

unread,
Jun 25, 2018, 4:47:42 PM6/25/18
to idem...@googlegroups.com
Move it to beforeSave

--
You received this message because you are subscribed to the Google Groups "iDempiere" group.
To unsubscribe from this group and stop receiving emails from it, send an email to idempiere+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/idempiere/a5299ded-371f-4e3c-8894-284fe99fd96d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages