Código javascript para agregar líneas a formulario_ml en toba 3.4

Lo solucioné con ajax y javascript, pero queda muy improlijo porque el evento atender_respuesta() está vacío, lo único que hago es pasar el parámetro del id_empresa seleccionado y no envío ninguna respuesta el método javascript.
Este es el código del método ajax:

function ajax__cargar_empresa($parametros, toba_ajax_respuesta $respuesta)
{
	$this->s__id_empresa = $parametros['id_empresa'];
}

Y este es el código de la extensión del formulario:

<?php
class form_recibo extends sindicato_ei_formulario
{
	//-----------------------------------------------------------------------------------
	//---- JAVASCRIPT -------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function extender_objeto_js()
	{
		echo "
		//---- Procesamiento de EFs --------------------------------
		
		{$this->objeto_js}.evt__id_empresa__procesar = function(es_inicial)
		{
			var id_empresa = this.ef('id_empresa').get_estado();
			if(id_empresa != apex_ef_no_seteado) {
				var parametro = {'id_empresa': id_empresa};
				this.controlador.ajax('cargar_empresa', parametro, this, this.atender_respuesta);
			}
		}
		{$this->objeto_js}.atender_respuesta = function()
		{
		}
		";
	}

}
?>

Matias,

trate de explicarte que no es necesario en ppio que recurras a un evento de paso de tab, que el mismo viaje al servidor te propaga los datos del combo.

A esta altura ya estoy perdido sobre lo que queres lograr, pasteame como te quedo el codigo del CI (completo) asi te digo que podes reacomodar y que secuencia seria la que te convendria usar en lugar de recurrir al pedido ajax… de paso entiendo mejor que queres lograr.

Saludos

Este es el código del ci con los dos formularios en forma de tab horizontal:

<?php
class ci_edicion extends sindicato_ci
{
	protected $s__id_empresa;
	protected $s__datos_recibo;
	protected $s__total;
	protected $s__datos_aportes;

	function get_relacion()
	{
		return $this->controlador->get_relacion();
	}

	//-----------------------------------------------------------------------------------
	//---- formulario -------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function ajax__cargar_empresa($parametros, toba_ajax_respuesta $respuesta)
	{
		$this->s__id_empresa = $parametros['id_empresa'];
	}

	function conf__formulario(sindicato_ei_formulario $form)
	{
		if(!empty($this->s__datos_recibo)) $form->set_datos($this->s__datos_recibo);
		elseif($this->get_relacion()->tabla("recibos")->esta_cargada())
			$form->set_datos($this->get_relacion()->tabla("recibos")->get());
		elseif(!empty($this->s__total)) $form->ef('total')->set_estado($this->s__total);
	}

	function evt__formulario__modificacion($datos)
	{
		$this->get_relacion()->tabla("recibos")->set($datos);
	}

	//-----------------------------------------------------------------------------------
	//---- Configuraciones --------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function evt__recibo__salida()
	{
		$this->s__datos_recibo = $this->dep('formulario')->get_datos();
	}

	function evt__aportes__entrada()
	{
		if(!$this->get_relacion()->esta_cargada() && !empty($this->s__id_empresa)) {
			$id_empresa = quote($this->s__id_empresa);
			$sql = "select t_ap.id_aporte, t_ap.id_concepto, t_ap.importe from pendientes t_p "
				."inner join aportes_pendientes t_ap on t_p.id_pendiente=t_ap.id_pendiente where "
				."id_empresa=$id_empresa order by t_ap.id_aporte, t_ap.id_concepto";
			$datos = consultar_fuente($sql);
			$this->dep('formulario_ml')->set_datos($datos);
		}
	}

	function evt__aportes__salida()
	{
		$this->s__datos_aportes = $this->dep('formulario_ml')->get_datos();
	}

	//-----------------------------------------------------------------------------------
	//---- formulario_ml ----------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function ajax__get_importe($parametros, toba_ajax_respuesta $respuesta)
	{
		$id_aporte = quote($parametros['id_aporte']);
		$id_concepto = quote($parametros['id_concepto']);
		$sql = "select importe from aportes_pendientes where id_aporte=$id_aporte and "
			."id_concepto=$id_concepto";
		$aporte_pendiente = consultar_fuente($sql);
		$respuesta->set($aporte_pendiente);
	}

