/*
 * LocaisRealizacaoDataProvider.java
 *
 * Created on February 22, 2007, 10:44 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package siprp.medicina.locais_realizacao;

import java.util.Date;

import siprp.MedicinaConstants;

import com.evolute.utils.Singleton;
import com.evolute.utils.arrays.Virtual2DArray;
import com.evolute.utils.data.IDObject;
import com.evolute.utils.data.MappableObject;
import com.evolute.utils.db.DBManager;
import com.evolute.utils.db.Executer;
import com.evolute.utils.sql.Assignment;
import com.evolute.utils.sql.Expression;
import com.evolute.utils.sql.Field;
import com.evolute.utils.sql.Select;
import com.evolute.utils.sql.Select2;
import com.evolute.utils.sql.Union;
import com.evolute.utils.sql.Update;
import com.evolute.utils.tables.ColumnizedMappable;

/**
 *
 * @author fpalma
 */
public class LocaisRealizacaoDataProvider
{
	private static final Object LOCK = new Object();
	private static LocaisRealizacaoDataProvider instance = null;
	
	private Executer EXECUTER;
	
	/** Creates a new instance of LocaisRealizacaoDataProvider */
	private LocaisRealizacaoDataProvider()
		throws Exception
	{
		DBManager dbm = ( DBManager ) Singleton.getInstance( Singleton.DEFAULT_DBMANAGER );
		EXECUTER = dbm.getSharedExecuter( this );
	}
	
	public static LocaisRealizacaoDataProvider getProvider()
		throws Exception
	{
		synchronized( LOCK )
		{
			if( instance == null )
			{
				instance = new LocaisRealizacaoDataProvider();
			}
		}
		return instance;
	}
	
