1.17.Guardando las modificaciones de los nodos


Llegamos al final de los post del formulario Gantt. Durante estos post habréis aprendido un poco el funcionamiento de dicho formulario y como modificarlo.
Como podéis imaginar no está todo explicado ni lo explicado está perfecto, pero es suficiente para entender el funcionamiento.

El último paso será salvar las modificaciones que realizamos en nuestro nodos, supongo que si habéis probado a modificar algún nodo os habréis dado cuenta que los datos no se guardan y eso es porque no le dimos funcionalidad.

Para guardar los cambios deberemos realizar las siguientes modificaciones:


En la clase XBB_GanttActiveXVarchart_SchedEmpl añadiremos el siguiente método. Éste nos guardará nuestras modificaciones en una tabla hasta que decidamos si guardar o no los cambios.


protected boolean insertVcNodeModification(GanttDataModification _ganttDataModification,
                                                                            boolean                        _alwaysInsertModification = false,
                                                                            boolean                        _validateModification = true)
{
      boolean ret = this.validateModification(_ganttDataModification);


      if(_ganttDataModification && (!_validateModification || ret))

      {
           this.insertModification(_ganttDataModification);
      }
      else

      {
          if (ret)

          {
               this.ganttDataModificationCollection().parmAllModificationsPassedValidation(false);


               if(_alwaysInsertModification)

               {
                   this.insertModification(_ganttDataModification);
               }
          }
      }

    return ret;

}




El siguiente método lo anularemos, en él podemos ver que tenemos acceso a los datos nuevos y antiguos del nodo.


public  void onEvent_OnNodeModifyEx(COM _oldNode, COM _node, int _modificationType, COMVariant _returnStatus)
{
        GanttVcNode ganttVcNodeOld  = GanttVcNode::newVcNode(_oldNode);
        GanttVcNode ganttVcNodeNew = GanttVcNode::newVcNode(_node);
        

        COMVariant variantStartDate;
         

        GanttDataModification ganttDataModification;

        try

       {

              // move the node to the start position in order to make sure that we reschedule correctly

              variantStartDate = ganttVcNodeNew.getFieldValue(this.fieldNameSchedFromDate(), ganttVcGantt);
              ganttDataModification = ganttVcNodeNew.createModificationByOldNode(ganttVcNodeOld, ganttVcGantt, GanttModificationAction::Update, this.parmSetExcludeFieldNames());

              if(ganttDataModification == null)

              {
                  throw error("@SYS6144");

              }

              // Modification must always be inserted even though it failed validation.

              // This way we can roll it back later in the onEvent_OnNodeModifyCompleteEx event.
              // Validation is performed in the case that the delayValidateModifications is not set
              if (this.insertVcNodeModification(ganttDataModification, false, !delayValidateModifications))
              {
                     // Always set the status to OK in order to reach onEvent_OnNodeModifyCompleteEx event

                     // where ganttDataModificationCollection should be reset.
                     this.setReturnStatusOK(_returnStatus);
              }
              else

              {
                     this.setReturnStatusFalse(_returnStatus);
              }
     }
     catch(Exception::Error)

     {
           this.ganttDataModificationCollection().parmAllModificationsPassedValidation(false);


           if(ganttDataModification)

           {
                   this.insertModification(ganttDataModification);
                   this.setReturnStatusOK(_returnStatus);
           }
           else

           {
                  this.setReturnStatusFalse(_returnStatus);
           }

           throw Exception::Error;
   }
}


En nuestra clase XBB_Ganttdata_SchedEmpl  crearemos el siguiente método el cual se recorrerá

todos los registros que han sido modificados para realizar los cambios.