	function conf__formulario_ml(sindicato_ei_formulario_ml $form_ml)
	{
		if($this->get_relacion()->esta_cargada()) 
			return $this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true);
		elseif(!empty($this->s__datos_aportes))
			return $this->s__datos_aportes;
	}

	function evt__formulario_ml__modificacion($datos)
	{
		$this->get_relacion()->tabla("aportes_recibos")->procesar_filas($datos);
		$this->get_relacion()->sincronizar();
		$aportes_recibos = $this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true);
		foreach($aportes_recibos as $value)
		{
			$id_aporte = quote($value['id_aporte']);
			$id_concepto = quote($value['id_concepto']);
			$importe = $value['importe'];
			$sql = "select * from aportes_pendientes where id_aporte = $id_aporte and id_concepto = $id_concepto";
			$aporte_pendiente = consultar_fuente($sql);
			if(!empty($aporte_pendiente))
			{
				$id_aporte_pendiente = quote($aporte_pendiente[0]['id_aporte_pendiente']);
				$importe_pendiente = $aporte_pendiente[0]['importe'] - $importe;
				$sql = !empty($importe_pendiente) ? "update aportes_pendientes set importe = $importe_pendiente "
					."where id_aporte_pendiente = $id_aporte_pendiente" : "delete from aportes_pendientes "
					."where id_aporte_pendiente = $id_aporte_pendiente";
				$cant_ap = ejecutar_fuente($sql);
			}
		}
		$id_empresa = quote($this->s__id_empresa);
		$sql = "select p.id_pendiente, p.total, sum(ap.importe) as aporte from pendientes p left join "
			."aportes_pendientes ap on p.id_pendiente = ap.id_pendiente where p.id_empresa = $id_empresa "
			."group by p.id_pendiente, p.total";
		$pendientes = consultar_fuente($sql);
		foreach($pendientes as $value)
		{
			$id_pendiente = quote($value["id_pendiente"]);
			$total = $value["total"];
			$aporte = $value["aporte"];
			$pendiente = $total - $aporte;
			$sql_du = !empty($aporte) ? "update pendientes set total = $pendiente where "
				."id_pendiente = $id_pendiente" : "delete from pendientes where id_pendiente = $id_pendiente";
			$cant_p = ejecutar_fuente($sql_du);
		}
	}

	function evt__formulario_ml__procesar($datos)
	{
		$this->s__total = 0;
		foreach($datos as $value) $this->s__total += $value["importe"];
	}

}
?>

Y este es el código de la extensión del formulario para ejecutar el pedido ajax:

<?php
class form_recibo extends sindicato_ei_formulario
{
	//-----------------------------------------------------------------------------------
	//---- JAVASCRIPT -------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function extender_objeto_js()
	{
		echo "
		//---- Procesamiento de EFs --------------------------------
		
		{$this->objeto_js}.evt__id_empresa__procesar = function(es_inicial)
		{
			var id_empresa = this.ef('id_empresa').get_estado();
			if(id_empresa != apex_ef_no_seteado) {
				var parametro = {'id_empresa': id_empresa};
				this.controlador.ajax('cargar_empresa', parametro, this, this.atender_respuesta);
			}
		}
		{$this->objeto_js}.atender_respuesta = function()
		{
		}
		";
	}

}
?>

Hola Matias,

mirando el codigo me queda la sensacion que estas haciendo las cosas en mas de una ocasion y eso te esta generando inconvenientes, si me lo permitis te ofrezco una version alternativa de tu codigo

<?php
class ci_edicion extends sindicato_ci
{
	protected $s__id_empresa;
	protected $s__datos_recibo;
	protected $s__total;
	protected $s__datos_aportes;

	function get_relacion()
	{
		return $this->controlador->get_relacion();
	}

	//-----------------------------------------------------------------------------------
	//---- formulario -------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function ajax__cargar_empresa($parametros, toba_ajax_respuesta $respuesta)
	{
		$this->s__id_empresa = $parametros['id_empresa'];
	}

	function conf__formulario(sindicato_ei_formulario $form)
	{
		if(!empty($this->s__datos_recibo)) 
			$form->set_datos($this->s__datos_recibo);
		elseif($this->get_relacion()->tabla("recibos")->esta_cargada())
			$form->set_datos($this->get_relacion()->tabla("recibos")->get());
		elseif(!empty($this->s__total)) 
			$form->ef('total')->set_estado($this->s__total);
	}

	function evt__formulario__modificacion($datos)
	{
		$this->s__datos_recibo = $datos;
		$this->get_relacion()->tabla("recibos")->set($datos);
	}

	//-----------------------------------------------------------------------------------
	//---- Configuraciones --------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	/*function evt__recibo__salida()
	{
		$this->s__datos_recibo = $this->dep('formulario')->get_datos();
	}*/