	public ColumnizedMappable[] getEmpresasComMarcacoes( Date data )
		throws Exception
	{
		
		
		Select selectConsultas =
			new Select2( 
				new String[]{ "trabalhadores_consultas_datas", "trabalhadores_consultas", "trabalhadores", "estabelecimentos" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{ 
					new Field( "trabalhadores_consultas_datas.trabalhadores_consultas_id" ).isEqual( new Field( "trabalhadores_consultas.id" ) ),
					new Field( "trabalhadores_consultas.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ),
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( new Field( "estabelecimentos.id" ) ) },
				new String[]{ "estabelecimentos.empresa_id" },
				new Field( "trabalhadores_consultas_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores_consultas_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Select selectEcds =
			new Select2( 
				new String[]{ "trabalhadores_ecds_datas", "trabalhadores_ecds", "trabalhadores", "estabelecimentos" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{ 
					new Field( "trabalhadores_ecds_datas.trabalhadores_ecds_id" ).isEqual( new Field( "trabalhadores_ecds.id" ) ),
					new Field( "trabalhadores_ecds.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ),
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( new Field( "estabelecimentos.id" ) ) },
				new String[]{ "estabelecimentos.empresa_id" },
				new Field( "trabalhadores_ecds_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores_ecds_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		
		Select select =
			new Select2( 
				new String[]{ "empresas" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "DISTINCT empresas.id", "empresas.designacao_social", "empresas.designacao_social_plain" },
				new Field( "empresas.id" ).in( new Union( new Select[]{ selectConsultas, selectEcds }, new int[]{} ) ),
				new String[]{ "empresas.designacao_social_plain" },
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		ColumnizedMappable empresas[] = new ColumnizedMappable[ array.columnLength() ];
		for( int n = 0; n < empresas.length; n++ )
		{
			Integer id = ( Integer ) array.get( n, 0 );
			String designacao = ( String ) array.get( n, 1 );
			empresas[ n ] = new ColumnizedMappable( id, designacao );
		}
		return empresas;
	}
	
	public ColumnizedMappable[] getEstabelecimentosComMarcacoesByEmpresa( Integer empresaID, Date data )
		throws Exception
	{
		Select selectConsultas =
			new Select2( 
				new String[]{ "trabalhadores_consultas_datas", "trabalhadores_consultas", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{ 
					new Field( "trabalhadores_consultas_datas.trabalhadores_consultas_id" ).isEqual( new Field( "trabalhadores_consultas.id" ) ),
					new Field( "trabalhadores_consultas.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "trabalhadores.estabelecimento_id" },
				new Field( "trabalhadores_consultas_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores_consultas_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Select selectEcds =
			new Select2( 
				new String[]{ "trabalhadores_ecds_datas", "trabalhadores_ecds", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{ 
					new Field( "trabalhadores_ecds_datas.trabalhadores_ecds_id" ).isEqual( new Field( "trabalhadores_ecds.id" ) ),
					new Field( "trabalhadores_ecds.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
					new String[]{ "trabalhadores.estabelecimento_id" },
				new Field( "trabalhadores_ecds_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores_ecds_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		
		Select select =
			new Select2( 
				new String[]{ "estabelecimentos" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "DISTINCT estabelecimentos.id", "estabelecimentos.nome", "estabelecimentos.nome_plain" },
				new Field( "estabelecimentos.id" ).in( new Union( new Select[]{ selectConsultas, selectEcds }, new int[]{} ) ).and( 
					new Field( "estabelecimentos.inactivo" ).isEqual( "n" ) ).and( 
					new Field( "empresa_id" ).isEqual( empresaID ) ),
				new String[]{ "estabelecimentos.nome_plain" },
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		ColumnizedMappable estabelecimentos[] = new ColumnizedMappable[ array.columnLength() ];
		for( int n = 0; n < estabelecimentos.length; n++ )
		{
			Integer id = ( Integer ) array.get( n, 0 );
			String nome = ( String ) array.get( n, 1 );
			estabelecimentos[ n ] = new ColumnizedMappable( id, nome );
		}
		
		return estabelecimentos;
	}
	
	public int getNumeroConsultasByEstabelecimentoAndDate( Integer estabelecimentoId, Date data )
		throws Exception
	{
		Select select =
			new Select2( 
				new String[]{ "trabalhadores_consultas_datas", "trabalhadores_consultas", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{ 
					new Field( "trabalhadores_consultas_datas.trabalhadores_consultas_id" ).isEqual( new Field( "trabalhadores_consultas.id" ) ),
					new Field( "trabalhadores_consultas.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "COUNT( DISTINCT trabalhadores.id )" },
				new Field( "trabalhadores_consultas_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "trabalhadores_consultas_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		return ( ( Number ) array.get( 0, 0 ) ).intValue();
	}
	
	public Integer[] getPrestadoresConsultaIdByEstabelecimentoAndDate( Integer estabelecimentoId, Date data )
		throws Exception
	{
		Select selectExterno =
			new Select2( 
				new String[]{ "trabalhadores_consultas_datas", "trabalhadores_consultas", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{ 
					new Field( "trabalhadores_consultas_datas.trabalhadores_consultas_id" ).isEqual( new Field( "trabalhadores_consultas.id" ) ),
					new Field( "trabalhadores_consultas.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "DISTINCT trabalhadores_consultas_datas.prestador_id" },
				new Field( "trabalhadores_consultas_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "trabalhadores_consultas_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Virtual2DArray arrayExterno = EXECUTER.executeQuery( selectExterno );
		Integer ids[] = new Integer[ arrayExterno.columnLength() ];
		for( int n = 0; n < arrayExterno.columnLength(); n++ )
		{
			ids[ n ] = ( Integer ) arrayExterno.get( n, 0 );
		}
		return ids;
	}
	
	public void setPrestadorConsultaIdForEstabelecimentoAndDate( Integer estabelecimentoId, Date data, Integer prestadorId )
		throws Exception
	{
		Select selectConsultas =
			new Select2( 
					new String[]{ "trabalhadores_consultas", "trabalhadores" },
					new Integer[]{ Select2.JOIN_INNER },
					new Expression[]{ 
						new Field( "trabalhadores_consultas.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
					new String[]{ "DISTINCT trabalhadores_consultas.id" },
					new Field( "trabalhadores_consultas.data" ).isEqual( data ).and( 
						new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
						new Field( "trabalhadores_consultas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
					null,
					null,
					null,
					null );
		Update updateConsultas = new Update( "trabalhadores_consultas",
												new Assignment[]{
													new Assignment( new Field( "prestador_id" ), prestadorId )
												},
												new Field( "id" ).in( selectConsultas ) );
		EXECUTER.executeQuery( updateConsultas );
		
		Select selectConsultasDatas =
			new Select2( 
				new String[]{ "trabalhadores_consultas_datas", "trabalhadores_consultas", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{ 
					new Field( "trabalhadores_consultas_datas.trabalhadores_consultas_id" ).isEqual( new Field( "trabalhadores_consultas.id" ) ),
					new Field( "trabalhadores_consultas.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "DISTINCT trabalhadores_consultas_datas.id" },
				new Field( "trabalhadores_consultas_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "trabalhadores_consultas_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Update updateConsultasDatas = new Update( "trabalhadores_consultas_datas",
				new Assignment[]{
					new Assignment( new Field( "prestador_id" ), prestadorId )
				},
				new Field( "id" ).in( selectConsultasDatas ) );
		EXECUTER.executeQuery( updateConsultasDatas );
	}
	
	protected IDObject[] getGruposEcdsByEstabelecimentoAndDate( Integer estabelecimentoId, Date data )
		throws Exception
	{
		Select select =
			new Select2( 
				new String[]{ "prt_grupos_protocolo", "prt_tipos_elementos_protocolo", "trabalhadores_ecd", 
								"trabalhadores_ecds_datas",	"trabalhadores_ecds", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{
					new Field( "prt_grupos_protocolo.id" ).isEqual( new Field( "prt_tipos_elementos_protocolo.grupo_protocolo_id" ) ),
					new Field( "prt_tipos_elementos_protocolo.id" ).isEqual( new Field( "trabalhadores_ecd.ecd_id" ) ),
					new Field( "trabalhadores_ecd.trabalhadores_ecds_datas_id" ).isEqual( new Field( "trabalhadores_ecds_datas.id" ) ),
					new Field( "trabalhadores_ecds_datas.trabalhadores_ecds_id" ).isEqual( new Field( "trabalhadores_ecds.id" ) ),
					new Field( "trabalhadores_ecds.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "DISTINCT prt_grupos_protocolo.id", "prt_grupos_protocolo.descricao", "prt_grupos_protocolo.ordem",
								"prt_grupos_protocolo.descricao_plain" },
				new Field( "trabalhadores_ecds_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "trabalhadores_ecds_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				new String[]{ "prt_grupos_protocolo.ordem", "prt_grupos_protocolo.descricao_plain" },
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		IDObject grupos[] = new IDObject[ array.columnLength() ];
		for( int n = 0; n < grupos.length; n++ )
		{
			Integer id = ( Integer ) array.get( n, 0 );
			String descricao = ( String ) array.get( n, 1 );
			grupos[ n ] = new MappableObject( id, descricao );
		}
		return grupos;
	}
	
	public Integer[] getPrestadoresByGrupoEcdEstabelecimentoAndDate( Integer grupoId, Integer estabelecimentoId, Date data )
		throws Exception
	{
		Select select =
			new Select2( 
				new String[]{ "prt_tipos_elementos_protocolo", "trabalhadores_ecd", 
								"trabalhadores_ecds_datas",	"trabalhadores_ecds", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{
					new Field( "prt_tipos_elementos_protocolo.id" ).isEqual( new Field( "trabalhadores_ecd.ecd_id" ) ),
					new Field( "trabalhadores_ecd.trabalhadores_ecds_datas_id" ).isEqual( new Field( "trabalhadores_ecds_datas.id" ) ),
					new Field( "trabalhadores_ecds_datas.trabalhadores_ecds_id" ).isEqual( new Field( "trabalhadores_ecds.id" ) ),
					new Field( "trabalhadores_ecds.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "DISTINCT trabalhadores_ecds_datas.prestador_id" },
				new Field( "trabalhadores_ecds_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "prt_tipos_elementos_protocolo.grupo_protocolo_id" ).isEqual( grupoId ) ).and(
					new Field( "trabalhadores_ecds_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		Integer prestadores[] = new Integer[ array.columnLength() ];
		for( int n = 0; n < prestadores.length; n++ )
		{
			prestadores[ n ] = ( Integer ) array.get( n, 0 );
		}
		return prestadores;
	}
	
	public int getNumeroMarcacoesByGrupoEcdEstabelecimentoAndDate( Integer grupoId, Integer estabelecimentoId, Date data )
		throws Exception
	{
		Select select =
			new Select2( 
				new String[]{ "prt_tipos_elementos_protocolo", "trabalhadores_ecd", 
								"trabalhadores_ecds_datas",	"trabalhadores_ecds", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{
					new Field( "prt_tipos_elementos_protocolo.id" ).isEqual( new Field( "trabalhadores_ecd.ecd_id" ) ),
					new Field( "trabalhadores_ecd.trabalhadores_ecds_datas_id" ).isEqual( new Field( "trabalhadores_ecds_datas.id" ) ),
					new Field( "trabalhadores_ecds_datas.trabalhadores_ecds_id" ).isEqual( new Field( "trabalhadores_ecds.id" ) ),
					new Field( "trabalhadores_ecds.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "COUNT( DISTINCT trabalhadores.id)" },
				new Field( "trabalhadores_ecds_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "prt_tipos_elementos_protocolo.grupo_protocolo_id" ).isEqual( grupoId ) ).and(
					new Field( "trabalhadores_ecds_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		return ( ( Number ) array.get( 0, 0 ) ).intValue();
	}

	public void setPrestadorIdForGruposEcdsEstabelecimentoAndDate( Integer estabelecimentoId, Date data, Integer prestadorId )
		throws Exception
	{
		Select selectConsultas =
			new Select2( 
					new String[]{ "trabalhadores_consultas", "trabalhadores" },
					new Integer[]{ Select2.JOIN_INNER },
					new Expression[]{ 
						new Field( "trabalhadores_consultas.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
					new String[]{ "DISTINCT trabalhadores_consultas.id" },
					new Field( "trabalhadores_consultas.data" ).isEqual( data ).and( 
						new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
						new Field( "trabalhadores_consultas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
					null,
					null,
					null,
					null );
		Update updateConsultas = new Update( "trabalhadores_consultas",
												new Assignment[]{
													new Assignment( new Field( "prestador_id" ), prestadorId )
												},
												new Field( "id" ).in( selectConsultas ) );
		EXECUTER.executeQuery( updateConsultas );
		
		Select selectConsultasDatas =
			new Select2( 
				new String[]{ "trabalhadores_consultas_datas", "trabalhadores_consultas", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{ 
					new Field( "trabalhadores_consultas_datas.trabalhadores_consultas_id" ).isEqual( new Field( "trabalhadores_consultas.id" ) ),
					new Field( "trabalhadores_consultas.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "DISTINCT trabalhadores_consultas_datas.id" },
				new Field( "trabalhadores_consultas_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "trabalhadores_consultas_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Update updateConsultasDatas = new Update( "trabalhadores_consultas_datas",
				new Assignment[]{
					new Assignment( new Field( "prestador_id" ), prestadorId )
				},
				new Field( "id" ).in( selectConsultasDatas ) );
		EXECUTER.executeQuery( updateConsultasDatas );
	}
	
	protected IDObject[] getExamesOficiaisByEstabelecimentoAndDate( Integer estabelecimentoId, Date data )
		throws Exception
	{
		Select select =
			new Select2( 
				new String[]{ "ecd_oficial", "trabalhadores_ecd", 
								"trabalhadores_ecds_datas",	"trabalhadores_ecds", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{
					new Field( "ecd_oficial.id" ).isEqual( new Field( "trabalhadores_ecd.ecd_oficial_id" ) ),
					new Field( "trabalhadores_ecd.trabalhadores_ecds_datas_id" ).isEqual( new Field( "trabalhadores_ecds_datas.id" ) ),
					new Field( "trabalhadores_ecds_datas.trabalhadores_ecds_id" ).isEqual( new Field( "trabalhadores_ecds.id" ) ),
					new Field( "trabalhadores_ecds.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "DISTINCT ecd_oficial.id", "ecd_oficial.descricao", "ecd_oficial.ordem",
								"ecd_oficial.descricao_plain" },
				new Field( "trabalhadores_ecds_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "trabalhadores_ecds_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				new String[]{ "ecd_oficial.ordem", "ecd_oficial.descricao_plain" },
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		IDObject ecds[] = new IDObject[ array.columnLength() ];
		for( int n = 0; n < ecds.length; n++ )
		{
			Integer id = ( Integer ) array.get( n, 0 );
			String descricao = ( String ) array.get( n, 1 );
			ecds[ n ] = new MappableObject( id, descricao );
		}
		return ecds;
	}
	
	public Integer[] getPrestadoresByEcdOficialEstabelecimentoAndDate( Integer ecdOficialId, Integer estabelecimentoId, Date data )
		throws Exception
	{
		Select select =
			new Select2( 
				new String[]{ "trabalhadores_ecd", "trabalhadores_ecds_datas",	"trabalhadores_ecds", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{
					new Field( "trabalhadores_ecd.trabalhadores_ecds_datas_id" ).isEqual( new Field( "trabalhadores_ecds_datas.id" ) ),
					new Field( "trabalhadores_ecds_datas.trabalhadores_ecds_id" ).isEqual( new Field( "trabalhadores_ecds.id" ) ),
					new Field( "trabalhadores_ecds.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "DISTINCT trabalhadores_ecds_datas.prestador_id" },
				new Field( "trabalhadores_ecds_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "trabalhadores_ecd.ecd_oficial_id" ).isEqual( ecdOficialId ) ).and(
					new Field( "trabalhadores_ecds_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		Integer prestadores[] = new Integer[ array.columnLength() ];
		for( int n = 0; n < prestadores.length; n++ )
		{
			prestadores[ n ] = ( Integer ) array.get( n, 0 );
		}
		return prestadores;
	}
	
	public int getNumeroMarcacaoesByEcdOficialEstabelecimentoAndDate( Integer ecdOficialId, Integer estabelecimentoId, Date data )
		throws Exception
	{
		Select select =
			new Select2( 
				new String[]{ "trabalhadores_ecd", "trabalhadores_ecds_datas",	"trabalhadores_ecds", "trabalhadores" },
				new Integer[]{ Select2.JOIN_INNER, Select2.JOIN_INNER, Select2.JOIN_INNER },
				new Expression[]{
					new Field( "trabalhadores_ecd.trabalhadores_ecds_datas_id" ).isEqual( new Field( "trabalhadores_ecds_datas.id" ) ),
					new Field( "trabalhadores_ecds_datas.trabalhadores_ecds_id" ).isEqual( new Field( "trabalhadores_ecds.id" ) ),
					new Field( "trabalhadores_ecds.trabalhador_id" ).isEqual( new Field( "trabalhadores.id" ) ) },
				new String[]{ "COUNT( DISTINCT trabalhadores.id)" },
				new Field( "trabalhadores_ecds_datas.data" ).isEqual( data ).and( 
					new Field( "trabalhadores.estabelecimento_id" ).isEqual( estabelecimentoId ) ).and(
					new Field( "trabalhadores_ecd.ecd_oficial_id" ).isEqual( ecdOficialId ) ).and(
					new Field( "trabalhadores_ecds_datas.estado" ).isEqual( new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ) ) ),
				null,
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		return ( ( Number ) array.get( 0, 0 ) ).intValue();
	}
	
	public Integer []getMarcacoesEcdsIdsByDataAndPrestadorId( Date data, Integer prestadorId )
		throws Exception
	{
		if( LocaisRealizacaoConstants.PRESTADOR_ID_SIPRP.equals( prestadorId ) )
		{
			prestadorId = null;
		}
		Select select = 
			new Select2( 
				new String[]{ "trabalhadores_ecds_datas" },
				new Integer[]{},
				new Expression[]{},
				new String[]{ "id" },
				new Field( "data" ).isEqual( data ).and( 
					new Field("prestador_id" ).isEqual( prestadorId ) ).and( 
					new Field( "estado" ).in( 
							new Integer[]{ 
									new Integer( MedicinaConstants.ESTADO_POR_REALIZAR ),
									new Integer( MedicinaConstants.ESTADO_PARCIALMENTE_REALIZADO ),
									new Integer( MedicinaConstants.ESTADO_REALIZADO ) } ) ),
				null,
				null,
				null,
				null );
		Virtual2DArray array = EXECUTER.executeQuery( select );
		Integer ids[] = new Integer[ array.columnLength() ];
		for( int n = 0; n < array.columnLength(); n++ )
		{
			ids[ n ] = ( Integer ) array.get( n, 0 );
		}
		return ids;
	}
}