protected 
void saveData(

       boolean         _onlyValidate = false
       boolean         _skipValidation = true)
{
       Set                            setRecIdsToBeSaved = new Set(Types::Int64);
       

       SetEnumerator         setEnumerator;
     

       XBB_GanttTmpSchedEmpl ganttTmpSchedEmpl;

       
super();


       if(_onlyValidate)
     
       {
             this.progressInitValidating();
       }
       else
       
       {
             this.progressInitSaving();
       }

       setRecIdsToBeSaved = ganttTable_SchedEmpl.parmSetUserModifiedRecIds();
       setEnumerator            = setRecIdsToBeSaved.getEnumerator();
       this.progressTotal(setRecIdsToBeSaved.elements());

       while(setEnumerator && setEnumerator.moveNext())
     

       {
              ganttTable_SchedEmpl.findRecId(setEnumerator.current(), true);

              ganttTmpSchedEmpl = ganttTable_SchedEmpl.parmTableBuffer();

              if(!_skipValidation && !ganttTable_SchedEmpl.validateWrite())

              {
                   throw Exception::Error;
             

              }

              XBB_GanttData_SchedEmpl::updateOrigData(ganttTmpSchedEmpl, _onlyValidate);

              this.progressUpdate();
       }

       this.progressFinish();
}



El método updateOrigData es el más importante en él actualizaremos los datos de la tabla PSASchedEmplReservation en base a nuestra tabla temporal del Gantt.

Nota: Id con cuidado a la hora de actualizar los datos si tenéis agrupaciones; pues en el caso de arrastrar un nodo que viene de una agrupación hacía otro donde no la hay, tendréis problemas y los datos no se actualizarán correctamente.


protected 
static server void updateOrigData(
     XBB_GanttTmpSchedEmpl   _ganttTmpSchedEmpl,     
     boolean                                   _onlyValidate = false)
{
     PSASchedEmplReservation PSASchedEmplReservation;

     PSASchedEmplReservation = PSASchedEmplReservation::findRecId(_ganttTmpSchedEmpl.PSASchedEmplReservationRecId, true);


     if (!PSASchedEmplReservation.RecId)
     {
        throw error(strfmt("@SYS115421",   PSASchedEmplReservation.ActivityNumber));
     }

     PSASchedEmplReservation.ActivityNumber = ganttTmpSchedEmpl.ActivityNumber;
     PSASchedEmplReservation.EndTime            = _ganttTmpSchedEmpl.EndTime;
     PSASchedEmplReservation.ProjId                 = _ganttTmpSchedEmpl.ProjId;
     PSASchedEmplReservation.StartTime           = _ganttTmpSchedEmpl.StartTime;
     PSASchedEmplReservation.TransDate          = _ganttTmpSchedEmpl.StartDate;
     PSASchedEmplReservation.Worker               = HcmWorker::findByPersonnelNumber(_ganttTmpSchedEmpl.PersonnelNumberId).RecId;

     if (!_onlyValidate)
   
     {
            PSASchedEmplReservation.update();
     }
}


Para finalizar agregaremos dos botones en nuestro formulario: uno para guardar los cambios y el otro para deshacer los cambios.

El botón deshacer irá deshaciendo uno por uno todos los cambios realizados (uno cada vez que presionemos el botón).







El código para el método clicked de nuestro botón save será el siguiente:


void clicked()
{     

       super();      
     
       ganttClient.save();
 }



Y para el undo el que sigue:


void clicked()
{     

       super();

      ganttClient.undo();
}



El los métodos del formulario anularemos el método close y añadiremos el siguiente código (indicado más abajo). Éste lo que hará es que si cerramos el formulario sin guardar los cambios nos preguntará si deseamos guardarlos.


public void close()
{
      // If changes are not saved, a confirmation dialog is shown
      if (ganttClient.canUndo() && Box::yesNo("@SYS136819", DialogButton::Yes) == DialogButton::Yes)
     {
           ganttClient.save();
     }

     super();

     ganttClient.parmGanttVisualization().close();
}



Aquí teneis el xpo final con todo el proyecto que hemos ido realizando a través de estos post.


Comentarios