	/*function evt__aportes__entrada()
	{
		if(! $this->get_relacion()->esta_cargada() && !empty($this->s__id_empresa)) {
			$this->dep('formulario_ml')->set_datos($this->get_datos_empresa($this->s__id_empresa));
		}
	}*/

	/*function evt__aportes__salida()
	{
		$this->s__datos_aportes = $this->dep('formulario_ml')->get_datos();
	}*/

	//-----------------------------------------------------------------------------------
	//---- formulario_ml ----------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function ajax__get_importe($parametros, toba_ajax_respuesta $respuesta)
	{
		$id_aporte = quote($parametros['id_aporte']);
		$id_concepto = quote($parametros['id_concepto']);
		$sql = "select importe from aportes_pendientes where id_aporte=$id_aporte and "
			."id_concepto=$id_concepto";
		$aporte_pendiente = consultar_fuente($sql);
		$respuesta->set($aporte_pendiente);
	}

	function conf__formulario_ml(sindicato_ei_formulario_ml $form_ml)
	{

		if($this->get_relacion()->esta_cargada()) 
			$form_ml->set_datos($this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true));
		elseif(!empty($this->s__datos_aportes))
			$form_ml->set_datos($this->s__datos_aportes);
		elseif (!empty($this->s__id_empresa))
			$form_ml->set_datos($this->get_datos_empresa($this->s__id_empresa));
	}

	function evt__formulario_ml__modificacion($datos)
	{

		$this->s__datos_aportes = $datos;		//Asegurate que el evt de modificacion en toba_editor este marcado como implicito

		$this->get_relacion()->tabla("aportes_recibos")->procesar_filas($datos);
		$this->get_relacion()->sincronizar();				//OJO aca ya estas impactando las tablas (independientemente de los updates inferiores)

		$aportes_recibos = $this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true);

		##
		# todo esto incluido el SINCRONIZAR previo deberia estar en una unica TRANSACCION MIRA EL AP!
		# de paso sumale un try/catch
		##
		foreach($aportes_recibos as $value)
		{			
			$aporte_pendiente = $this->get_pendientes($value['id_aporte'], $value['id_concepto']);
			if(!empty($aporte_pendiente))
			{
				$id_aporte_pendiente = quote($aporte_pendiente[0]['id_aporte_pendiente']);
				$importe_pendiente = $aporte_pendiente[0]['importe'] - $value['importe'];

				$sql = !empty($importe_pendiente) ? "update aportes_pendientes set importe = $importe_pendiente "
					."where id_aporte_pendiente = $id_aporte_pendiente" : "delete from aportes_pendientes "
					."where id_aporte_pendiente = $id_aporte_pendiente";
				$cant_ap = ejecutar_fuente($sql);
			}
		}

		$pendientes = $this->get_pendientes_x_empresa($this->s__id_empresa);
		foreach($pendientes as $value)
		{
			$id_pendiente = quote($value["id_pendiente"]);
			$pendiente = quote($value["total"] - $value["aporte"]);			
			$sql_du = !empty($value["aporte"]) ? "update pendientes set total = $pendiente where "
				."id_pendiente = $id_pendiente" : "delete from pendientes where id_pendiente = $id_pendiente";
			$cant_p = ejecutar_fuente($sql_du);
		}

		##
		# FIN DE LA TRANSACCION
		##


	}

	function evt__formulario_ml__procesar($datos)
	{
		/*
		 * Este evento se dispara por botonera?.. tene en cuenta que se va a disparar evt__formulario_ml__modificacion
         * si esta configurado como `implicito`, capaz te conviene hacer la cuenta directamente en el otro metodo
         */
		$this->s__total = 0;
		foreach($datos as $value) 
			$this->s__total += $value["importe"];
	}

	protected function get_datos_empresa($empresa)
	{
		$id_empresa = quote($empresa);
		$sql = "select t_ap.id_aporte, t_ap.id_concepto, t_ap.importe 
				  from pendientes t_p "
				."inner join aportes_pendientes t_ap on t_p.id_pendiente=t_ap.id_pendiente 
					where "
				."id_empresa=$id_empresa order by t_ap.id_aporte, t_ap.id_concepto";
		$datos = consultar_fuente($sql);
		return $datos;
	}

	protected function get_pendientes($aporte, $concepto)
	{
		$id_aporte = quote($aporte);
		$id_concepto = quote($concepto);
		$sql = "select * from aportes_pendientes where id_aporte = $id_aporte and id_concepto = $id_concepto";
		return consultar_fuente($sql);
	}

	protected function get_pendientes_x_empresa($empresa)
	{
		$id_empresa = quote($empresa);
		$sql = "select p.id_pendiente, p.total, sum(ap.importe) as aporte 
				from pendientes p left join "
			."aportes_pendientes ap on p.id_pendiente = ap.id_pendiente 
				where p.id_empresa = $id_empresa "
			."group by p.id_pendiente, p.total";
		return consultar_fuente($sql);
	}


}
?>

