Pregunta
Kurro Lopez · Mayo 22, 2019

¿Cómo eliminar un item de una producción por código?

Hola a todos,

Estoy intentado eliminar un item de una producción a través de una rutina que instala y deshabilita items.

Para añadir no tengo problemas, incluso para habilitar y deshabilitar algunos items en particular.

El problema me surge cuando intento eliminar el item de la producción, porque cuando lo hace, la producción se queda inestable y solo vuelve a funcionar cuando se añade nuevamente este item en la colección (o se elimina de forma manual el item en el fichero produccion.cls

 

Este es mi intento de código:

set produccionName="MyApp.production"

set itemDelete = "MyApp.BP.item"

if ##class(Ens.Config.Item).NameExists(produccionName,itemDelete, .idItem)
{
    write !,"Removing BP: "_itemDelete
    set objItem=##class(Ens.Config.Item).%OpenId(idItem)
    do objItem.%Delete()
    kill objItem

   do ##class(Ens.Director).RestartProduction(0,1)
}

En el mejor de los casos, no hace nada y el item se mantiene. He probado también usando directamente el método %DeleteId() y algunas funciones de la clase Ens.Config.Production como RemoveItem

¿Alguna idea?

 

Un gran saludo,

Francisco López

 

 

00
2 0 5 111

Respuestas

Hay que retocar multiples clases para manipular una producción:

Hay que cargar la definición del XML, manipular esta definición y volver a grabar los cambios al XML.

Aquí un ejemplo:

ClassMethod Remove(pProdName, pItemName) As %Status
{
  #DIM tSC as %Status=$$$OK
  #DIM errObj as %Exception.AbstractException
  try {
  //Copy Production XData Content to the Ens.Config.Production and Save
  $$$THROWONERROR(tSC,##class(Ens.Config.Production).LoadFromClass(pProdName))

  set tProdConfig=##class(Ens.Config.Production).%OpenId(pProdName)
  if (tProdConfig="") {
    $$$ThrowStatus($$$ERROR($$$GeneralError,"No se ha encontrado la Configuración de producción "_pProdName))
  }
  for tIx=tProdConfig.Items.Count():-1:1 {  //Reverse Scan to Avoid skipping Item after remove
    set tItem=tProdConfig.Items.GetAt(tIx)
    if (tItem.Name=pItemName) {
      //---Remove Item from Production Configuration
      Do tProdConfig.Items.RemoveAt(tIx) 
      Do ##class(Ens.Config.Item).%DeleteId(tItem.%Id())
    }
  }
  // update production class
  $$$THROWONERROR(tSC,tProdConfig.SaveToClass())
  //Recompile Class
  do $SYSTEM.OBJ.Compile(pProdName,"f")
  //Update or Restart Production
  do ##class(Ens.Director).UpdateProduction()
  }catch(errObj) {
    set tSC=errObj.AsStatus()
  }
  quit tSC
}

wow... tengo que probarlo, tiene muy buena pinta

Lo utilizo en una herramienta adhoc de gestión de despliegues de Integración; permite borrar / añadir nuevos componentes a una producción en funcionamiento, y configurarlos con sus parametros que pueden ser distintos en los entornos test / prod.

Probado, implementado y funcionando... una gran idea

Te importaría realizar la misma respuesta en el community en inglés, hasta que no se implememte la funcionalidad de traducir las respuestas aceptadas, hay que estar hacíendolo así. De esta forma quedará registrado en ambos foros, y la solución es muy buena.

https://community.intersystems.com/post/how-delete-item-production-code

Muchas gracias

Aqui otra solución mucho más sencilla

/// Elimina un item de la producción
ClassMethod ProductionItemRemove(pProdName, pItemName) As %Status
{
    write !,"Removing Item: "_pItemName

   if ##class(Ens.Config.Item).NameExists(pProdName, pItemName,.itemId)

    {
        set objItem=##class(Ens.Config.Item).%OpenId(itemId)
        set prod=##class(Ens.Config.Production).%OpenId(pProdName)
        do prod.RemoveItem(objItem)
        do prod.%Save()
        
        kill objItem
    
        do ##class(Ens.Director).RestartProduction(0,1)
    }
    
    quit $$$OK
}

Un saludo,

Francisco López