me faltan algunos datos sobre como estan configurados los eventos de los formularios en toba_editor.. pero creo que eso reflejaria el ciclo mas o menos.

Presta atencion particular a lo que menciono sobre la transaccion, si se te cae el pedido de pagina te va a quedar inconsistente la bd.

Saludos

Hola @richard, gracias por la respuesta, te paso el código del ci_edicion como lo tengo ahora:

<?php
class ci_edicion extends sindicato_ci
{
    protected $s__id_empresa;
    protected $s__datos_recibo;
    protected $s__datos_aportes;

    function get_relacion()
    {
        return $this->controlador->get_relacion();
    }

    //-----------------------------------------------------------------------------------
    //---- formulario -------------------------------------------------------------------
    //-----------------------------------------------------------------------------------

    function ajax__cargar_empresa($parametros, toba_ajax_respuesta $respuesta)
    {
        $this->s__id_empresa = $parametros['id_empresa'];
    }

    function conf__formulario(sindicato_ei_formulario $form)
    {
        if(!empty($this->s__datos_recibo))
            $form->set_datos($this->s__datos_recibo);
        elseif($this->get_relacion()->tabla("recibos")->esta_cargada())
            $form->set_datos($this->get_relacion()->tabla("recibos")->get());
    }

    function evt__formulario__modificacion($datos)
    {
        $this->s__datos_recibo = $datos;
        $this->get_relacion()->tabla("recibos")->set($datos);
    }

    //-----------------------------------------------------------------------------------
    //---- formulario_ml ----------------------------------------------------------------
    //-----------------------------------------------------------------------------------

    function ajax__get_importe($parametros, toba_ajax_respuesta $respuesta)
    {
        $aporte_pendiente = $this->get_pendientes($parametros['id_aporte'], $parametros['id_concepto']);
        $respuesta->set($aporte_pendiente);
    }

    function conf__formulario_ml(sindicato_ei_formulario_ml $form_ml)
    {
        if($this->get_relacion()->esta_cargada())
            $form_ml->set_datos($this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true));
        elseif(!empty($this->s__datos_aportes))
            $form_ml->set_datos($this->s__datos_aportes);
        elseif (!empty($this->s__id_empresa))
            $form_ml->set_datos_defecto($this->get_datos_empresa($this->s__id_empresa));
    }

    function evt__formulario_ml__modificacion($datos)
    {
        $this->s__datos_aportes = $datos;
        $this->get_relacion()->tabla("aportes_recibos")->procesar_filas($datos);
        $this->get_relacion()->sincronizar();
        $aportes_recibos = $this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true);
        $aportes_pendientes = toba::tabla("aportes_pendientes");
        $total = 0;
        foreach($aportes_recibos as $value)
        {
            $importe = $value['importe'];
            $aporte_pendiente = $this->get_pendientes($value['id_aporte'], $value['id_concepto']);
            if(!empty($aporte_pendiente))
            {
                $id_aporte_pendiente = array('id_aporte_pendiente'=>$aporte_pendiente['id_aporte_pendiente']);
                $aportes_pendientes->cargar($id_aporte_pendiente);
                $aporte_pendiente['importe'] -= $importe;
                if(!empty($aporte_pendiente["importe"])) $aportes_pendientes->set($aporte_pendiente);
                else $aportes_pendientes->eliminar_todo();
                $aportes_pendientes->sincronizar();
            }
            $total += $importe;
        }
        $recibo = $this->get_relacion()->tabla('recibos')->get();
        $recibo["total"] = $total;
        $this->get_relacion()->tabla('recibos')->set($recibo);
        $pendiente = $this->get_pendientes_x_empresa($this->s__id_empresa);
        $pendientes = toba::tabla("pendientes");
        foreach($pendiente as $value)
        {
            $array_pendiente = array("id_pendiente" => $value["id_pendiente"]);
            $pendientes->cargar($array_pendiente);
            $datos = $pendientes->get();
            $datos["total"] = $value["aporte"];
            $pendientes->set($datos);
        }
        $pendiente = $this->get_pendientes_baja($this->s__id_empresa);
        foreach($pendiente as $value) {
            $array_pendiente = array("id_pendiente" => $value["id_pendiente"]);
            $pendientes->cargar($array_pendiente);
            $pendientes->eliminar_todo();
        }
        $aportes_pendientes->resetear();
        $pendientes->resetear();
    }

    protected function get_datos_empresa($empresa)
    {
        $id_empresa = quote($empresa);
        $sql = "select t_a.periodo, t_ap.id_aporte, t_ap.id_concepto, t_ap.importe from pendientes t_p inner join "
            ."aportes_pendientes t_ap on t_p.id_pendiente=t_ap.id_pendiente inner join aportes t_a on "
            ."t_a.id_aporte=t_ap.id_aporte where t_p.id_empresa=$id_empresa and t_ap.anula=false and "
            ."t_p.anula=false order by t_ap.id_aporte, t_ap.id_concepto";
        $datos = consultar_fuente($sql);
        foreach($datos as $key => $value) {
            $datos[$key]["referencia"] = "COBRANZA PERIODO ".$value["periodo"];
        }
        return $datos;
    }

    protected function get_pendientes($aporte, $concepto)
    {
        $array_aportes_pendientes = array("id_aporte"=>$aporte,"id_concepto"=>$concepto);
        $aportes_pendientes = toba::tabla("aportes_pendientes");
        $aportes_pendientes->cargar($array_aportes_pendientes);
        return $aportes_pendientes->get();
    }

    protected function get_pendientes_x_empresa($empresa)
    {
        $id_empresa = quote($empresa);
        $sql = "select p.id_pendiente, p.total, sum(ap.importe) as aporte from pendientes p left join "
            ."aportes_pendientes ap on p.id_pendiente = ap.id_pendiente where p.id_empresa = $id_empresa "
            ."group by p.id_pendiente, p.total";
        return consultar_fuente($sql);
    }

    protected function get_pendientes_baja($empresa)
    {
        $id_empresa = quote($empresa);
        $sql = "select * from pendientes p where not exists (select '' from aportes_pendientes ap "
            ."where p.id_pendiente = ap.id_pendiente and ap.anula=false) and p.id_empresa = $id_empresa";
        return consultar_fuente($sql);
    }

}
?>

Te comento que hice los cambios que pusiste vos, pero me sigue dando el error porque el atributo apex_ei_analisis_fila del array $datos del evento evt__formulario_ml__modificacion sigue siendo igual a M.

Hola Matias,

es raro lo que me decis (igual me vendria bien una captura de la definicion del ML en toba_editor) , salvo que alguno de estos 2 casos sea un “default” para el alta… no deberia estar llegandote como una modificacion.

Subime la captura de la pestaña de Propiedades Basicas por si acaso hay algun detalle que se escape, el resto ya es revisar a fondo el metodo que impacta.. ya que como te decia, es raro que trabaje derecho viejo con las tablas de esa forma.

Es mas, me intriga saber cual es la relacion entre aportes_pendientes, aportes_recibos y recibos… tiene que haber una manera de usarlas en un DR.

Saludos

Esta es la captura de pantalla de las propiedades básicas del formulario_ml:


Con respecto a la relación de las tablas te comento que aportes_pendientes no tiene ninguna con aportes_recibos ni recibos, estas dos últimas son las que tienen relación entre sí, aportes_pendientes solo tiene los comprobantes que no fueron pagados por la empresa al sindicato, esta tabla es para facilitarle la carga de los recibos al usuario sin tener que elegir de a un comprobante y hacer clic en un botón agregar varias veces.
Tengo una pregunta: si yo agrego la tabla aportes_pendientes al dr y elimino uno o varios registros del formulario_ml, cuando ejecute el método sincronizar del dr se van a eliminar de la tabla, siendo que esta tabla es una tabla default para el alta de un recibo?

Ya lo solucioné, puse este código en el método conf__formulario_ml:

    function conf__formulario_ml(sindicato_ei_formulario_ml $form_ml)
    {
        if($this->get_relacion()->esta_cargada())
            $form_ml->set_datos($this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true));
        elseif(!empty($this->s__datos_aportes))
            $form_ml->set_datos($this->s__datos_aportes);
        elseif (!empty($this->s__id_empresa)) {
            $datos = $this->get_datos_empresa();
            foreach ($datos as $key => $value) {
                $datos[$key]['apex_ei_analisis_fila'] = 'A';
            }
            $form_ml->set_datos($datos);
        }
    }

Y ahora funciona perfecto.