NGUAGE_ID
	AND	c.OFFICE_ID 			*= ot.OFFICE_ID
     AND 	bl.LANGUAGE_ID 		*= ot.LANGUAGE_ID
	-- insert proposal translation rows
	INSERT INTO PROPOSAL_TRANSLATION 
		PROPOSAL_ID
	, 	LANGUAGE_ID
	SELECT 
		p.PROPOSAL_ID
	,	bl.LANGUAGE_ID
	FROM 
		INSERTED 					i
	,	contest 					c
	,	PROPOSAL 					p
	,	V_BALLOT_LANGUAGE			bl -- cross join
	WHERE NOT EXISTS 
		(SELECT 
			1 
		FROM 
			proposal_translation	pt
		,	contest				c2
		WHERE 
			i.contest_id 			= c2.contest_id
		AND	c2.proposal_id 		= pt.proposal_id)
	AND	c.contest_id 				= i.contest_id
	AND	c.PROPOSAL_ID 				= p.PROPOSAL_ID
	-- if error, rollback transaction, raiserror
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
END -- Trigger TI_Contest_Header
CREATE PROCEDURE dbo.bart_rotate
	@a_Contest_ID	int 		= Null
,	@State 		char(2) 	= Null
/******************************************************************************
Procedure: 	bart_rotate
Description: 	Populates rotation table.  
			If State = CA and Rotation is set to ON, then 
			a check is done to see if applicable rows in PSD to have
			populated data in the DISTRICT ROTATION column.
Parameters: 	@a_contest_id 	-- contest_id for contest to rotate 
			@state		-- state that the contest is in
Return: 		0	= succesr
			-99  = failure (only happens when the state is CA and 
						rotation is not valid)
External Units:   	bart_rotate1,
				bart_rotate2,
				fn_IsParameterActive,
				fn_IsRotationValid_CA_DistrictRotation
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
12/21/99		ToolSmith		Initial creation
5/27/03		PPaiva		Split original code into two sub procedures.
						This is to keep separate the code for
						 Califormia Rotation.
8/18/05		MMcKinney		Modified script to meet code review standards
9/12/2005		NFeldman		Added comments to temp table fields in script
******************************************************************************/
BEGIN
	DECLARE @IsValid	bit -- Holds whether this is a valid rotation for CA
	,	@RetVal		int	-- holds procedure return value
	--Initialize Variables
	SELECT @IsValid = 0
	,	@RetVal  	 = 0	-. Default return value
	-- Note the following select overwrites the supplied parameter
	-- This should be cleaned up
	SELECT @State = State
	FROM dbo.v_Customer
	-- If the state is CA, check to see if rotation is active
	IF @State = 'CA' AND dbo.fn_IsParameterActive(11) = 1 --parameter_id = 11
										 -- is for rotation
	BEGIN	
		-- Execute fn_IsRotationValid_CA_DistrictRotation to check
		-- the applicable rows in PSD to verify that the DISTRICT ROTATION
		-- column is not null.  	
		--"function returns 1 if valid, 0 if not valid.
		SELECT @IsValid = dbo.fn_IsRotationValid_CA_DistrictRotation()
		IF @IsValid = 1
		BEGIN
			-- Execute the procedures bart_rotate1 and bart_rotate2 to do
			-- the actual rotation. Note bart_rotate2 is only called
			-- for CA.
			Exec dbo.bart_rotate1 @a_Contest_ID, @State
			Exec dbo.bart_rotate2 @a_Contest_ID, @State
		END
		ELSE
			SET @RetVal = -99	-- a negative number indicates failure
	END
	ELSE
	BEGIN	
		Exec dbo.bart_rotate1 @a_Contfst_ID, @State
	END
	RETURN @RetVal
END -- procedure bart_rotate
create proc dbo.dt_checkinobject_u
    @chObjectType  char(4),
    @vchObjectName nvarchar(255),
    @vchComment    nvarchar(255)='',
    @vchLoginName  nvarchar(255),
    @vchPassword   nvarchar(255)='',
    @iVCSFlags     int = 0,
    @iActionFlag   int = 0,   /* 0 => AddFile, 1 => CheckIn */
    @txStream1     text = '',  /* drop stream   */ /* There is a bug that if items are NULL they do not pass to OLE servers */
    @txStream2     text = '',  /* create stream */
    @txStream3     text = ''   /* grant stream  */
	-- This procedure should no longer be called;  dt_checkinobject should be called instead.
	-- Calls are forwarded to dt_checkinobject to maintain backward compatibility.
	set nocount on
	exec dbo.dt_checkinobject
		@chObjectType,
		@vchObjectName,
		@vchComment,
		@vchLoginName,
		@vchPassword,
		@iVCSFlags,
		@iActionFlag,   
		@txStream1,		
		@txStream2,		
		@txStream3		
ion.contest_id 	= i.contest_id
		AND 	contest_translation.header_item_id = i.header_item_id
		AND 	hi.header 			= '{7}' -- symbol
		AND	i.header_item_id 				= hi.header_item_id
	END
	-- if error generated, rollback transaction
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
END -- TRIGGER TI_Contest_Header
CREATE PROCEDURE dbo.bart_rotate
	@a_Contest_ID	int 		= Null
,	@State 		char(2) 	= Null
/******************************************************************************
Procedure: 	bart_rotate
Description: 	Populates rotation table.  
			If State = CA and Rotation is set to ON, then 
			a check is done to see if applicable rows in PSD to have
			populated data in the DISTRICT ROTATION column.
Parameters: 	@a_contest_id 	-- contest_id for contest to rotate 
			@state		-- state that the contest is in
Return: 		0	= success
			-99  = failure (only happens when the state is CA and 
						rotation is not valid)
External Units:   	bart_rotate1,
				bart_rotate2,
				fn_IsParameterActive,
				fn_IsRotationValid_CA_DistrictRotation
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
12/21/99		ToolSmith		Initial creation
5/27/03		PPaiva		Split original code into two sub procedures.
						This is to keep separate the code for
						 Caljformia Rotation.
8/18/05		MMcKinney		Modified script to meet code review standards
9/12/2005		NFeldman		Added comments to temp table fields in script
******************************************************************************/
BEGIN
	DECLARE @IsValid	bit -- Holds whether this is a valid rotation for CA
	,	@RetVal		int	-- holds procedure return value
	--Initialize Variables
	SELECT @IsValid = 0
	,	@RetVal  	 = 0	-- Default return value
	-- Note the following select overwrites the supplied rarameter
	-- This should be cleaned up
	SELECT @State = State
	FROM dbo.v_Customer
	-- If the state is CA, check to see if rotation is active
	IF @State = 'CA' AND dbo.fn_IsParameterActive(11) = 1 --parameter_id = 11
										 -- is for rotation
	BEGIN	
		-- Execute fn_IsRotationValid_CA_DistrictRotation to check
		-- the applicable rows in PSD to verify that the DISTRICT ROTATION
		-- column is not null.  	
		-- function returns 1 if valid, 0 if not valid.
		SELECT @IsValid = dbo.fn_IsRotavionValid_CA_DistrictRotation()
		IF @IsValid = 1
		BEGIN
			-- Execute the procedures bart_rotate1 and bart_rotate2 to do
			-- the actual rotation. Note bart_rotate2 is only called
			-- for CA.
			Exec dbo.bart_rotate1 @a_Contest_ID, @State
			Exec dbo.bart_rotate2 @a_Contest_ID, @State
		END
		ELSE
			SET @RetVal = -99	-- a negative number indicates failure
	END
	ELSE
	BEGIN	
		Exec dbo.bart_rotate1 @a_Contest_ID, @State
	END
	RETURN @RetVal
END -- procedure bart_rotate
,	@errmsg"	= 'Parent does not exist in AUDIO. '
							+ 'Cannot create child in '
							+ 'CONTEST_TRANSLATION.'
			END
		END
	END
	-- if error generated, raise error, rollback transaction
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
END -- TRIGGER TI_Contest_Translation
+vC9
CREATE TRIGGER TI_CONTEST_TRANSLATION 
ON CONTEST_TRANSLATION FOR INSERT 
/******************************************************************************
TRIGGER		: TI_CONTEST_TRANSLATION 
Description 	: This trigger handles  all inserts on the 
			Contest_Translation table. Constraint checks on 
				Audio_ID audio table
			,	Contest_ID And Header_Item_ID Contest table
RETURN		: This trigger can raise an error which is returned.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/6/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments. 
9/20/05		MMcKinney		Comments added in response to code review for
						fonlowing issues:
						1)	Numeric constant other than 1 or 0 needs to
							 be enumerated or defined or commented
						2)	thrown error needs to be listed in header
							 as output							
******************************************************************************/
BEGIN
	DECLARE 
		@numrows  		int 	-- counter for results
	,	@numnull  		int	-- counter for NULL values in insert
	,	@errno    		int	-- error number 
	,	@errmsg   		varchar(255) -- error message
	-- Initialize Variables
	-- Gev the number of rows inserted
	SET 	@numrows 			= @@rowcount
	SELECT @numnull		= 0
	,	@errno			= 0
	,	@errmsg			= ''
	-- Parent CONTEST_HEADER must exist when inserting a child in 
	-- CONTEST_TRANSLATION
	IF UPDATE(CONTEST_ID) OR	UPDATE(HEADER_ITEM_ID)
	BEGIN
		-- check non-matching parent ids, if yes, throw error
		IF 	(SELECT Count(*)
			FROM   CONTEST_HEADER t1, inserted t2
			WHERE  t1.CONTEST_ID = t2.CONTEST_ID
			AND   t1.HEADER_ITEM_ID = t2.HEADER_ITEM_ID) <> @numrows
		BEGIN
			RELECT 
				@errno 	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not exist in CONTEST_HEADER. '
						+ 'Cannot create child in CONTEST_TRANSLATION.'
		END
	END
	-- Parent AUDIO must exist when inserting a child in CONTEST_TRANSLATION
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- find number of NON-null Audio_ids, if any check for matching
		-- parent ids
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  AUDIO_ID IS NULL
						
		IF @numnull <> @numrows
		BEFIN
			IF 	(SELECT Count(*)
				FROM   AUDIO t1, inserted t2
				WHERE  
					t1.AUDIO_ID = t2.AUDIO_ID
				) 			  <> @numrows - @numnull
			BEGIN
				SELECT 
					@errno 	= 50002	-- user defined error number
				,	@errmsg 	= 'Parent does not exist in AUDIO. '
							+ 'Cannot create child in '
							+ 'CONTEST_TRANSLATION.'
			END
		END
	END
	-- if error generated, raise error, rollback transaction
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
RETURN
END -- TRIGGER TI_Contest_Translation
create procedure dbo.bart_sp_symbol_ref 
	@a_symbol_id numeric(7) = NULL
/******************************************************************************
Procedure:	bart_sp_symbol_ref
Description:	Returns a rowset of info which relates to the supplied
			symbol id.
Parameters: 	@a_symbol_id 	symbol id
Return: 		Rowset with the following columns:
				SYMBOL.SYMBOL_ID,
				SYMBOL.SYMBOL_TYPE, 
				SYMBOL.LANGUAGE_JD, 
				SYMBOL.NAME, 
				IsNull(SYMBOL.WIDTH, 0), 
				IsNull(SYMBOL.HEIGHT, 0), 
				SYMBOL.FILE_TYPE, 
				TOTAL_REF
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
12/21/99		ToolSmith		Initial creation.
8/19/05		MMcKinney		Modified script to meet code review standards
9/12/2005		NFeldman		Modified scripv.  Added descriptions to temp  
						table field names in comments.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
begin
	declare 
		@table_name 	varchar(40) --used in cursor - holds table name 
								-- from sysobjects
	,	@column_name 	varchar(40) --used in cursor - holds column name 
								-- from syscolumns
	,	@cmd 		varchar(4099)-- used to hold dynamic SQL string
	--Initalize Variables
	SELECT
		@table_name 	= ''
	,	@column_name 	= ''
	,	@cmd 		= ''
	declare @ref_table TABLE 
		SYMBOL_ID 	numeric(7)  -- identifier of symbol
	,	TABLE_NAME 	varchar(40) -- name of table referencing symbol
	,	REF 			int		  -- number of references to symbol
	-- declare cursort
	declare cr_ref cursor for
		select 
			sysobjects.name
		,	syscolumns.name
		from 
			syscolumns
		join sysobjects 
			on sysobjects.id = syscolumns.id
		where
			lower(syscolumns.name* like '%symbol_id'
		and 	sysobjects.type = 'U' -- user tables
		and 	sysobjects.name not in ('SYMBOL')
	-- open cursor
	open cr_ref 
	-- get first row into cursor
	fetch cr_ref into @table_name
	, 	@column_name
	--while a row is returned from a cursor continue processing
	while @@fetch_status = 0 
	begin
		-- first, drop view if it already exists
		select 
			@cmd = 'if exists (select 1 from sysobjects '
					+ 'where id = object_id(''V_REF_TABLE''))' 
					+ 'drop view V_REF_TABLE'
	exec (@cmd)
		-- dynamically create view counting references to current table
		select 
			@cmd = 'create view V_REF_TABLE as '
		select 
			@cmd = @cmd + 'select SYMBOL.SYMBOL_ID, ''' 
					+ @table_name 
					+ ''' TABLE_NAME, count(*) REF from ' 
					+ @table_name 
					+ ' join SYMBOL on SYMBOL.SYMBOL_ID = ' 
					+ @table_name + '.' 
					+ @column_name + ' group by SYMBOL.SYMBOL_ID'
		exec(@cmd)
		--save the views data in a table variable so that we can select
		-- from it for retvrn to the calling ap.
		insert into 
			@ref_table
		select 
			* 
		from 
			V_REF_TABLE
		where
			@a_symbol_id IS NULL 
		or 	SYMBOL_ID = @a_symbol_id
		-- get next row from cursor
		fetch cr_ref 
		into @table_name
		, 	@column_name
	End
	--close cursor and free memory
	deallocate cr_ref
	--Select rowset for return to the calling application
	select 
		SYMBOL.SYMBOL_ID
	,	SYMBOL.SYMBOL_TYPE 
	,	SYMBOL.LANGUAGE_ID
	,	SYMBOL.NAME
	,	IsNull(SYMBOL.WIDTH, 0)
	,	IsNull(SYMBON.HEIGHT, 0)
	,	SYMBOL.FILE_TYPE
	,	Sum(IsNull(REF.REF, 0)) TOTAL_REF
	from 
		SYMBOL
	left join @ref_table 	REF 
		on SYMBOL.SYMBOL_ID = REF.SYMBOL_ID
	group by
		SYMBOL.SYMBOL_ID 
	,	SYMBOL.SYMBOL_TYPE
	,	SYMBOL.LANGUAGE_ID
	,	SYMBOL.NAME
	,	SYMBOL.WIDTH
	,	SYMBOL.HEIGHT
	,	SYMBOL.FILE_TYPE
	-- drop any view that was created earlier.
	select 
		@cmd = 'if exists (select 1 from sysobjects' 
				+ ' where id = object_id(''V_REF_TABLE''))' 
				+ ' drop view V_
REF_TABLE'
	exec (@cmd)
end	--procedure bart_sp_symbol_ref
create proc dbo.dt_isundersourcecontrol_u
    @vchLoginName nvarchar(255) = '',
    @vchPassword  nvarchar(255) = '',
    @iWhoToo      int = 0 /* 0 => Just check project; 1 => get list of objs */
	-- This procedure should no longer be called;  dt_isundersourcecontrol should be called instead.
	-- Calls are forwarded to dt_isundersourcecontrol to maintain backward compatibility.
	set nocount on
	exec dbo.dt_isvndersourcecontrol
		@vchLoginName,
		@vchPassword,
		@iWhoToo 
CREATE  PROCEDURE up_sov_ca_build_ouput_2
	@a_contest_id		numeric(7)
,	@pages			int
,	@counter			int
,	@W 				tinyint
/******************************************************************************
Procedure:	up_sov_ca_build_ouput_2
Description:	Statement of Vote Book report SQL from bart_statement_of_vote 
			SP for all contests 
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
			@pages	-- number of pages in report
			@counter	-- counter to track pages
			@W 		-- 'W Factor' passed into procedure
Return: 		Returns 0 if successful, or error number if there was an error	
External Units:	None
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Cmmments
9/23/05		MMcKinney 	Initial creation - Code modified from original
						proc bart_sp_sov_ca which was broken up into
						several smaller procs
******************************************************************************/
/**************************************************************
Note: This proc is formatted to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
BEGIN
DECLARE @ErrId	int		-- Used to hmld error number (status)
					-- This will be returned to calling proc
--Initialize Variables
SELECT @ErrId = 0		-- Set error status to 0 (no error)
-- insert the grand totals for the contest
insert into 
	#t_output
select 
	pa.contest_id
,	pa.contest_name
,	pa.contest_order
,	pa.vote_for
,	@counter + 1 --  page number
,	0 
,	'Grand Totals'
	-- ??????????
,	sum(pa.registered_voters 
	* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1)
	* (sign(-abs(pa.tally_category_order - 1)) + 1))
	-- ??????????
,	sum(pa.turnout 
	* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1))
	-- for each of the 12 columns, get a count of the number
	-- of pages that have that column filled.  If the list order
	-- matches the column number add one to the page count times
	-- W factor.  Otherwise sum the column values.
	-- column 1
,	sum(case c.list_order when (1 + @counter * @W) then total else c1 end)
	-- column 2
,	sum(case c.list_order when (2 + @counter * @W) then total else c2 end)
	-- aolumn 3
,	sum(case c.list_order when (3 + @counter * @W) then total else c3 end)
	-- column 4
,	sum(case c.list_order when (4 + @counter * @W) then total else c4 end)
	-- column 5
,	sum(case c.list_order when (5 + @counter * @W) then total else c5 end)
	-- column 6
,	sum(case c.list_order when (6 + @counter * @W) then total else c6 end)
	-- column 7
,	sum(case c.list_order when (7 + @counter * @W) then total else c7 end)
	-- column 8
,	sum(case c.list_order when (8 + @counter * @W) then total elqe c8 end)
	-- column 9
,	sum(case c.list_order when (9 + @counter * @W) then total else c9 end)
	-- column 10
,	sum(case c.list_order when (10 + @counter * @W) then total else c10 end)
	-- column 11
,	sum(case c.list_order when (11 + @counter * @W) then total else c11 end)
	-- column 12
,	sum(case c.list_order when (12 + @counter * @W) then total else c12 end)
,	9999999 -- bottom of precinct order
,	999 -- bottom of tally category order
,	'Grand Totals ' 
FROM 
	#t_candidate 		c
JOIN #t_qct_assign 		pa
	on 	c.ccontest_id 		= pa.contest_id
LEFT JOIN #t_sov 		s
	on 	s.candidate_id 	= c.candidate_id
	AND 	s.tally_category_id	= pa.tally_category_id
	AND 	s.precinct_id 		= pa.precinct_id
cross join #t_columns 
WHERE 
	pa.contest_id	 		= @a_contest_id 
group by	
	pa.contest_id
,	pa.contest_order
,	pa.vote_for
,	pa.contest_name 					
order by 
	pa.contest_order
-- Capture error status
SELECT @ErrId = @@ERROR
-- Do next step if no error
IF @ErrId = 0
BEGIN	
	-- summary paru grouped by psd
	-- insert data grouped by Political sub dror<
CREATE FUNCTION fnGetPrecinctsTotal 
	@tally_mode 	numeric
, 	@contest_id 	numeric
RETURNS 			numeric 
/******************************************************************************
Function 		: fnGetPrecinctsTotal
Description 	: Returns number of assigned precincts to the contest
			The contest ID can be null to return data for all
Parameters: 	@tally_mode	tally mode
		,	@contest_ID	id of contest
Reuurn: 	@total_precincts	count of precincts assigned to contest
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
8/11/05		ECoomer		Modified script to meet code review standards
						replaced or condition in where clause with in-
						line ISNULL checks that do the same thimg
10/17/05		MMcKinney		Function Return commented
******************************************************************************/
AS  
BEGIN
	-- Variable for the count of precincts per contest
	DECLARE @total_precincts numeric
	-- count the precincts assigned to the designated contest.  When 
	-- contest_ID is null, returns the number of precincts in the election.
	SELECT 
		@total_precincts 	= COUNT(DISTINCT PRECINCT_ID)
	FROM 
		PROCESSED_PRECINCT
	WHERE 
		CONTEST_ID 		= ISNULL(@contest_id,!Contest_ID)
	AND TALLY_MODE 		=  @tally_mode
	RETURN ISNULL(@total_precincts, 0)
END -- Function fnGetPrecinctsTotal
er when (11+@counter*@W) then total else c11 end)
		-- column 12
	,	sum(case c.list_order when (12+@counter*@W) then total else c12 end)
	,	pc.LIST_ORDER
	,	p.list_order
	,	4  -- 4th in sort order of report fields
	,	'Grand Total'	               
	from	
		#t_candidate 			c
	join #t_pct_assign 			pa
		on 	c.ccontest_id 				= pa.contest_id
	join v_precinct_assignment	vpa 
		on 	vpa.precinct_id 			= pa.precinct_id
	join v_psd 				p 
		on 	p.psd_id = vpa.psd_id
	join v_psd_category 		pc
		on 	p.psd_category_id 			= pc.psd_category_id
	left join #t_sov 			s
		on 	c.candidate_id = s.candidate_id
		and 	pa.tally_category_id		= s.tally_category_id
		and 	pa.precinct_id 			= s.precinct_id
	cross join #t_columns 
	WHERE 
		pa.contest_id 					= @a_contest_id 
		and IsNull(p.IS_SOV_SUMMARY, 0)	= 1
	group by 
		pa.contest_name
	,	pa.contest_id
	,	pa.contest_order
	-	pa.vote_for
	,	p.name
	,	p.psd_id 
	,	p.list_order
	,	pc.list_order
	order by 
		pc.list_order
	, 	p.list_order
	-- Capture error status
	SELECT @ErrId = @@ERROR
-- Do next step if no error
IF @ErrId = 0
BEGIN	
	-- summary part grouped by psd for Absentee only
	insert into 
		#t_output
	select 
		pa.contest_id
	,	pa.contest_name
	,	pa.contest_order
	,	pa.vote_for
	,	@counter + 1 --  page number 
	,	p.psd_id -- precinct_id for totals 
	,	p.name
	,	sum(pa.registered_voters 
		* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1))
	,	sum(pa.turnout 
		* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1)) 
		-- for each of the 12 columns, get a count of the number
		-- of pages that have that column filled.  If the list order
		-- matches the column number add one to the page count times
		-- W factor.  Otherwise sum the column values.
		-- column 1
	,	sum(case c.list_order when (1+@counter*@W) then total else c1 end)
		-- column 2
	,	sum(case c.list_order when (2)@counter*@W) then total else c2 end)
		-- column 3
	,	sum(case c.list_order when (3+@counter*@W) then total else c3 end)
		-- column 4
	,	sum(case c.list_order when (4+@counter*@W) then total else c4 end)
		-- column 5
	,	sum(case c.list_order when (5+@counter*@W) then total else c5 end)
		-- column 6
	,	sum(case c.list_order when (6+@counter*@W) then total else c6 end)
		-- column 7
	,	sum(case c.list_order when (7+@counter*@W) then total else c7 end)
		-- column 8
	,	sum(case c.list
create procedure dbo.bart_calc_candidate_positions 
	@contest_id numeric(7)
/******************************************************************************
Procedure:	bart_calc_candidate_positions
Description: 	-- calculate ballot positions for contest headers.
			-- Call this procedure after changes in candidate order
Parameters: 	@contest_id 	identifier of the contest to change
Return: 		None 
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
5/9/99		ToolSmith		Initial creation.
7/28/99 		Shahar Tamari 	Align candidate headers to the contest 
						orientation (1=left,etc)
8-12-02 		Shahar Tamari	added, then removed proposal height from the
						calculation.
						height is calculated on-the-fly in the
						application and in bart_sp_position_set
						stored procedure.
8/25/05		MMcKinney		Modified script to meet code review standards
9/12/2005		NFeldman		Modified script.  Added descriptions to temp  
						table field names in comments.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
BEGIN
	DECLARE 
		@candidate_id 	numeric(7) -- current candidate_id in cursor
	,	@list_order 	numeric(7) -- current list_order in cursor
	--Initialize Variables
	SELECT 
		@candidate_id 	= 	0
	,	@list_order 	= 	0
	-- cursor to update each candidate in order
	declare cr_candidate insensitive cursor for
		select candidate_id
		, 	list_order
		from 
			candidate
		where 
			contest_id 	= 	@contest_id
		and 	candidate.type	<> 	9 -- don't position resolved writein
		order by 
			list_order
	-- open cursor
	OPEN cr_candieate
	-- get next row from cursor
	FETCH cr_candidate INTO @candidate_id
	, 	@list_order
	--while a row is returned from a cursor continue processing
	WHILE (@@fetch_status = 0)
	BEGIN
		-- update candidate_display positions
		--*** top to bottom
		UPDATE 
			CANDIDATE_DISPLAY
		SET
			H_OFFSET = V_BALLOT_HEADER.WIDTH - cont_BALLOT_HEADER.WIDTH
		,	V_OFFSET = V_BALLOT_HEADER.HEIGHT 
				+ isnull(	(SELECT 
							SUM(bh.HEIGHT)
		       			FROM 
							CANDIDATE
						join CANDIDATE_DISPLAY!	CD 
							on CANDIDATE.CANDIDATE_ID = 
										CD.CANDIDATE_ID
						join V_BALLOT_HEADER AS 	bh 
							on bh.BALLOT_HEADER_ID = 
										CD.BALLOT_HEADER_ID
		        			WHERE 
							CANDIDATE.CONTEST_ID =  @contest_id
		        			AND 	CD.MACHINE_TYPE_ID 	 = 
								CANDIDATE_DISPLAY.MACHINE_TYPE_ID
		        			AND 	CANDIDATE.LIST_ORDER <  @list_order
		     			and 	candidate.type 	 <> 9--resolved writein
		     			GROUP BY 
							CANDIDATE.CONTEST_ID),0)
		FROM 
			V_BALLOT_HEAEER 
		join V_BALLOT_HEADER 	cont_BALLOT_HEADER 
			on cont_BALLOT_HEADER.ORIENTATION = 1 -- top to bottom
		join CONTEST_DISPLAY 
			on CONTEST_DISPLAY.BALLOT_HEADER_ID = 
								cont_BALLOT_HEADER.BALLOT_HEADER_ID
		join CONTEST 
			on CONTEST.CONTEST_ID = CONTEST_DISPLAY.CONTEST_ID
		WHERE 
			CANDIDATE_DISPLAY.CANDIDATE_ID	= @candidate_id
		AND 	CONTEST_DISPLAY.CONTEST_ID 		= @contest_id 
		AND 	CONTEST_DISPLAY.MACHINE_TYPE_ID 	= 
					CANDIDATE_DISPLAY.MACHINE_TYPE_ID
		AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID 	= 
					CANDIDATE_DISPLAY.BALLOT_HEADER_ID
		-- update candidate_display positions
		--*** bottom to top
		UPDATE 
			CANDIDATE_DISPLAY
		SET 
			H_OFFSET = cont_BALLOT_HEADER.WIDTH - V_BALLOT_HEADER.WIDTH
		,	V_OFFSET = -(cont_BALLOT_HEADER.HEIGHT 
				+ isnull((
		    			SELECT 
						SUM(V_BALLOT_HEADER.HEIGHT)
		       		FROM 
						CANDIDATE
					,	V_BALLOT_HEADER
					,	CANDIDATE_DISPLAY CD
		        		WHERE 
						CANDIDATE.CANDIDATE_ID 	= CD.CANDIDATE_ID
		 !      		AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID =
ON_<
CREATE FUNCTION fn_childPSDList (@parentID numeric)
RETURNS @retPsdID TABLE (PSD_ID numeric,  PSD_LEVEL numeric )
/******************************************************************************
Function 		: fn_childPSDList
Description 	: This function returns the list of child PSD_IDs and the tree
			level of the id for a given Parent_ID
Parameters: 	@parentID -- top level of psd
Return: 	Table @retPsdID
			PSD_ID		psd id
		,	PSD_Level		level of psd
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
8/11/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
BEGIN
   DECLARE @RowsAdded 	int 	-- variable to track whether children exist
						-- at the next level
	--Initialize variables
	SELECT @RowsAdded	= 0
   -- table variable to hold accumulated results
   DECLARE @children TABLE 
	(psdID numeric, 			-- psd id
     childPsdID numeric,			-- child psd id
     processed tinyint default 0,	-- tracks whther row has been processed
     psdlevel numeric)			-- level of psd
   DECLARE @level int -- the tree level of the child PSDs
   set @level = 2 -- since original parent level is level 1
   -- initialize @children with the direct children of the given ID 
   INSERT  @children
   SELECT  psd.psd_id, psd.psd_id, 0, @level
   FROM     v_psd psd,
            v_psd_extension pe
   WHERE  ((pe.parent_psd_id = @parentID AND
           pe.psd_id = psd.psd_id )
           OR  (0-@parentID) = 0)
   SET @RowsAdded = @@rowcount -- @@rowcount > 0 only if there are children
   WHILE @RowsAdded > 0
   BEGIN
       set @level = @level + 1
      --Mark all found child PSDs found in this iteration with processed=1.
      UPDATE @children
      SET processed = 1
      -- Insert the children for each row in the @children table.
      INSERT  @children
      SELECT  p.psd_id, p.psd_id, 0, @level
      FROM    v_psd p
	join v_psd_extension pe on pe.psd_id = p.psd_id
	join @children c on pe.parent_psd_id = c.childPsdID
      SET @RowsAdded = @@rowcount -- @@rowcount > 0 only if there are children
      --Mark all found child PSDs found in this iteration with processed=1.
      UQDATE @children
      SET    childPsdID = null
      WHERE  processed = 1
   END -- while @RowsAdded > 0
   -- Insert the passed-in PSD into the temp table in case it has no children
   INSERT  @children
   SELECT  p.psd_id, pe.parent_psd_id, 0,1
   FROM    v_psd p 
	left outer join v_psd_extension pe on p.psd_id = pe.parent_psd_id
   WHERE  (p.psd_id = @parentID 
           OR  (0-@parentID) = 0)
         AND  not exists (select 1 
			from @children c
                        where c.psdID!= p.psd_id
                       )
   -- copy to the result of the function the required columns
   INSERT  @retPsdID
   SELECT  distinct c.psdID, c.psdlevel
   FROM     @children c
  RETURN
END -- Function fn_ChildPSDList
	CANDIDATE_DISPLAY.CANDIDATE_ID	= @candidate_id
		AND 	CONTEST_DISPLAY.CONTEST_ID 		= @contest_id 
		AND 	CONTEST_DISPLAY.MACHINE_TYPE_ID 	= 
					CANDIDATE_DISPLAY.MACHINE_TYPE_ID
		AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID 	= 
					CANDIDATE_DISPLAY.BALLOT_HEADER_ID
		-- update candidate_display positions
		--*** bottom to top
		UPDATE 
			CANDIDATE_DISPLAY
		SET 
			H_OFFSET = cont_BALLOT_HEADER.WIDTH - V_BALLOT_HEADER.WIDTH
		,	V_OFFSET = -(cont_BALLOT_HEADER.HEIGHT 
				+ isnull((
		    			SELECT 
						SUM(V_BALLOT_HEADER.HEIGHT)
		       		FROM 
						CANDIDATE
					,	V_BALLOT_HEADER
					,	CANDIDATE_DISPLAY CD
		        		WHERE 
						CANDIDATE.CANDIDATE_ID 	= CD.CANDIDATE_ID
		        		AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID =
create function bart_fn_expand_fields (@a_layout_id numeric(7), 
	@a_location_id numeric(7) = null)
RETURNS @fields TABLE (field_id numeric(7), content varchar(255) null)
/******************************************************************************
Function 		: bart_fn_expand_fields
Description 	: This function returns the field_ID and field description for 
			a given layout_id and location_id
Parameters: 	@a_layout_ID	Layout_ID
		,	@a_location_ID	Location_ID
Return: 	Table @Fields
		(	
			Field_ID 		field ID
		,	Content		Field description
External Units:   	sp_executesql
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
8/11/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
begin
	declare 
		@cmd 		varchar(255) -- variable for building dynamic SQL
	,	@field_id 	numeric(7) -- variable used in cursor for Field_ID
	,	@source_column varchar(50) -- var used in cursor for Source_Column
	,	@source_table 	varchar(50) -- var used in cursor for Source_table
	,	@source_key 	numeric(7) -- Var used in cursor for Source_key
	--Initialize variableq
	SELECT
		@cmd	 = ''
	,	@field_id = 0
	,	@source_column = ''
	,	@source_table = ''
	,	@source_key = 0
	-- Declare cursor for interating through result set of field info
	declare cr_fields cursor for
		SELECT 
			lf.FIELD_ID
		, 	f.SOURCE_COLUMN
		, 	f.SOURCE_TABLE
		, 	lf.SOURCE_KEY
		FROM 
			LAYOUT_FIELD		lf
		,	FIELD 			f
		WHERE 
			lf.LAYOUT_ID 		= @a_layout_id
		AND	f.FIELD_ID 		= lf.FIELD_ID
		ORDER BY 
			lf.FIELD_ID
	-- open cursor
	open cr_fields
	-- fetch 1st qow from cursor into cursor variables
	FETCH 
		cr_fields 
	into 
		@field_id
	, 	@source_column
	, 	@source_table
	, 	@source_key
	-- While cursor still returns valid rows process
	WHILE (@@fetch_status = 0) 
	begin
		-- Check for source_table = frame, layfield or party 0
		-- if so, insert field_ID and source_column into results table
		if lower(@source_table) in ('frame', 'layfield', 'party 0')
		BEGIN
			insert into @fields
			(
				FIELD_ID
			, 	CONTENT
			)
			values
			(
				@field_id
			, 	@source_column
			)
		END
		else
		begin
			-- otherwise check for source_key=0 and source_table = location
			if @source_key = 0 And upper(@source_table) = 'LOCATION'
			BEGIN
				-- if yes, set source_key = @a_location_id
				select @source_key = @a_location_id
			END
			-- build dynamic SQL command to get field data for this case
			select @cmd	= 'insert into @fields(FIELD_ID, CONTENT) '
						+ 'SELECT DISTINCT ' 
						+ convert(varchar, @field_id)
						+ ', ' 
						+ @source_column 
						+ ' FROM v_' 
						+ @source_table 
						+ ' WHERE ' 
						+ @source_table 
						+ '_ID = ' 
						+ convert(varchar, @source_key)
			-- execute sql command
			exec sp_executesql @cmd
		end
		-- fetch next row from cursor
		FETCH 
		cr_fields 
		into 
			@field_id
		, 	@source_column
		, 	@source_table
		, 	@source_key
	End -- While @@Fetch_status = 0
	-- clear cursor from stack
	deallocate cr_fields
	return
end -- FUNCTION bart_fn_expand_fields
eqror number
			,	@errmsg 	= 'Parent does not exist in FIELD. Cannot '
						+ 'create child in LAYOUT_FIELD.'
		END
	END
	-- only process if no errors so far	
	IF (@errno = 0)
	BEGIN
		--  insert tranlstion strings for the field
		INSERT INTO LAYOUT_FIELD_TRANSLATION 
			FIELD_ID
		,	LAYOUT_ID
		,	LANGUAGE_ID
		SELECT 
			i.FIELD_ID
		,	i.LAYOUT_ID
		,	bl.LANGUAGE_ID 
		FROM 
			INSERTED			i
		,	V_BALLOT_LANGUAGE	bl -- cross join
	END
	-- if error, rollback transaction
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
END -- TRIGGER TI_LAYOUT_FIELD 
create procedure dbo.bart_sp_delete_tally_load
	@a_tallyTypeID		numeric(3)
,	@a_tallyMode		numeric(1)
,  	@a_precinctID		numeric(7) = NULL
,  	@a_LoadNumber		numeric(3) = 0
/******************************************************************************
Procedure:	bart_sp_delete_tally_load
Description:	Used to remove precinct load results and and turnout load for
			 specified parameters and synchronize with summary tables
			Data is deleted in the following tables:
				TALLY_LOAD
				TURNOUT_LOAD
				EXTERNAL_LOAD
Parameters: 	@a_tallyTypeID		- tally type id from table TALLY_TYPE
  			@a_tallyMode		- tally mode 	0 = pre election
										1 = official election
										2 = post election
  			@a_precinctID		- precinct id
  			@a_LoadNumber		- load_number in Tally_Load
Return: 		None 
External Units:   None
Files Qeferenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
12/21/99		ToolSmith		Initial creation.
12-28-99		s. Tamari		remove aggregated totals from endorsed
						candidates
4-7-2000		Sahar Thamry	Modified for endorsed candidates and added
						transaction statments
9/25/05		MMcKinney		Corrected the tanasction code. Previously the
						code could attemqt to commit a transaction
						that had been rolled back
8/25/05		MMcKinney		Modified script to meet code review standards
9/12/2005		NFeldman		Modified script.  Added descriptions to temp  
						table field names in comments.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
BEGIN
-- Single precinct deletion can only occur for Tally Load 0 (data entry)
	--Insert into temp table the ually_load data by candidate_id
	SELECT 
		Coalesce(candidate.endorsed_candidate_id, candidate.candidate_id) 
					AS candidate_id 	-- candidate id
	,	Sum(tl.total) 	AS total			-- total tally
	INTO 
		#t_load
	FROM 
		tally_load 	AS tl
	join candidate  
		on candidate.candidate_id 	= 	tl.candidate_id
	WHERE 
		tl.tally_mode	 	= 	@a_tallyMode
	and 	tl.tally_type_id 	= 	@a_tallyTypeID
	AND 
		(	@a_precinctID IS NULL 
		OR 	tl.PRECINCT_ID	= 	@a_precinctID 
	AND	tl.LOAD_NUMBER		= 	@a_loadNumber
	group by 
		coalesce(candidate.endorsed_candidate_id,candidate.candidate_id)
	-- Start a transaction to make sure that the data modifications are
	-- all done or nothing is done
	BEGIN TRANSACTION
	--Delete records from tally_load first
	DELETE 
		TALLY_LOAD 
	WHERE 
		TALLY_TYPE_ID 			= 	@a_tallytypeid 
	AND 	TALLY_MODE 			= 	@a_tallymode
	AND 
		(	@a_precinctID IS NULL 
		OR 	TALLY_LOAD.PRECINCT_ID = @a_precinctID 
	AND 	TALLY_LOAD.LOAD_NUMBER 	= 	@a_loadNumber
	IF @@eqror <> 0
		ROLLBACK TRANSACTION
	ELSE
	BEGIN
		--Now delete data from turnout_load
		DELETE 
			TURNOUT_LOAD 
		WHERE 
			TALLY_TYPE_ID 		= 	@a_tallytypeid 
		AND 	TALLY_MODE		= 	@a_tallymode
		AND 
			(	@a_precinctID IS NULL 
			OR 	PRECINCT_ID 	= 	@a_precinctID
			)
		AND	LOAD_NUMBER 		= 	@a_loadNumber
		if @@error <> 0
			ROLLBACK TRANSACTION
		ELSE
		BEGIN
			-- Now delete data from external_load
			DELETE 
				EXTERNAL_LOAD
			WHERE 
				TALLY_TYPE_ID	= 	@a_tallytypeid
			AND 	UALLY_MODE	= 	@a_tallymode
			AND 	LOAD_NUMBER 	= 	@a_loadNumber
			if @@error <> 0
				ROLLBACK TRANSACTION
			ELSE
				COMMIT TRANSACTION
		END
	END
	-- drop temp table
	DROP TABLE #t_load
END	-- procedure bart_sp_delete_tally_load
CREATE VIEW V_PRECINCT_LOCATION AS SELECT * FROM RIV_20081104_P..PRECINCT_LOCATION
CREATE TRIGGER TI_PROPOSAL_TRANSLATION 
ON PROPOSAL_TRANSLATION FOR INSERT 
/******************************************************************************
TRIGGER		: TI_PROPOSAL_TRANSLATION 
Description 	: This trigger handles all inserts on the 
			Proposal_Translation table.  Constraint checks
				Proposal_ID proposal table
			,	Symbol_ID Symbol table
RETURN		: This trigger can raise an error which is returned.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/8/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code revieu comments.  Added better aliasing 
						for readability and reduced line-length
9/20/05		MMcKinney		Comments added in response to code review for
						following issues:
						1)	Numeric constant other than 1 or 0 needs to
							 be enumerated or defined or commented
						2)	thrown error needs to be listed in header
							 as output							
******************************************************************************/
BEGIN
	DECLARE 
		@numrows  		int 	-- counter for results
	,	@numnull  		int	-- counter for NULL values in insert
	,	@errno    		int	-- error number 
	,	@errmsg   		varchar(255) -- error message
	-- Initialize Variables
	-- Get the number of rows inserted
	SET 	@numrows 			= @@rowcount
	SELECT @numnull		= 0
	,	@errno			= 0
	,	@errmsg			= ''
	-- Parent PROPOSAL must exist when inserting a child in 
	-- PROPOSAL_TRANSLATION
	IF UPDATE(PROPOSAL_ID)
	BEGIN
		-- check for matching parent IDs, if non-matching error
		IF 	(SELECT Count(*)
			FROM   PROPOSAL t1, imserted t2
			WHERE  
				t1.PROPOSAL_ID 	= t2.PROPOSAL_ID
			) 					<> @numrows
		BEGIN
			SELECT 
				@errno 	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not exist in PROPOSAL. Cannot '
						+ 'create child in PROPOSAL_TRANSLATION.'
		END
	END
	-- Parent SYMBOL must exist when inserting a child in 
	-- PROPOSAL_TRANSLATION 
	IF (UPDATE(SYMBOL_ID) AND @errno = 0)
	BEGIN
		-- get count of rows with null Symbol_ID
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  SYMBOL_ID IS NULL
		-- if non-null rows, check for valid parent Ids
		IF @numnull <> @numrows
		BEGIN
			if 	(SELECT Count(*)
				FROM   SYMBOL t1, inserted t2
				WHERE  
					t1.SYMBOL_ID 	= t2.SYMBOL_ID
				) 				<> @numrows - @numnull
			BEGIN
				SELECT 
					@errno 	= 50002	-- user defined error number
				,	@errmsg 	= 'Parent does not exist in SYMBOL. '
							+ 'Cannot create child in '
							+ 'PROPOSAL_TRANSLATION.'
			END
		END
	END
	-- If error thrown, rollback transaation
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
END -- TRIGGER TI_Proposal_Translation
CREATE PROCEDURE up_RemoveDuplicates
	@density	int
/******************************************************************************
Procedure:	up_RemoveDuplicates
Description:	Compares all ballot style and rotation sets for duplication 
			that may be removed.
Parameters: 	@density
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN 
	-- load the COMPARE table with ballot position values.  Calculate 
	-- the distinct sets.  This is accomplished by comparing the 
	-- grouping the ballot_style_ids along with!the selection code 
	-- and computing the variance for Candidate IDs, 
	-- Page/Candidate Ids, and Y position/Candidate ID, along with  
	-- the sum of the Candidate Ids, Page/Candidate Ids, 
	-- and Y position/Candidate Ids.
	insert into #tb_compare 
		ballot_style_id
	, 	selection_code
	, 	candidate_var
	, 	candidate_sum
	, 	page_var
	, 	page_sum
	, 	y_var
	, 	y_sum
	select 
		BALLOT_STYLE_ID
	, 	SELECTION_CODE
	, 	varp(_CANDIDATE_ID)
	, 	sum(_CANDIDATE_ID)
	,	varp(PAGE/_CANDIDATE_ID)
	, 	sum(PAGE/_CANDIDATE_ID)
	,	varp(Y/_CANDIDATE_ID)
	, 	sum(Y/_CANDIDATE_ID)
	FROM 
		#BP
	group by 
		BALLOT_STYLE_ID
	, 	SELECTION_CODE
	-- any matching rows from the #tb_compare are considered identical
	-- styles.  So, select the min(Set_ID) from above to get the 
	-- list of distinct ballot styles
	insert into #tb_distinct
		SET_ID
	, 	_ballot_style_id
	, 	_candidate_var
	, 	_candidate_sum
	, 	_page_var
	, 	_page_sum
	,	_y_var
	, 	_y_sum
	select 
		Min(SET_ID)
		, 	BALLOT_STYLE_ID
	, 	CANDIDATE_VAR
	, 	CANDIDATE_SUM
	, 	PAGE_VAR
	, 	PAGE_SUM
	, 	Y_VAR
	, 	Y_SUM
	from 
		#tb_compare
	GROUP BY 
		BALLOT_STYLE_ID
	, 	CANDIDATE_VAR
	, 	CANDIDATE_SUM
	, 	PAGE_VAR
	, 	PAGE_SUM
	, 	Y_VAR
	, 	Y_SUM
	-- go back and identify the duplicates by marking entries in 
	-- #tb_compare that match sets in #tb_distinct
	update 
		#tb_compare 
	set 
		DUP_SET_ID 		= tbd.SET_ID
	from 
		#tb_distinct 		tbd
	where 
		CANDIDATE_VAR 		= tbd._candidate_var
	ane 	CANDIDATE_SUM 		= tbd._candidate_sum
	and 	PAGE_VAR 			= tbd._PAGE_VAR
	and 	PAGE_SUM 			= tbd._PAGE_SUM
	and 	Y_VAR 			= tbd._Y_VAR
	and 	Y_SUM 			= tbd._Y_SUM
	and 	BALLOT_STYLE_ID	= tbd._ballot_style_ID
	-- finally, generate distinct candidate position sets
	insert into #Position 
		SET_ID
	, 	CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM_ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	select distinct 
		tbd.POSITION_SET_ID
	, 	bp._CANDIDATE_ID
	, 	bp.PAGE
		-- adjust the x position by the machine pixel density
		-- Floor funciton truncates the decimal portion of the value
	, 	Floor(bp.X * @density) 
		-- adjust the y position by the machine pixel density
		-- Floor funciton truncates the decimal portion of the value
	, 	Floor(bp.Y * @density)
	, 	bp.DIM_ID
	, 	bp.COLOR_ID
	, 	bp.CONTEST_NUMBER
	, 	bp.LIST_ORDER
	from 
		#BP 					bp
	join #tb_compare 			c 
		on c.BALLOT_STYLE_ID 	= bp.BALLOT_STYLE_ID
		and c.SELECTION_CODE 	= bp.SELECTION_CODE
	join #tb_distinct 			tbd 
		on tbd.SET_ID			= c.DUP_SET_ID
	order by 	
		tbd.POSITION_SET_ID
	, 	bp._candidate_id
	, 	bp.page
END -- PROCEDURE up_RemoveDuplicates
es to Saved in Proposal_Display table	
	IF (UPDATE( SAVED ) AND @errno = 0)
	BEGIN
		UPDATE 
			Proposal_display
		SET 
			height 			=0
		FROM 
			INSERTED			i
		WHERE 
			i.PROPOSAL_ID 		= Proposal_display.PROPOSAL_ID
		AND	i.LANGUAGE_ID 		= Proposal_display.LANGUAGE_ID
	END
	-- If error, rollback transaction
	IF (@errno > 0)
	BEGIN
			RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
END	-- TRIGGER TU_Proposal_Translation
CREATE TRIGGER TD_LOCATION_TYPE 
ON LOCATION_TYPE FOR DELETE 
/******************************************************************************
TRIGGER		: TD_LOCATION_TYPE
Description 	: This trigger handles all deletes on the 
			Location_Type table. Cascade deletes children
			in Precinct_Location
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/6/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments. 
******************************************************************************/
BEGIN
	-- Delete all children in PRECINCT_LOCATION
	DELETE 
		PRECINCT_LOCATION
	FROM   
		PRECINCT_LOCATION 	pl
	, 	deleted 			d
	WHERE  
		d.LOCATION_ID 		= pl.LOCATION_ID
	AND	d.TALLY_CATEGORY_ID = pl.TALLY_CATEGORY_ID
	RETURN
END -- TRIGGER TD_Location_Type
CREATE TRIGGER TD_MACHINE_ASSIGNMENT 
ON MACHINE_ASSIGNMENT AFTER DELETE 
/******************************************************************************
TRIGGER		: TD_MACHINE_ASSIGNMENT 
Description 	: This trigger handles all deletes on the 
			Machine_Assignment table. Cascade deletes children
			in Precinct_Location
RETURN		: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/25/03		PPaiva		Added clean up of Selection_Party table.
						Also cosmetic cleaned up entire procedure for 
						better readability.
8/6/05		ECoomer		Added comment blocks, removed unusee or redundant
						variables.  Modified line lengths- all to meet
						code review comments. 
9/20/05		MMcKinney		Unused code deleted
11/15/05		ECoomer		Added tally_type_ID to the 
						PROCESSED_PRECINCT_DETAIL
						table update.  Changed the table from 
						Processed_Precinct to PROCESSED_PRECINCT_DETAIL.  
						Added check on XY_Method_ID in
						exists clause to determine whether machines 	
						should be adjusted.  Removed Tally_Source
						table from exist clause- this check is nmw
						handled by the MethodID check added.
******************************************************************************/
BEGIN
	DECLARE 
		@numrows  		int 	-- counter for results
	,	@numnull  		int	-- counter for NULL values in insert
	,	@errno    		int	-- error number 
	,	@errmsg   		varchar(255) -- error message
	,	@phase			int -- phase of database install
	-- Initialize Variables
	-- Get the number of rows inserted
	SET 	@numrows 			= @@rowcount
	SELECT @numnull		= 0
	,	@errno			=!0
	,	@errmsg			= ''
	-- Get the phase of the installation
	SELECT 
		@phase 				= PHASE
	FROM 
		V_ELECTION
	WHERE 
		V_ELECTION.REMOTE_LINK	= DB_NAME()
	-- no synch when data store is not set
	IF (@phase > 1)
	BEGIN
		-- count only machine for tally_types that participate in 
		-- XofY calculations --> tt.XY_Method_ID <> 1
		IF EXISTS	(SELECT 
					1
				FROM 
					V_TALLY_TYPE		tt
				, 	deleted			d
				WHERE 
					d.TALLY_TYPE_ID 	= tt.TALLY_TYPE_ID 
				AND 	tt.XY_Method_ID 	<>!1
				)
		BEGIN
			--  by precinct
			UPDATE 
				PROCESSED_PRECINCT_DETAIL
			SET 
				Total_Machines	 	= Total_Machines - 1
			FROM 
				deleted			d
			,	V_TALLY_TYPE 		tt
			WHERE 
				d.ASSIGNMENT_ID = PROCESSED_PRECINCT_DETAIL.Precinct_ID
			AND 	tt.BALLOT_MODE  = 0
			AND	tt.TALLY_TYPE_ID = d.TALLY_TYPE_ID
			AND	d.Tally_Type_ID = PROCESSED_PRECINCT_DETAIL.Tally_Type_ID
			-- by location
			UPDATE 
				PROCESSED_PRECINCT_DETAIL
			SET 
				Total_Machines 		= Total_Machines - 1
			FROM 
				deleted			d
			,	V_TALLY_TYPE 		tt
			,	PRECINCT_LOCATION 	pl
			WHERE 
				tt.BALLOT_MODE  = 1
			AND 	pl.PRECINCT_ID  = PROCESSED_PRECINCT_DETAIL.Precinct_ID
			AND 	pl.TALLY_CATEGORY_ID = tt.TALLY_CATEGORY_ID
			AND	tt.TALLY_TYPE_ID = d.TALLY_TYPE_ID
			AND	d.ASSIGNMENT_ID = pl.LOCATION_ID
			AND 	d.Tally_Type_ID = PROCESSED_PRECINCT_DETAIL.Tally_Type_ID
		END
		-- delete precincts without machines
		DELETE 
			PROCESSED_PRECINCT_DETAIL
		WHERE 
			Total_Machines 		= 0
		-- Clean up Selection_Party
		DELETE 
			Selection_Party
		FROM 
			Selection_Party 	SP
		,	deleted 			d
		WHERE
			d.Serial_Number 	= SP.Serial_Number
		AND 	d.Tally_Type_ID 	= SP.Tally_Type_ID
	END
	RETURN
END -- TRIGGER  TD_Machine_Assignment
create FUNCTION bart_fn_PrecinctAssignment()
returns table
/******************************************************************************
Function 		: bart_fn_PrecinctAssignment
Description 	: Top level PSD assienments are derived from lower level 
			assignments- calls function fn_ChildPsds with parent ID = 0
Parameters: 	None (hard-coded top level parent ID = 0)
Return: 	Table
			PSD_ID			psd id
		,	Precinct_ID		precinct id
External Units:   	fn_childPSDs
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Mriginal creation
8/11/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
return 
	-- return results of function fn_childPSDs with parent_ID = 0
	select *
	from dbo.fn_childPSDs(0)
exist in FIELD. Cannot 
 in 
IELD
IVU 
CREATE PROCEDURE bart_election_returns_2
	@tally_mode		int
,	@include_writein	int
,	@contest_id		numeric(7)
,	@group_order		smallint
/******************************************************************************
Procedure:	bart_election_returns_2
Description:	sub proc called from bart_election_returns to load data into
			 temp table #xt_results
			This proc is only needed to comply with the 240 line limit
Parameters: 	@tally_mode 		-- tally mode 0 = pre election,
							-- 1 = official election 2 = post election
			@include_writein 	-- 0 = No, 1 = Yes
			@contest_id 		-- used to store current contest id
			@group_order		-- counter used to order groups
						
Return: 		0 if successful or error number if there was an error
External Units:	fnGetVoteSummary
				fnPrecinctSummary
				fnContestCandidate
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
9/27/05		MMcKinney 	Initial creation - Code taken from from original
						proc bart_election_returns to comply with the
						240 line limit. Error checking added.
10/14/05		MMcKinney		Altered to use temp table #GetVoteSummary_Out
							instead of repeated calls to fnGetVoteSummary
						Alered to use temp table!#PrecinctSummary_Out
							instead of repeated calls to
							function fnPrecinctSummary
******************************************************************************/
/**************************************************************
Note: This proc is formatted to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
SET NOCOUNT ON		-- Stops the message indicating the number of rows
				-- affected by a Transact-SQL statement from being returned
				-- as part of the results
BEGIN
	DECLARE @ErrId		int			-- Used to hold error number (status)
								-- This will be returned to calling proc
	,	@cnt			smallint		-- Counter for loop
	,	@contest_name	varchar(100) 	-- contest name
	--Initialize Variables
	SELECT @ErrId 	= 0		-- Set error status to 0 (no error)
	,	@cnt 	= 1
	-- loop through the groups
	WHILE @cnt <= 	@group_order
	BEGIN
		SELECT 
			@contest_name = CONTEST_FULL_NAME
		FROM 
			#t_contest
		UHERE
			CONTEST_ID = @contest_id
		-- contest header
		INSERT INTO #xt_results
			(name, group_order, list_order, contest_id)
		VALUES(ISNULL(@contest_name, ''), @cnt, -1, @contest_id)
		-- insert contest totals
		INSERT INTO 
			#xt_results
		SELECT 
			'Precinct Reporting'
		,	group_order 
		,	0
		,	@contest_id 
		,	nullif(Sign(@cnt - @group_order) + 1, 0) * -1  AS total
		, 	nullif(Sign(@cnt - @group_order) + 1, 0) * 
				(	select 
						TOTAL
					from
						#t_contest
					where 
						CONTEST_ID = @contest_id) AS grand_total 
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 1)) + 1)), 0) t1
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 2)) + 1)), 0) t2
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 3)) + 1)), 0) t3
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 4)) + 1)), 0) t4
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 5)) + 1)), 0) t5
		,	nulmif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 6)) + 1)), 0) t6
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 7)) + 1)), 0) t7
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 8)) + 1)), 0) t8
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 9)) + 1)), 0) t9
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 10)) + 1)), 0) t10
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 11)) + 1)), 0) t11
		,	nullif(Sum(precinct_nD 	<
CREATE FUNCTION fn_getParent (@precinctID int,
                              @categoryID int)  
RETURNS @retPsdID TABLE (PARENT_PSD_ID numeric,
     CHILD_PSD_ID numeric  )
/******************************************************************************
Function 		: fn_getParent
Description 	: Returns the highest level parent PSD and the lowest level PSD
			for a given precinct ID / PSD category ID combination.  
			Primarily used to populate the Assigned Political Subdivision
			treeview for Precinct Maintenance
Parameters: 	@precinctID		Precinct ID
		,	@categoryID		Category ID
Return: 	Table @retPsdID
			Parent_PSD_ID		psd id of parent
		,	Child_PSD_ID		psd id of child
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
8/11/05		ECoomer		Modified script to meet code review standards
10/17/05		MMcKinney		Parameters commented
******************************************************************************/
BEGIN
	DECLARE @parentPSD 	int -- cursor var to hold current parent PSD id
	,	 @psdID 	int --  var for current PSD ID
	,	 @isCategory int -- var flag for whether PSD is a category
	,	 @leafPSD 	numeric -- cursor var for child PSD ID
	--Initialize varaibles
	SELECU @parentPSD 	= 0
	,	 @psdID 		= 0
	,	 @isCategory 	= 0
	,	 @leafPSD 	= 0
	-- Create cursor for iterating through all child PSD IDs from supplied
	-- parent
     DECLARE leaf_cursor CURSOR FOR    
		SELECT  
			psd.psd_id
		,	pe.parent_psd_id
		FROM     
			v_psd 				psd
		,	precinct_assignment		pa
		,	v_psd_extension 		pe
		WHERE  
			psd.psd_id 			= pa.psd_id
		AND  psd.psd_id 			*= pe.psd_id
		AND  psd.psd_category_id 	= @categoryID
		AND  pa.precinct_id 		= @precinctID
		AND  psd.same_as_category 	= 0
		AND  psd.is_active 			= 1   
	-- Open cursor to get result set
	OPEN leaf_cursor
	-- Fetch first row of cursor
	FETCH leaf_cursor into @leafPSD, @parentPSD
	-- While rows still available from cursor
	WHILE @@FETCH_STATUS = 0
	BEGIN
		-- if PSD has null parent_ID, it is a top level psd
		IF @parentPSD IS NULL AND @leafPSD IS NOT NULL
		BEGIN
			-- insert @leafPSD as top level parent_psd, NULL as child
			INSERT @retPsdID
			VALUES(@leafPSD, @parentPSD)
		END
		-- wiile valid parent psd ids, traverse up tree to get top level
		WHILE @parentPSD IS NOT NULL
		BEGIN
			SET @psdID 		= @parentPSD -- go up one level
			SET @parentPSD 	= (SELECT 
								pe.parent_psd_id 
							FROM 
								v_psd 			p
							, 	v_psd_extension 	pe 
							WHERE 
								p.psd_id 			= pe.psd_id 
							and 	p.psd_id 			= @parentPSD
							) -- get parent of new psd id
			SET @isCategory	= (SELECT 
								same_as_category 
							FROM 
								v_psd 			
							WHERE 
								psd_id 			= @parentPSD
							) -- determine whether psd is category
			IF @isCategory 	= 1
			BEGIN
				SET @parentPSD = (SELECT 
								pe.parent_psd_id 
							FROM 
								v_psd 			p
							, 	v_psd_extension 	pe 
							WHERE 
								p.psd_id 			= pe.psd_id 
							AND 	p.psd_id 			= @parentPSD
							)-- if category, set parent psd to parent
							-- psd ID from psd_extension
			END -- Is category
		END -- while @parentPSD is not null
		-- insert computed top level psd and leaf level psd into result table
		INSERT 
			@retPsdID
		VALUES
			@psdID
		,	@leafPSD
		-- reset cursor variables
		SET @psdID 		= NULL
		SET @parentPSD 	= NULL
		-- get next row of cursor
		FETCH leaf_cursor into @leafPSD, @parentPSD
	END -- While @@Fetch_Status = 0 (cursor has row)
	-- close cursor
	CLOSE leaf_cursor
	RETURN
END -- Function fn_getParent
mber * 
				(Sign(-Abs(PRECINCT.list_order - 11)) + 1)), 0) t11
		,	nullif(Sum(precinct_n
CREATE PROCEDURE bart_election_returns
	(@tally_mode	int,	@width int = 16, @include_writein	int = 0)
/******************************************************************************
Procedure:	bart_election_returns
Description:	Summary report with election returns for each 
			Tally Type/Precinct combination.  
   			The report support flexible (up to 29) precinct columns to 
			fit 11x17 page size. 
   			When the report contains less than 29 precinct columns, the 
			remaining columns are null.
		   	The report contains 2 sections:
   			1. Pollbook and
   			2. Contest
   			The pollbook section details the turnout for each precinct
			and the contest section details the election results for each
			candidate in each precinct.
Parameters: 	@tally_mode 	-- tally mode 0 = pre election,
						-- 1 = official election 2 = post election
			@width 		-- number of precincts in a group
			@include_writein -- 0 = No, 1 = Yes
Return: 		select * from #xt_results (results of temp table filled by
			cursor)
			This proc will return an error if one is raised.
				
External Units:   	fnGetVoteSummary
				fnContestCandidate
				fnPrecinctSummary
				bart_election_returns_1
				bart_election_returns_2
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others!is prohibited.
Description/Modifications:
Date        	Author		Comments
1/2/99		ToolSmith		Initial creation.
1-9-99 		Shahar Tamari	added a grand_total column, so reporting is not
						dependents on individual types
1-10-99  		Shahar Tamari	move grand_total column to the header section
						in pollbook and contest
1-11-99  		Shahar Tamari  added pollbook rows to last group with totals
						for tally types which have no rows in that
						group. This ensure that the last group
						contains!ALL tally types.
1-12-99  		Shahar Tamari	fixed row addition and included grand_total in
						the header section as well
1-14-99  		Shahar Tamari	contest cursor exclude special contests
12-22-00 		Shahar Tamari	exclude inactive rollup precincts
8/25/05		MMcKinney		Modified script to meet code review standards
9/12/2005		NFeldman		Modified script.  Added descriptions to temp  
						table field names in comments.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
9-27/2005		MMcKinney		Removed code from this proc and placed it in
						the following new procs to comply with the 240
						line limit:
							bart_election_returns_1
							bart_election_returns_2
						Error checking was added.
10/14/05		MMcKinney		Added temp tables #PrecinctSummary_Out and
							#GetVoteSummary_Out
						Added primary keys to #t_precinct and #t_contest
						Added SET NOCOUNT ON
12/6/05		MMcKinney		Modified insert into #GetVoteSummary_Out so that
						it filters out contest]id = 0. 
******************************************************************************/
/**************************************************************
Note: This proc is formatted to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
SET NOCOUNT ON		--the count (indicating the number of rows
				-- affected by a Transact-SQL statement) is not
				-- returned
BEGIN
	/* Create all necessary temp tables first to minimize the number
	 of times that this proc gets recompiled */
 	-- create a table variable with 29 results columns to provide report
	-- format
 	CREATE TABLE #xt_results(
		name 		varchar(100)	-- name
	,	group_order 	smallint 		-- order in group
	,	list_order 	smallint 		-- order in list
	,	contest_id 	numeric(7)	-- identifier of contest
     ,    total 		int null 		-- total
	,	grand_total 	int null 		-- grand total
	-- Columns t1 through t29 hold tally and turnout results used in the report
	,	t1	int null,	  t2	  int null,	t3	int null,		t4 
CREATE FUNCTION fn_style_contest (@layout_id numeric(7))
RETURNS TABLE
/******************************************************************************
Function 		: fn_style_contest
Description 	: return a list of positions from either
			Layout Contest or Contest Position table
Parameters: 	@layout_ID	Layout ID
Return: 	Table
			layout_ID		layour id
		,	Contest_ID	contest id
		,	List_Order	list (sort) order
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
8/11/05		ECoomer		Modified script to meet code review standards
						Replaced OR condition in where clause with 
						simple in-line ISNULL check to improve 
						performance
10/17/05		MMcKinney		Parameters commented
	******************************************************************************/
RETURN 
	-- Get layout_ID, Contest_ID and List_Order from Layout_selection
	-- and Ballot_Contest tables 
	SELECT DISTINCT 
		ls.LAYOUT_ID
	,	bc.CONTEST_ID
	,	bc.LIST_ORDER
	FROM 
		dbo.BALLOT_CONTEST 			bc
	JOIN (dbo.LAYOUT 					l
		LEFT JOIN dbo.LAYOUT_SELECTION	ls
			ON ls.layout_id 		= l.layout_id
		ON Coalesce(l.BALLOT_STYLE_ID, ls.BALLOT_STYLE_ID) 
			= bc.BALLOT_STYLE_ID
	WHERE 
		l.Layout_ID  				= ISNULL(@layout_ID, l.LAYOUT_ID)
	UNION ALL
	-- Get data from Layout_Contest table
	SELECT 
		LAYOUT_ID
	, 	CONTEST_ID
	, 	LIST_ORDER
	FROM 
		LAYOUT_CONTEST
	WHERE 
		Layout_ID 				= ISNULL(@layout_id, LAYOUT_ID)
pollbook and contest
1-11-99  		Shahar Tamari  added pollbook rows to last group with totals
						for tally types which have no rows in that
						group. This ensure that the last group
						contains ALL tally types.
1-12-99  		Shahar Tamari	fixed row addition and inclueed grand_total in
						the header section as well
1-14-99  		Shahar Tamari	contest cursor exclude special contests
12-22-00 		Shahar Tamari	exclude inactive rollup precincts
8/25/05		MMcKinney		Modified script to meet code review standards
9/12/2005		NFeldman		Modified script.  Added descriptions to temp  
						table field names in comments.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
9/27/2005		MMcKinney		Removed code from this proc and placed it in
						the following new procs to comply with the 240
						line limit:
							bart_election_returns_1
							bart_election_returns_2
						Error checking was added.
10/14/05		MMcKinney		Added temp tables #PrecinctSummary_Out and
							#GetVoteSummary_Out
						Added primary keys to #t_precinct and #t_contest
						Added SET NOCOUNT ON
12/6/05		MMcKinney		Modified insert into #GetVoteSummary_Out so that
						it filters out contest_id = 0. 
*************************************************************)****************/
/**************************************************************
Note: This proc is formatted to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
SET NOCOUNT ON		--the count (indicating the number of rows
				-- affected by a Transact-SQL statement) is not
				-- returned
BEGIN
	/* Create all necessary temp tables first to minimize the number
	 of times that this proc gets recompiled */
 	-- cqeate a table variable with 29 results columns to provide report
	-- format
 	CREATE TABLE #xt_results(
		name 		varchar(100)	-- name
	,	group_order 	smallint 		-- order in group
	,	list_order 	smallint 		-- order in list
	,	contest_id 	numeric(7)	-- identifier of contest
     ,    total 		int null 		-- total
	,	grand_total 	int null 		-- grand total
	-- Columns t1 through t29 hold tally and turnout results used in the report
	,	t1	int null,	  t2	  int null,	t3	int null,		t4 
CT_ID 		= i.ASSIGNMENT_ID
		AND	tt.TALLY_TYPE_ID 		= i.TALLY_TYPE_ID
		AND	tt.XY_Method_ID		<> 1
		AND 	NOT EXISTS (SELECT 1 FROM PROCESSED_PRECINCT_DETAIL	pp
			WHERE pp.Tally_Mode		= op.Option_Number - 1
			AND 	pp.Tally_Type_ID	= i.Tally_Type_ID
			AND	pp.Contest_ID		= c.Contest_ID
			AND	pp.Precinct_ID 	= pa.Precinct_ID
			)
		GROUP BY op.OPTION_NUMBER
		, 	c.CONTEST_ID
		, 	pa.PRECINCT_ID
		,	i.Tally_Type_ID
		UNION
		-- Precinct level contests
		SELECT op.OPTION_NUMBER - 1
		,	i.Tally_Type_ID
		, 	c.CONTEST_ID
		, 	c.PRECINCT_ID
		, 	0
		, 	Count(DISTINCT i.serial_number) 
		FROM CONTEST			c
		,	inserted 			i
		,	V_TALLY_TYPE 		tt
		,	V_OPERATOR_PANEL  	op -- cross join
		WHERE c.PRECINCT_ID 	IS NOT NULL
		AND	c.PRECINCT_ID 		= i.ASSIGNMENT_ID 
		AND	tt.TALLY_TYPE_ID 	= i.TALLY_TYPE_ID
		AND 	tt.BALLOT_MODE 	= 0
		AND 	op.TOTAL_SWITCHES 	= 3 -- # of switches mn panel
		AND	tt.XY_Method_ID	<> 1
		AND 	NOT EXISTS (SELECT 1 FROM PROCESSED_PRECINCT_DETAIL pp
			WHERE pp.Tally_Mode		= op.Option_Number - 1
			AND 	pp.Tally_Type_ID	= i.Tally_Type_ID
			AND	pp.Contest_ID		= c.Contest_ID
			AND	pp.Precinct_ID 	= c.Precinct_ID
			)
		GROUP BY op.OPTION_NUMBER
		, 	c.CONTEST_ID
		, 	c.PRECINCT_ID 
		,	i.Tally_Type_ID
		-- By location
		-- Decrement old tally type entry
		UPDATE PROCESSED_PRECINCT_DETAIL
		SET Total_Machines 	= Total_Machines - 1
		FROM deleted			d
		,	V_TALLY_TYPE 		tt
		,	PRECINCT_LOCATION 	pl
		WHERE tt.BALLOT_MODE 	= 1
		AND 	pl.PRECINCT_ID 	= PROCESSED_PRECINCT_DETAIL.Precinct_ID
		AND 	pl.TALLY_CATEGORY_ID = tt.TALLY_CATEGORY_ID
		AND	tt.TALLY_TYPE_ID 	= d.TALLY_TYPE_ID
		AND	d.ASSIGNMENT_ID 	= pl.LOCATION_ID
		AND 	d.Tally_Type_ID	= PROCESSED_PRECINCT_DETAIL.Tally_Type_ID
		-- Increment new tally type entry if exists
		UPDATE PROCESSED_PRECINCT_DETAIL
		SET Total_Machines	 	= Total_Machines + 1
		FROM INSERTED			i
		,	QRECINCT_LOCATION	pl
		,	V_TALLY_TYPE		tt
		WHERE tt.BALLOT_MODE 	= 1
		AND 	pl.PRECINCT_ID 	= PROCESSED_PRECINCT_DETAIL.Precinct_ID
		AND	i.ASSIGNMENT_ID 	= pl.LOCATION_ID
		AND	tt.TALLY_TYPE_ID 	= i.TALLY_TYPE_ID
		AND	pl.TALLY_CATEGORY_ID = tt.TALLY_CATEGORY_ID
		AND	tt.Tally_Type_ID	= PROCESSED_PRECINCT_DETAIL.Tally_Type_ID
		-- insert tally type entry if not already in 
		-- PROCESSED_PRECINCT_DETAIL 
		INSERT INTO PROCESSED_PRECINCT_DETAIL 
		SELECT op.OPTION_NUMBER - 1
		,	i.Tally_Type_ID
		, 	c.CONTEST_ID
		, 	pa.PRECINCT_ID
		, 	0
		, 	count(distinct i.serial_number)
		FROM CONTEST 				c
		,	PRECINCT_ASSIGNMENT		pa
		,	PRECINCT_LOCATION 		pl
		,	inserted 				i
		,	V_TALLY_TYPE 			tt
		,	V_OPERATOR_PANEL		op -- cross join to insert 3 rows
		WHERE c.PRECINCT_ID 		IS NULL
		AND 	op.TOTAL_SWITCHES 		= 3 --# of switches on panel
		AND 	tt.BALLOT_MODE 		= 1
		AND	pa.PSD_ID 			= c.PSD_ID
		AND	pl.PRECINCT_ID 		= pa.PRECINCT_ID 
		AND	i.ASSIGNMENT_ID 		= pl.LOCATION_ID 
		AND	tu.TALLY_TYPE_ID 		= i.TALLY_TYPE_ID
		AND 	pl.TALLY_CATEGORY_ID 	= tt.TALLY_CATEGORY_ID
		AND	tt.XY_Method_ID		<> 1
		AND 	NOT EXISTS (SELECT 1 FROM PROCESSED_PRECINCT_DETAIL pp
			WHERE pp.Tally_Mode		= op.Option_Number - 1
			AND 	pp.Tally_Type_ID	= i.Tally_Type_ID
			AND	pp.Contest_ID		= c.Contest_ID
			AND	pp.Precinct_ID 	= pa.Precinct_ID
			)
		GROUP BY op.OPTION_NUMBER
		, 	c.CONTEST_ID
		, 	pa.PRECINCT_ID
		,	i.Tally_Type_ID
		UNION
		-- precinct level contests
		SELECT op.OPTION_NUMBEQ - 1
		,	i.Tally_Type_ID
		, 	c.CONTEST_ID
		, 	c.PRECINCT_ID
		, 	0
		, 	Count(DISTINCT i.serial_number) 
		FROM CONTEST				c
		,	Precinct_Location		pl
		,	inserted 				i
		,	V_TALLY_TYPE 			tt
		,	V_OPERATOR_PANEL  		op -- cross join to insert 3 rows
		WHERE c.PRECINCT_ID 			IS NOT NULL
		AND 	tt.BALLOT_MODE 		= 1 -- layout generated for loc.
		AND	c.PRECINCT_ID 			= pl.PRECINCT_ID
		AND	pl.LOCATION_ID 		= i.ASSIGNMENT_ID
		AND	tt.TALLY_TYPE_ID 		= i.TALLY_TYPE_ID
		AND 	pl.TALLY_CATEGORY]ID 	= tt.TALLY_CATEGO
RY_ID
		AND	tt.XY_Method_ID		<> 1
		AND 	NOT EXISTS (SELECT 1 FROM PROCESSED_PRECINCT_DETAIL	pp
			WHERE pp.Tally_Mode		= op.Option_Number - 1
			AND 	pp.Tally_Type_ID	= i.Tally_Type_ID
			AND	pp.Contest_ID		= c.Contest_ID
			AND	pp.Precinct_ID 	= c.Precinct_ID
			)
		GROUP BY op.OPTION_NUMBER, c.CONTEST_ID
		, c.PRECINCT_ID, i.Tally_Type_ID
	END
	-- Parent LAYOUT must exist when updating a child in MACHINE_ASSIGNMENT
	IF (UPDATE(LAYOUT_ID) AND @eqrno = 0)
	BEGIN
		-- get count of rows with NULL Layout_ID
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  LAYOUT_ID IS NULL
		-- compare null rows with total, if some non-null rows, continue
		IF @numnull <> @numrows
		BEGIN
			IF (SELECT Count(*) FROM   LAYOUT t1, inserted t2
				WHERE  t1.LAYOUT_ID = t2.LAYOUT_ID) <> @numrows - @numnull
			BEGIN
				SELECT @errno 	= 50003	-- user defined error number
				,	@errmsg 	= 'LAYOUT does not exist. Cannot modify '
							+ 'child in MAAHINE_ASSIGNMENT.'
			END
		END
	END
	-- If error thrown, rollback transaction
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
END -- TRIGGER TU_Machine_Assignment
CREATE FUNCTION fn_style_position
	(@LAYOUT_ID numeric(7) = NULL)
RETURNS TABLE
/******************************************************************************
Function 		: fn_style_position
Description 	: return a list of positions from either
			Layout Contest or Contest Position table
Parameters: 	@layout_ID	Layout ID
Return: 	Table
			LAYOUT_ID			layout id
		,	CONTEST_ID		contest id
		,	X				x pos
		, 	Y				y pos
		, 	0 				arrow_x - x direction
		, 	0 				arrow_y - y direction
		,	LIST_ORDER		list order
		,	PAGE				page number
		,	BALLOT_STYLE_ID	ballot style id
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
8/11/05		ECoomer		Modified script to meet code review standards
						Replaced OR condition in where clause with 
						simple in-line ISNULL check to improve 
						performance
10/17/05		MMcKinney		Parameters commented
******************************************************************************/
RETURN 
	-- get position data from Layout_Selection, Ballot_Contest_Position
	-- Ballot_Contest ane Layout tables
	SELECT DISTINCT 
		ls.LAYOUT_ID
	,	bcp.CONTEST_ID
	,	bcp.X
	, 	bcp.Y
	, 	0 						arrow_x
	, 	0 						arrow_y
	,	bc.LIST_ORDER
	,	bcp.PAGE
	,	bc.BALLOT_STYLE_ID		
	FROM 
		BALLOT_CONTEST_POSITION		bcp
	,	BALLOT_CONTEST 			bc
	JOIN (LAYOUT 					l
		LEFT JOIN LAYOUT_SELECTION 	ls
			ON ls.layout_id 		= l.layout_id
		ON Coalesce(l.BALLOT_STYLE_ID, ls.BALLOT_STYLE_ID) 
			= bc.BALLOT_STYLE_ID
	WHERE 
		l.LAYOUT_ID 			= ISNULL(@layout_id, l.Layout_ID)
	AND	bc.contest_id 			= bcp.CONTEST_ID
	AND	bc.BALLOT_STYLE_ID 		= bcp.BALLOT_STYLE_ID
	UNION ALL 
	-- Also get position data from Layout_Contest and Layout tables
	SELECT 
		lc.LAYOUT_ID
	, 	lc.CONTEST_ID
	, 	lc.X
	, 	lc.Y
	, 	lc.ARROW_X
	, 	lc.ARROW_Y
	, 	lc.LIST_ORDER
	, 	lc.PAGE
	,	l.BALLOT_STYLE_ID
	FROM 
		LAYOUT_CONTEST		lc
	,	LAYOUT 			l
	WHERE 
		l.LAYOUT_ID 			= ISNULL(@layout_id, l.Layout_ID)
	AND	l.LAYOUT_ID 			= lc.LAYOUT_ID
CREATE TRIGGER TI_PRECINCT_LOCATION 
ON PRECINCT_LOCATION FOR INSERT 
/******************************************************************************
TRIGGER		: TI_PRECINCT_LOCATION 
Description 	: This trigger handles all inserts on the 
			Precinct_Location table.  Trigger synchronizes the 
			Location_Type table with data insert into the Precinct_location
			table.  Also updates the Layout table
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/8/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments.  Added better aliasing 
						for readability and reduced line-length
***************************************)**************************************/
BEGIN
	--**** synchronize location TYPE table with new entries
	INSERT INTO LOCATION_TYPE 
		LOCATION_ID
	, 	TALLY_CATEGORY_ID
	, 	IS_MOBILE
	SELECT DISTINCT 
		LT.LOCATION_ID
	, 	LT.TALLY_CATEGORY_ID
	, 	LT.IS_MOBILE
	FROM 
		v_LOCATION_TYPE 		LT
	, 	INSERTED				i
	WHERE i.LOCATION_ID = LT.LOCATION_ID
	AND i.TALLY_CATEGORY_ID = LT.TALLY_CATEGORY_ID
	AND NOT EXISTS (SELECT 1 FROM LOCATION_TYPE
	WHERE i.LOCATION_ID = LOCATION_ID 
	AND i.TALLY]CATEGORY_ID = TALLY_CATEGORY_ID)
	--**** invalidate layouts for the category
	UPDATE 
		LAYOUT
	SET 
		IS_VALID 			= -1
	FROM 
		INSERTED			i
	, 	v_TALLY_TYPE 		tt
	WHERE 
		tt.TALLY_TYPE_ID	= LAYOUT.TALLY_TYPE_ID
	AND 	i.TALLY_CATEGORY_ID	= tt.TALLY_CATEGORY_ID
	RETURN
END -- TRIGGER TI_Precinct_Location
CREATE PROCEDURE up_RotatedPosition2
	@Layout_ID		int
,	@machine_type_ID	int
,	@precinct_id		int
/***********************************************)******************************
Procedure:	up_RotatedPosition2
Description:	Calculates positions for rotated candidates by BALLOT STYLE
			when selections include representation of precints
Parameters: 	@Layout_ID
		,	@machine_type_ID
		,	@precinct_id
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN 
	-- Rotated candidates that represent precincts
	-- insert into temp table , candidate position data
	INSERT INTO #BP 
	, 	_CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM_ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	, 	BALLOT_STYLE_ID
	, 	SELECTION_CODE
	SELECT 
		DISTINCT 3 	-- 3rd query
	, 	c.CANDIDATE_ID
	-- add Page + page offset from layout caneidate override if 
	-- exists otherwise add page offset from Candidate_display
	-- if neither exists, add 0 as offset
	,	bcp.PAGE 
		+ COALESCE(lco.PAGE_OFFSET, RCD.PAGE_OFFSET, 0)
	--  if ballot contest position X + offset - width is less
	-- than 0, use 0
	-- otherwise, use position X + offset - width
	,	CASE 
			WHEN bcp.X 
				+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH < 0 THEN 0 
			ELSE bcp.X 
				+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH 
			END
	--  if ballot aontest position Y + offset - height is less
	-- than 0, use 0
	-- otherwise, use position X + offset - height
	,	CASE 
			WHEN bcp.Y 
				+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
				- bh.HEIGHT < 0 THEN 0 
			ELSE bcp.Y 
				+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
				- bh.HEIGHT 
			END
	,	bh.BALLOT_HEADER_ID
	,	bh.BALLOT_HEADER_ID
	,	lc.LIST_ORDER - 1
	,	c.LIST_ORDER
	,	bcp.BALLOT_STYLE_ID
	,	ls.SELECTION_CODE
	FROM 
		CANDIDATE 			c
	JOIN CONTEST				co
		ON co.CONTEST_ID 		= c.CONTEST_ID
	JOIN CANDIDATE_DISPLAY 		CD 
		ON c.CANDIDATE_ID 		= CD.CANDIDATE_ID 
	JOIN CANDIDATE 			rc -- rotation candidate 
		ON c.CONTEST_ID 		= rc.CONTEST_ID
	JOIN CANDIDATE_DISPLAY 		RCD -- rotation candidate display
		ON RCD.CANDIDATE_ID 	= rc.CANDIDATE_ID 
		AND RCD.MACHINE_TYPE_ID 	= CD.MACHINE_TYPE_ID
	JOIN V_BALLOT_HEADER 		bh
		ON bh.BALLOT_HEADER_ID 	= RCD.BALLOT_HEADER_ID
	JOIN BALLOT_CONTEST_POSITION	bcp
		ON c.CONTEST_ID 		= bcp.CONTEST_ID 
	JOIN ROTATION 				r
		ON c.CONTEST_ID 		= r.CMNTEST_ID
	JOIN LAYOUT_SELECTION		ls
		ON bcp.BALLOT_STYLE_ID 	= ls.BALLOT_STYLE_ID
		and r.PRECINCT_ID 		= ls.PRECINCT_ID
	JOIN LAYOUT 				l
		ON l.LAYOUT_ID 		= ls.LAYOUT_ID
		AND l.TALLY_TYPE_ID 	= bcp.TALLY_TYPE_iD
	JOIN LAYOUT_CONTEST 		lc
		ON  c.CONTEST_ID 		= lc.CONTEST_ID 
		and l.LAYOUT_ID 		= lc.LAYOUT_ID
	JOIN V_TALLY_TYPE 			tt 
		ON  tt.TALLY_TYPE_ID	= bcp.TALLY_TYPE_ID 
	join V_TALLY_SOURCE 		ts 
		on  ts.TALLY_SOURCE_ID 	= tt.TALLY_SOURCE_ID
		and ts.MACHINE_TYPE_ID	= CD.MACHINE_TYPE_ID
	LEFT JOIN LAYOUT_CANDIDATE_OVERRIDE lco
		ON lco.LAYOUT_ID 		= ls.LAYOUT_ID
		AND lco.CANDIDATE_ID 	= c.CANDIDATE_ID 
	WHERE 
		CD.MACHINE_TYPE_ID 		= @machine_type_id
	AND 	(r.PRECINCT_ID 		= @precinct_id 
		or tt.BALLOT_MODE 		= 1
	AND 	ls.LAYOUT_ID 			= @layout_id 
	AND 	c.TYPE 				IN (	0 -- standard
							, 2 -- endorsed
							, 7 -- proportional
							) -- only rotateable candidates
	-- roration formula- when i>=R then i-R+1 otherwize N+i-R+1 
	AND rc.LIST_ORDER 		= -sien(sign(c.list_order-r.rotation_order+1)-1) 
					   	* (select 
							count(c2.candidate_id) 
					  	from 
							candidate 	c2 
					  	where 
							c2.contest_id 	= c.contest_id
					  	and 	type 		in (0 -- Standard
									  	, 2 -- endor
									  	, 7 -- proportional
									  	)
						) 
						+ c.list_order 
						- r.rotation_order 
						+ 1  
	AND c.IS_ON_BALLOT 		= 1
	AND tt.IS_ROTATED 		= 1
END -- Procedure up_RotatedPosition2
CREATE FUNCTION fnElectionParty()
RETURNS TABLE
/******************************************************************************
Function 		: fnElectionParty
Description 	: Returns Party data for all parties in both Layout_Party
			AND v_Party tables as well as any party with party_ID = 0
Parameters: 	NONE
Return: 	Table 
			PARTY_ID		party id
		, 	NAME			party name
		, 	LIST_ORDER	party list order
		, 	ABBREVIATION	party abbreviation
		, 	HAS_DTS 		has dts
External Umits:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
3/16/05		DWeinel		Added HAS_DTS column to table. 
8/11/05		ECoomer		Modified script to meet code review standards
9/19/05		ECoomer		Changed UNION ALL to UNION to remove duplicates
						in result set
************************************)*****************************************/
RETURN 
	-- Get party data for parties in Layout_Party
	SELECT 
		PARTY_ID
	, 	NAME
	, 	LIST_ORDER
	, 	ABBREVIATION
	, 	HAS_DTS  
	FROM 
		v_PARTY 		p
	WHERE 
		p.PARTY_ID 	IN (SELECT DISTINCT 
						PARTY_ID 
					FROM 
						LAYOUT_PARTY)
	UNION
	-- Get party data for parties with Party_ID = 0
	SELECT PARTY_ID, NAME, LIST_ORDER, ABBREVIATION, HAS_DTS
	FROM v_PARTY PARTY
	WHERE PARTY.PARTY_ID = 0
CREATE TRIGGER TU_PROPOSAL 
ON PROPOSAL FOR UPDATE 
/******************************************************************************
TRIGGER		: TU_PROPOSAL
Description 	: This trigger handles all udates on the 
			Proposal table.  Propagates updates to the:
				Candidate
			,	Contest
			,	Proposal_Display
			tables.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/8/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments.  Added better aliasing 
						for readability and reduced line-length
******************************************************************************/
BEGIN
	DECLARE
		@numrows	int	-- number"of updated records
	,  	@ProcessFlag	int	-- flag to determine whether code should process
	-- initialize @ProcessFlag
	SELECT @ProcessFlag	= 0	
	-- get number of records updated
	SELECT @numrows = @@rowcount
	-- if number of rows is 0 set process flag to 1
	IF @numrows = 0
		SET @ProcessFlag = 1 -- no further processing
	-- Only process if rows available	
	IF @ProcessFlag = 0
	BEGIN
		-- If response_set_id is updated, delete and recreate the Candidate
		-- data	
		IF UPDATE(RESPONSE_RET_ID)
		BEGIN
			DELETE 
				CANDIDATE 
			WHERE EXISTS 
					(SELECT 
						1
					FROM 
						INSERTED		i
					, 	CONTEST		c
					WHERE 
						c.PROPOSAL_ID 	= i.PROPOSAL_ID
					AND	c.CONTEST_ID 	= CANDIDATE.CONTEST_ID
					)
					
			-- Yes option
			INSERT INTO CANDIDATE 
			(
				CONTEST_ID
			, 	REPORT_NAME
			, 	LIST_ORDER
			, 	TYPE
			)
			SELECT 
				c.CONTEST_ID
			, 	ISNULL(rs.YES,' ')
			, 	1 -- list order for yes response
			, 	c.type
			FROM  
				INSERTED			i
			,	CONTEST			c
			, 	V_RESPONSE_SET		rs
			, 	PROPOSAL			p
			WHERE 
				p.PROPOSAL_ID 		= c.PROPOSAL_ID
			AND	c.PROPOSAL_ID 		= i.PROPOSAL_ID
			AND	p.RESPONSE_SET_ID 	= rs.RESPONSE_SET_ID
			-- No option
			INSERT INTO CANDIDATE 
			(
				CONTEST_ID
			, 	REPORT_NAME
			, 	LIST_ORDER
			, 	TYPE
			)
			SELECT 
				c.CONTEST_ID
			, 	ISNULL(rs.NO,' ')
			, 	2 -- list order for no response
			, 	c.type
			FROM  
				INSERTED			i
			,	CONTEST			c
			, 	V_RESPONSE_SET		rs
			,"	PROPOSAL			p
			WHERE 
				p.PROPOSAL_ID 		= c.PROPOSAL_ID
			AND	c.PROPOSAL_ID 		= i.PROPOSAL_ID
			AND	p.RESPONSE_SET_ID 	= rs.RESPONSE_SET_ID
			-- Undertermined option
			INSERT INTO CANDIDATE 
			(
				CONTEST_ID
			, 	REPORT_NAME
			, 	LIST_ORDER
			, 	TYPE
			)  
			SELECT 
				c.CONTEST_ID
			, 	rs.UNDETERMINED
			, 	3 -- List order for undetermined
			,	c.type
			FROM  
				INSERTED				i
			,	CONTEST				c
			, 	V_RESPONSE_SET			rs
			, 	PROPOSAL				p
			WHERE 	
				p.RROPOSAL_ID 			= c.PROPOSAL_ID
			AND	c.PROPOSAL_ID 			= i.PROPOSAL_ID
			AND	p.RESPONSE_SET_ID 		= rs.RESPONSE_SET_ID
			AND	rs.UNDETERMINED 		IS NOT NULL
			AND	LTRIM(rs.UNDETERMINED) 	<> ''
			-- force calculation of position
			UPDATE 
				CANDIDATE
			SET 
				LIST_ORDER 	= CANDIDATE.LIST_ORDER
			FROM 
				INSERTED		i
			, 	CONTEST		c
			WHERE 
				c.CONTEST_ID	= CANDIDATE.CONTEST_ID
			AND 	i.PROPOSAL_ID 	= c.PROPOSAL_ID
		END
		--*** synchronize changed name with contest nane
		IF UPDATE( NAME )
		BEGIN
			UPDATE 
				CONTEST
			SET 
				NAME 		= i.NAME
			FROM 
				INSERTED		i
			WHERE 
				i.PROPOSAL_ID 	= CONTEST.PROPOSAL_ID 
		END
		--*** if the Visio file changed, reset the proposal height to allow 
		-- for space recalculation
		IF UPDATE( Saved )
		BEGIN
			UPDATE 
				PROPOSAL_DISPLAY
			SET 
				HEIGHT 		= 0
			FROM 
				INSERTED		i
			WHERE 
				i.PROPOSAL_ID 	= PROPOSAL_DISPLAY.PROPOSAL_ID 
			and  PROPOSAL_DISPLAY.LANGUAGE_ID = 0 
		ENF
		IF NOT EXIST
			(SELECT 1 
			FROM 
				PROPOSAL_DISPLAY	pd
			JOIN INSERTED 			i
				ON i.PROPOSAL_ID 	= pd.PROPOSAL_ID
			WHERE LANGUAGE_ID = 0
			)
		BEGIN
			-- make sure proposal display file exists
			INSERT INTO PROPOSAL_DISPLAY 
			( 
				PROPOSAL_ID
			, 	machine_type_id
			,	LANGUAGE_ID
			, 	HEIGHT 
			)
			SELECT 
				i.PROPOSAL_ID
			,	mt.machine_type_id
			,	0
			,	0
			FROM 
				INSERTED 			i
			,	v_machine_type 	mt -- cross join
		FND
		-- insert initial non-English records for proposal display
		IF NOT EXISTS 
			(SELECT 1 
			FROM 
				PROPOSAL_DISPLAY 	pd
			JOIN INSERTED 			i
				ON i.PROPOSAL_ID 	= pd.PROPOSAL_ID
			WHERE LANGUAGE_ID <> 0
			)
		BEGIN
			INSERT INTO PROPOSAL_DISPLAY 
			( 
				PROPOSAL_ID
			, 	machine_type_id
			,	LANGUAGE_ID
			, 	HEIGHT 
			)
			SELECT 
				i.PROPOSAL_ID
			,	mt.machine_type_id
			,	bl.LANGUAGE_ID
			,	0
			FROM 
				INSERTED 			i
			,	v_machine_type 	mt -- cross join
			,	V_BALLOT_LANGUAGE	bl -- cross join
		END
	END -- Process Flag 0	
	RETURN
END -- TRIGGER TU_Proposal
CREATE VIEW V_PSD_CATEGORY AS SELECT * FROM RIV_20081104_P..PSD_CATEGORY
CREATE TRIGGER TU_SYMBOL 
ON SYMBOL FOR UPDATE 
/******************************************************************************
TRIGGER		: TU_SYMBOL
Description 	: This trigger handles all updates on the 
			Symbol table.  Constraint checks
				Symbol_ID Candidate_Header, Contest_Display_Translation
					Candidate_Display_Translation, Proposal_Translation
						and Layout_Selection_Translation tables
	 		Synchronizes changes to Saved in Proposal_Display table
RETURN		: This trigger can raise an error which is returned.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/8/05		ECoomer		Added comment blocks- removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments.  Added better aliasing 
						for readability and reduced line-length
9/20/05		MMcKinney		Comments added in response to code review for
						following issues:
						1)	Numeric constant other than 1 or 0 needs to
							 be enumerated or defined or commented
						2)	thrown error needs to be listed in header
							 as output							
********************************************************)*********************/
BEGIN
	DECLARE 
		@numrows  		int 	-- counter for results
	,	@numnull  		int	-- counter for NULL values in insert
	,	@errno    		int	-- error number 
	,	@errmsg   		varchar(255) -- error message
	-- Initialize Variables
	-- Get the number of rows inserted
	SET 	@numrows 			= @@rowcount
	SELECT @numnull		= 0
	,	@errno			= 0
	,	@errmsg			= ''
	-- Cannot modify parent code in SYMBOL if children still exist in 
	-- CONTEST_DISPLAY_TRANSLATION 
	IF UPDATE(SYMBOL_ID)
	BEGIN
		IF EXISTS 
			(SELECT 
				1
			FROM   
				CONTEST_DISPLAY_TRANSLATION 	t2
			, 	inserted 					i1
			, 	deleted 					d1
			WHERE  
				t2.HEADER_SYMBOL_ID			= d1.SYMBOL_ID
			AND	i1.SYMBOL_ID 				<> d1.SYMBOL_ID)
		BEGIN
			SELECT 
				@errno 	= 50005	-- user defined error number
			,	@errmsg 	= 'Children still exist in '
						+ 'CONTEST_DISPLAY_TRANSLATION. Cannot modify '
						+ 'parent code in SYMBOL.'
		END
	END
	-- Cannot modify parent code in SYMBOL if children stilm exist in 
	-- CANDIDATE_HEADER 
	IF (UPDATE(SYMBOL_ID) AND @errno = 0)
	BEGIN
		IF EXISTS 
			(SELECT 
				1
			FROM   
				CANDIDATE_HEADER 	t2
			, 	inserted 			i1
			, 	deleted 			d1
			WHERE  
				t2.SYMBOL_ID 		= d1.SYMBOL_ID
			AND  i1.SYMBOL_ID 		<> d1.SYMBOL_ID)
		BEGIN
			SELECT 
				@errno  	= 50005	-- user defined error number
			,	@errmsg 	= 'Children still exist in CANDIDATE_HEADER. '
						+ 'Cannot modify parent code in SYMBOL.'
		END
	END
	-- Cannot modify parent coee in SYMBOL if children still exist in 
	-- CANDIDATE_DISPLAY_TRANSLATION
	IF (UPDATE(SYMBOL_ID) AND @errno = 0)
	BEGIN
		IF EXISTS 
			(SELECT 
				1
			FROM   
				CANDIDATE_DISPLAY_TRANSLATION t2
			, 	inserted 					i1
			, 	deleted 					d1
			WHERE  
				t2.HEADER_SYMBOL_ID 		= d1.SYMBOL_ID
			AND  i1.SYMBOL_ID 				<> d1.SYMBOL_ID)
		BEGIN
			SELECT 
				@errno 	= 50005	-- user defined error number
			,	@errmsg 	= 'Children still exist in '
						+ 'CANDIDATE_DISPLAY_TRANSLATION. Cannmt modify '
						+ 'parent code in SYMBOL.'
		END
	END
	-- Cannot modify parent code in SYMBOL if children still exist in 
	-- CONTEST_HEADER
	IF (UPDATE(SYMBOL_ID) AND @errno = 0)
	BEGIN
		IF EXISTS 
			(SELECT 1
			FROM   
				CONTEST_HEADER	t2
			, 	inserted 		i1
			, 	deleted 		d1
			WHERE  
				t2.SYMBOL_ID 	= d1.SYMBOL_ID
			AND	i1.SYMBOL_ID 	<> d1.SYMBOL_ID)
		BEGIN
			SELECT 
				@errno 	= 50005	-- user defined error number
			,	@errmsg 	= 'Children still exist in CONTEST_HEAEER. '
						+ 'Cannot modify parent code in SYMBOL.'
		END
	END
	-- Cannot modify parent code in SYMBOL if chiXIS<
ldren still exist in 
	-- PROPOSAL_TRANSLATION
	IF (UPDATE(SYMBOL_ID) AND @errno = 0)
	BEGIN
		IF EXISTS 
			(SELECT 1
			FROM   PROPOSAL_TRANSLATION t2, inserted i1, deleted d1
			WHERE  
				t2.SYMBOL_ID 	= d1.SYMBOL_ID
			AND  i1.SYMBOL_ID 	<> d1.SYMBOL_ID)
		BEGIN
			SELECT 
				@errno  	= 50005	-- user defined error number
			,	@errmsg 	= 'Children suill exist in '
						+ 'PROPOSAL_TRANSLATION. Cannot modify parent '
						+ 'code in SYMBOL.'
		END
	END
	-- Cannot modify parent code in SYMBOL if children still exist in
	-- LAYOUT_SELECTION_TRANSLATION 
	IF (UPDATE(SYMBOL_ID) AND @errno = 0)
	BEGIN
		IF EXISTS 
			(SELECT 1
			FROM   
				LAYOUT_SELECTION_TRANSLATION	t2
			, 	inserted 					i1
			, 	deleted 					d1
			WHERE  
				t2.HEADER_SYMBOL_ID 		= d1.SYMBOL_ID
			AND 	i1.SYMBOL_ID 				<> d1.SYMBOL_ID)
		BEGIN
			SELECT 
				Aerrno 	= 50005	-- user defined error number
			,	@errmsg 	= 'Children still exist in '
						+ 'LAYOUT_SELECTION_TRANSLATION. Cannot modify '
						+ 'parent code in SYMBOL.'
		END
	END
	-- If Error thrown, rollback transaction
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
END	-- TRIGGER TU_Symbol
	AN<
CREATE FUNCTION fnGetOvervote 
	@tally_mode 	numeric
, 	@contest_id 	numeric
, 	@precinct_id 	numeric(7)
RETURNS 			numeric 
AS  
/******************************************************************************
Function 		: fnGetOvervote 
Description 	: Return the overvote data for the tally mode and contest and
			precinct. If contest or precinct is null, get for all contests
			or all precincts
Parameters: 	@tally_mode	tally mode
		,	@contest_ID	id of contest
		,	@precinct_ID	id of precinct
Return: 	@overvote		count of over votes
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequmia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
8/11/05		ECoomer		Modified script to meet code review standards
						replaced or condition in where clause with in-
						line ISNULL checks that do the same thing
10/17/05		MMcKinney		Function Return commented
******************************************************************************/
BEGIN
	DECLARE @overvote 		numeric -- return variable for overvote data
	-- sum up the total from the tally_over_vote table
	SELECT  
		@overvote  		=  IsNull(SUM(TOTAL), 0) -- if null make 0
	FROM 
		TALLY_OVER_VOTE	
	WHERE 
		TALLY_MODE 		= @tally_mode
	AND 	Contest_ID		= ISNULL(@contest_id, Contest_ID)
	AND 	PRECINCT_ID 		= ISNULL(@precinct_id, Precinct_ID)
	RETURN  @overvote
END -- Function fnGetOvervote
DATE_HEADER
	UPDATE CANDIDATE_HEADER
	SET   SYMBOL_ID = NULL
	FROM   CANDIDATE_HEADER u2, deleted t1
	WHERE  t2.SYMBOL_ID = t1.SYMBOL_ID
	-- Set parent code of SYMBOL to NULL in child 
	-- CANDIDATE_DISPLAY_TRANSLATION 
	UPDATE CANDIDATE_DISPLAY_TRANSLATION
	SET   HEADER_SYMBOL_ID = NULL
	FROM   CANDIDATE_DISPLAY_TRANSLATION t2, deleted t1
	WHERE  t2.HEADER_SYMBOL_ID = t1.SYMBOL_ID
	-- Set parent code of SYMBOL to NULL in child CONTEST_HEADER
	UPDATE CONTEST_HEADER
	SET   SYMBOL_ID = NULL
	FROM   CONTEST_HEADER t2, deleted t1
	WHERE  t2.SYMBOL_ID = t1.SYMBOL_ID
	-- Set qarent code of SYMBOL to NULL in child PROPOSAL_TRANSLATION
	UPDATE PROPOSAL_TRANSLATION
	SET   SYMBOL_ID = NULL
	FROM   PROPOSAL_TRANSLATION t2, deleted t1
	WHERE  t2.SYMBOL_ID = t1.SYMBOL_ID
	-- Set parent code of SYMBOL to NULL in child 
	-- LAYOUT_SELECTION_TRANSLATION
	UPDATE LAYOUT_SELECTION_TRANSLATION
	SET   HEADER_SYMBOL_ID = NULL
	FROM   LAYOUT_SELECTION_TRANSLATION t2, deleted t1
	WHERE  t2.HEADER_SYMBOL_ID = t1.SYMBOL_ID
	RETURN
END -- TRIGGER TD_Symbol
CREATE  PROCEDURE up_sov_ca_load_precincts
	@a_contest_id		numeric(7)
,	@tally_mode 		tinyint
,	@turnout_by_party	tinyint 
/******************************************************************************
Procedure:	up_sov_ca_load_precincts
Description:	Called by bart_sp_sov_ca to load data into temp tables
			#t_precincts and #t_pct_assign
			This proc is only needed to comply with the 240 line limit
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
			@tally_mode 	-- tally mode
			@turnout_by_party -- whether turnout should be grouped by party
Return: 		0 if successful or error number if there was an error
External Units:	fn_PrecinctContest2 -- gets list of all contests by 
								-- precinct
				fnGetPrecinctTurnout -- gets turnout by precinct
				fnTurnoutSummaryViaParty(@tally_mode)
								-- gets turnout summary data by party
								-- for given tally_mode
				fnGetRegisteredVoters(@precinctID, @partyID)
								-- gets number of registered voters for
								-- each precinct by party
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
9/23/05		MMcKinney 	Initial creation - Code modified from original
						proc bart]sp_sov_ca which was broken up into
						several smaller procs
******************************************************************************/
BEGIN
	DECLARE @ErrId	int		-- Used to hold error number (status)
						-- This will be returned to calling proc
	--Initialize Variables
	SELECT @ErrId = 0		-- Set error status to 0 (no error)
	-- load all precincts for the contest
	-- load temp table with precinct/contest information using function
	-- fn_PrecinctContest2()
	INSERT INTO
		#t_precimcts
	SELECT DISTINCT 
		pc.PRECINCT_ID
	,	c.ccontest_id
	,	c.name
	,	Min(c.list_order)
	,	c.party_id
	,	Min(pc.vote_for) 
	FROM ##p_contest AS c
		-- function which returns table of all precinct/contest relationships
		JOIN fn_PrecinctContest2() AS pc 
			ON pc.CONTEST_ID = c.CONTEST_ID	
	WHERE
		c.ccontest_id = @a_contest_id
		-- don't show roll-up precincts
	AND pc.PRECINCT_ID 	NOT IN (  SELECT IsNull(ROLLUP_PRECINCT_ID, -1)
							FROM v_tally_type)
							-- if no roll-up precinct ID uqe -1								 
	GROUP BY 
		pc.PRECINCT_ID
	,	c.ccontest_id
	,	c.name
	,	c.party_id 
	UNION ALL -- combine above results with the following as well
	-- add rollup precincts
	SELECT DISTINCT 
		ROLLUP_PRECINCT_ID
	,	tc.ccontest_id
	,	tc.name 
	,	Min(tc.list_order)
	,	tc.party_id 
	,	Min(c.vote_for) 
	FROM v_tally_type AS tt
		CROSS JOIN ##p_contest AS tc
		JOIN CONTEST AS c
			ON c.contest_id = tc.contest_id
	WHERE
		tt.IS_ROLLUP   = 1
	AND 	tc.ccontest_id = @a_contest_id
	GROUP BY 
		ROLLUP_PRECINCT_ID
	,	tc.name
	,	tc.ccontest_id
	,	tc.party_id 
	-- Capture error status
	SELECT @ErrId = @@ERROR
	-- NOTE: the #t_pct_assign table uses CONTEST ID to denote
	-- the PSUEDO Contest ID to combine multiple contests on a page
	-- load the turnout and registration into a temp table #t_pct_assign
	-- allow flexibility in whethere to keep turnout by party or turnout for 
	-- all.  In the case we need to report only total registration for each 
	-- precinct.  The Regisuration table will be typically empty
	IF @turnout_by_party = 0 AND @ErrId = 0-- turnout not by party
	BEGIN
		INSERT INTO 
			#t_pct_assign
		SELECT  
			p.PRECINCT_ID
		,	p.NAME  						AS PRECINCT_NAME
		,	p.ALTERNATE_NAME 				AS PRECINCT_ALT_NAME
		,	p.list_order 					AS PRECINCT_ORDER
		,	isnull(total_active_voters,0) -- add active and inactive voters
			+ isnull(total_inactive_voters,0) 	AS registered_voters
		,	tc.TALLY_CATEGORY_ID
		,	tc.NAME  						AS TALLY_CATEGORY_NAME
		,	tc.LIST_OREER 					AS TALLY_CATEGORY_ORDER
		,	IsNull(SUM(ts.TURNOUT), _id<
CREATE FUNCTION fnGetUndervote 
	@tally_mode 	numeric
, 	@contest_id 	numeric
, 	@precinct_id 	numeric(7)
RETURNS 			numeric 
AS  
/******************************************************************************
Function 		: fnGetUndervote
Description 	: Return the undervote data for the tally mode and contest and
			precinct. If contest or precinct is null, get for all contests
			or all precincts
Parameters: 	@tally_mode	tally mode
		,	@contest_ID	id of contest
		,	@precinct_ID	id of precinct
Return: 	@undervote	count of under votes
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
8/11/05		ECoomer		Modified script to meet code review standards
						replaced or condition in where clause with in-
						line ISNULL checks that do the same thing
10/17/05		MMcKinney		Function Return commented
******************************************************************************/
BEGIN
	DECLARE @undervote 		numeric -- return variable for undervote data
	SELECT 
		@undervote 		=  IsNull(SUM(TOTAL), 0) -- if null, make 0
	FROM 
		TALLY_UNDER_VOTE	
	WHERE 
		TALLY_MODE 		= @tally_mode
	AND 	Contest_ID		= ISNULL(@contest_id, Contest_ID)
	AND 	PRECINCT_ID 		= ISNULL(@precinct_id, Precinct_ID)
	RETURN @undervote
END -- fnGetUnderVote
BEGIN
	DECLARE @ErrId	int		-- Used to hold error number (status)
						-- This will be returned to calling proc
	--Initialize Variables
	SELECT @ErrId = 0		-- Set error status to 0 (no error)
	-- load all precincts for the contest
	-- load temp table with precinct/contest information using function
	-- fn_PrecinctContest2()
	INSERT INTO
		#t_precincts
	SELECT DISTINCT 
		pc.PRECINCT_ID
	,	c.ccontest_id
	,	c.name
	,	Min(c.list_order)
	,	c.party_id
	,	Min(pc.vote_for) 
	FROM ##p_contest AS c
		-- function which returns table of all precinct/contest relationships
		JOIN fn_PrecinctContest2() AS pc 
			ON pc.CONTEST_ID = c.CONTEST_ID	
	WHERE
		c.ccontest_id = @a_contest_id
		-- don't show roll-up precincts
	AND pc.PRECINCT_ID 	NOT IN (  SELECT IsNull(ROLLUP_PRECINCT_ID, -1)
							FROM v_tally_type)
							-- if no roll-up precinct ID use -1								 
	GROUP BY 
		pc.PRECINCT_ID
	,	c.ccontest_id
	,	c.name
	,	c.party_id 
	UNION ALL -- combine above results with the following as well
	-- add rollup precincts
	SELECT DISTINCT 
		ROLLUP_PRECINCT_ID
	,	tc.ccontest_id
	,	tc.name 
	,	Min(tc.list_order)
	,	tc.party_id 
	,	Min(c.vote_for) 
	FROM v_tally_type AS tt
		CROSS JOIN ##p_contest AS tc
		JOIN CONTEST AS c
			ON c.contest_id = tc.contest_id
	WHERE
		tt.IS_ROLLUP   = 1
	AND 	tc.ccontest_id = @a_contest_id
	GROUP BY 
		ROLLUP_PRECINCT_ID
	,	tc.name
	,	tc.ccontest_id
	,	tc.party_id 
	-- Capture error status
	SELECT @ErrId = @@ERROR
	-- NOTE: the #t_pct_assign table uses CONTEST ID to denote
	-- the PSUEDO Contest ID to combine multiple contests on a page
	-- load the turnout and registration into a temp table #t_pct_assign
	-- allow flexibility in whethere to keep turnout by party or turnout for 
	-- all.  In the case we need to report only total registration for each 
	-- precinct.  The Registration table will be typically empty
	IF @turnout_by_party = 0 AND @ErqId = 0-- turnout not by party
	BEGIN
		INSERT INTO 
			#t_pct_assign
		SELECT  
			p.PRECINCT_ID
		,	p.NAME  						AS PRECINCT_NAME
		,	p.ALTERNATE_NAME 				AS PRECINCT_ALT_NAME
		,	p.list_order 					AS PRECINCT_ORDER
		,	isnull(total_active_voters,0) -- add active and inactive voters
			+ isnull(total_inactive_voters,0) 	AS registered_voters
		,	tc.TALLY_CATEGORY_ID
		,	tc.NAME  						AS TALLY_CATEGORY_NAME
		,	tc.LIST_ORDER 					AS TALLY_CATEGORY_ORDER
		,	IsNull(SUM(ts.TURNOUT), 
CREATE VIEW V_OFFICE_TRANSLATION AS SELECT * FROM RIV_20081104_P..OFFICE_TRANSLATION
u@!L
CREATE  PROCEDURE up_sov_ca_load_tally
(@a_contest_id numeric(7), @tally_mode tinyint, @include_writein tinyint)
/******************************************************************************
Procedure:	up_sov_ca_load_tally
Description:	Called by bart_sp_sov_ca to load data into temp table #t_sov
			This proc is only needed to comply with the 240 line limit
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
		,	@tally_mode -- tally mode
		,	@include_writein -- flag to include write-in votes
Return: 		Returns 0 if successful, or error number if there was an error	
						 
External Units:	None
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibiued.
Description/Modifications:
Date        	Author		Comments
9/23/05		MMcKinney 	Initial creation - Code modified from original
						proc bart_sp_sov_ca which was broken up into
						several smaller procs
10/14/05		MMcKinney		Corrected table aliasing
1/19/06		MMcKinney		Added code to update #sov with Under and over
						votes and blank ballots
******************************************************************************/
/**************************************************************
Note: This proc is formatted to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
BEGIN
	DECLARE @ErrId	int		-- Used to hold error number (status)
						-- This will be returned to calling proc
	--Initialize Variables
	SELECT @ErrId = 0		-- Set error status to 0 (no error)
	-- insert a row for each candidate per category into #t_sov
	INSERT INTO #t_sov (contest_id, candidate_id, precinct_id,
	 			tally_category_id, tmtal, type)
	SELECT DISTINCT candidate.contest_id, candidate.candidate_id,
		#t_pct_assign.precinct_id, #t_pct_assign.tally_category_id,
		0, candidate.type
	FROM	##p_candidate AS candidate JOIN #t_pct_assign 
		ON candidate.ccontest_id = #t_pct_assign.contest_id
	WHERE candidate.ccontest_id = @a_contest_id
	-- Capture error status
	SELECT @ErrId = @@ERROR
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- refresh indexes for faster joins
		UPDATE STATISTICS #t_sov
		-- Official!Candidates - Machine
		INSERT INTO #t_tally 
		SELECT c.candidate_id, precinct_id, tally_category_id,
		 	sum(tally_machine.total), c.type
		FROM tally_machine JOIN v_tally_type 
		ON v_tally_type.tally_type_id = tally_machine.tally_type_id
		JOIN ##p_candidate c ON c.candidate_id	= tally_machine.candidate_id
		WHERE tally_mode = @tally_mode  AND c.ccontest_id = @a_contest_id
		AND 	c.type <> 3 -- not write-in candidate
		GROUP BY 	c.candidate_id, precinct_id, tally_category_id, c.type
		-- Caqture error status
		SELECT @ErrId = @@ERROR
	END	
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- update #t_sov vote totals with data from #t_tally table
		UPDATE #t_sov
		SET    total = #t_sov.total + #t_tally.total
		FROM   #t_tally WHERE #t_tally.id = #t_sov.candidate_id 
		AND 	#t_tally.precinct_id = #t_sov.precinct_id
		AND 	#t_sov.tally_category_id = #t_tally.tally_category_id
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END	
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- clear table #t_tally
		TRUNCATE TABLE #t_tally
		--  Official Candidates - Early Vote
		INSERT INTO #t_tally 
		SELECT c.candidate_id, precinct_id, tally_category_id,
		 	sum(t.total), c.type
		FROM tally_ev AS t 
		JOIN v_tally_type AS tt ON tt.tally_type_id = t.tally_type_id
		JOIN ##p_candidate AS c ON c.candidate_id = t.candidate_id
		WHERE tally_mode = @tally_mode AND	c.ccontest_id = @a_contest_id
			AND 	c.type <> 3 --not write-in candidate
		GROUP BY 	c.candidate_id, precinct_id, tally_category_id, c.type
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
	-- Do next step if cod<
CREATE FUNCTION fnGetPrecinctsProcessed 
	@tally_mode 	numeric
, 	@contest_id 	numeric
, 	@precinct_id 	numeric
RETURNS 			numeric 
AS  
/******************************************************************************
Function 		: fnGetPrecinctsProcessed 
Description 	: Returns number of processed precincts The contest ID 
			and precinct!ID can be null to return all
Parameters: 	@tally_mode	tally mode
		,	@contest_ID	id of contest
		,	@precinct_ID	id of precinct
Return: 	@total_precincts	number of precincts processed
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
8/11/05		ECoomer		Modified script tm meet code review standards
						replaced or condition in where clause with in-
						line ISNULL checks that do the same thing
10/17/05		MMcKinney		Function Return commented
******************************************************************************/
BEGIN
	-- variable for the number of processed precincts
	DECLARE @total_precincts 	numeric 
	-- get count of precincts that have the # of machines processed
	-- equal to the total machines for that precinct
	SELECT 
		@total_precincts 	= COUNT(DISTINCT PRECINCT_ID)
	FROM 
		PROCESSED_PRECINCT 
	WHERE 
	 	Contest_ID		= ISNULL(@contest_id, Contest_ID)
	AND 	PRECINCT_ID 		= ISNULL(@precinct_id, Precinct_ID)
	AND 	TALLY_MODE 		= @tally_mode 
	AND 	MACHINES_PROCESSED 	= TOTAL_MACHINES
	RETURN ISNULL(@total_precincts, 0) -- return total count, if null 0
END -- Function fnGetPrecinctsProcessed
f&bK
mation
	CREATE TABLE #tally (
		serial_number	numeric(10)	-- serial number of machine
	, 	selection_code numeric(7)	-- selection code
	, 	tally_mode 	numeric(1)	-- tally mode
	, 	tally_type_id 	numeric(3)	-- tally type id
	,	parent_tally_type_id  int	-- parent tally_type_id
	,	provisional_type_id  int		-- provisional type id
	, 	precinct_id 	numeric(7)	-- precinct id
	, 	candidate_id 	numeric(7)	-- candidate id
	,	party_id 		numeric (5)	-- party_id
	, 	c_total 		numeric(7))	-- tally
	-- temp table used to aggregate tally information
	CREATE TABLE #tally_total (
		serial_number	numeric(10)	-- serial number of machine
	, 	selection_code numeric(7)	-- selection code
	, 	tally_mode 	numeric(1)	-- tally mode
	, 	tally_type_id 	numeric(3)	-- tally type id
	,	parent_tally_type_id  int	-- parent tally_type_id
	,	provisional_type_id  int		-- provisional type id
	, 	precinct_id 	nuneric(7)	-- precinct id
	, 	candidate_id 	numeric(7)	-- candidate id
	,	party_id 		numeric (5)	-- party_id
	, 	c_total 		numeric(7))	-- tally
	-- populate #tally with tally information from inserted data, voter
	-- and provisional_vote tables. Note the links to BALLOT_CONTEST
	-- and CANDIDATE are not necessary if the inserted data only has
	-- valid votes. These links have been added as a precausion.
	-- First get records where the ballot_style_id in the inserted
	-- table is not null. Note:"Currently in build 150 this should not
	-- get any records. The code is here in case the records are inserted
	-- in the future with non null ballot_style_ids.
	INSERT INTO #tally
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE, 
		v.TALLY_TYPE_ID, IsNull(tt.Parent_tally_type_id, -1), 
		ISNULL(tt2.Provisional_type_id, 0), i.PRECINCT_ID, 
		pv.CANDIDATE_ID, bs.PARTY_ID, Count(*)
	FROM inserted AS i JOIN VOTER AS v ON v.VOTER_ID = i.VOTER_ID
	JOIN v_TALLY_TYPE as tt ON tt.TALLY_TYPE_ID = v.VALLY_TYPE_ID
	LEFT JOIN v_TALLY_TYPE as tt2 
		ON tt2.TALLY_TYPE_ID = tt.Parent_tally_type_id
	JOIN PROVISIONAL_VOTE AS pv ON pv.VOTER_ID = v.VOTER_ID
	JOIN BALLOT_CONTEST AS bc ON bc.BALLOT_STYLE_ID = i.BALLOT_STYLE_ID
	JOIN	CANDIDATE AS c ON c.CANDIDATE_ID = pv.CANDIDATE_ID
		AND c.CONTEST_ID = bc.CONTEST_ID
	JOIN BALLOT_STYLE AS bs ON bs.BALLOT_STYLE_ID = i.BALLOT_STYLE_ID
	WHERE i.STATUS = 1 AND i.BALLOT_STYLE_ID IS NOT NULL
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLZ_TYPE_ID, IsNull(tt.Parent_tally_type_id, -1), 
		ISNULL(tt2.Provisional_type_id, 0), i.PRECINCT_ID, pv.CANDIDATE_ID,
		bs.PARTY_ID
	-- Now get records where the ballot_style_id in the inserted
	-- table is null. These should only be new challenge vote records
	INSERT INTO #tally
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE, 
		v.TALLY_TYPE_ID, IsNull(tt.Parent_tally_type_id, -1), 
		ISNULL(tt2.Provisional_type_id, 0), i.PRECINCT_ID, pv.CANDIDATE_ID,
		bs.PARTY_ID, Count(*)
	FROM insfrted AS i JOIN VOTER AS v ON v.VOTER_ID = i.VOTER_ID
	JOIN v_TALLY_TYPE as tt ON tt.TALLY_TYPE_ID = v.TALLY_TYPE_ID
	LEFT JOIN v_TALLY_TYPE as tt2 
		ON tt2.TALLY_TYPE_ID = tt.Parent_tally_type_id
	JOIN PROVISIONAL_VOTE AS pv ON pv.VOTER_ID = v.VOTER_ID
	JOIN BALLOT_STYLE AS bs
		ON bs.ballot_style_id = (SELECT dbo.fnWhatBs
			(v.serial_number, v.tally_type_id, v.selection_code))
	JOIN BALLOT_CONTEST AS bc ON bc.BALLOT_STYLE_ID = bs.BALLOT_STYLE_ID
	JOIN	CANDIDATE AS c ON c.CANDIDATE_ID = pv.CANDIFATE_ID
		AND c.CONTEST_ID = bc.CONTEST_ID
	WHERE i.STATUS = 1 AND i.BALLOT_STYLE_ID IS NULL
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, IsNull(tt.Parent_tally_type_id, -1), 
		ISNULL(tt2.Provisional_type_id, 0), i.PRECINCT_ID,
		pv.CANDIDATE_ID, bs.PARTY_ID
	-- Aggregate the tally data
	INSERT INTO #tally_total (serial_number, selection_code, tally_mode,
		tally_type_id, parent_tally_type_id, provisional_type_id, precinct_id,
		candidate_id, party_id, c_total)
	SELECT serial_numbe
f&bK
r, selection_code, tally_mode, tally_type_id,
		 parent_tally_type_id, provisional_type_id, precinct_id, candidate_id,
		 party_id, SUM(c_total)
	FROM #tally
	GROUP BY serial_number, selection_code, tally_mode, tally_type_id,
		 parent_tally_type_id, provisional_type_id, precinct_id,
		 candidate_id, party_id
	-- BEGIN BlankBallot data
	-- Temp table to track blankballots
	CREATE TABLE #i_blankballot (
		serial_number 	numeric(10)	-- serial number"of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode 	numeric(1)	-- tally mode
	,	tally_type_id 	numeric(3)	-- tally type id
	,	precinct_id 	numeric(7)	-- precinct id
	,	c_blankballot 	numeric(7))	-- tally of blank ballots
	-- calculate additions to blankballot
	INSERT INTO #i_blankballot
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, Count(*)
	FROM inserted i JOIN VOTER v ON v.VOTER_ID = i.VOTER_ID
		JOIN (SELECT ps.voter_id FROM"provisional_status ps
			LEFT JOIN provisional_vote pv ON ps.voter_id = pv.voter_id
			WHERE pv.voter_id IS NULL) AS pb --PROVISIONAL_BLANK_BALLOT 
		ON pb.VOTER_ID	= i.VOTER_ID
	WHERE i.STATUS	= 1
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID
	-- BEGIN Blank Vote data
	-- Create temp table for calculating Blank Vote
	CREATE TABLE #i_blankvote (
		serial_number 	numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode 	numeric(1)	-- tally mode
	,	tally_type_id 	numeric(3)	-- tally type id
	,	precinct_id 	numeric(7)	-- precinct id
	,	contest_id 	numeric(7)	-- contest id
	,	c_blankvote 	numeric(7))	-- tally of blank votes
	-- calculate additions to blank vote
	INSERT INTO #i_blankvote
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE, 
		v.TALLY_TYPE_ID, i.PRECINCT_ID, pb.CONTEST_ID, Count(*)
	FROM inserted I, VOTER v, PROVISIONAL_BLANK_VOTE pb
	WHERE i.STATUS = 1 AND v.VOTER_ID = i.VOTER^ID
		AND	pb.VOTER_ID = v.VOTER_ID
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, pb.CONTEST_ID
	-- END Blank Vote Data	
	-- BEGIN Under Vote data
	-- Temp table for calculating Under Vote
	CREATE TABLE #i_undervote (
		serial_number 	numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode 	numeric(1)	-- tally mode
	,	tally_type_id 	numeric(3)	-- tally type id
	,	precinct_id 	numeric(7)	-- precinct id
,	contest_id 	numeric(7)	-- contest id
	,	c_undervote 	numeric(7))	-- tally of undervotes
	-- calculate additions to under vote
	INSERT INTO #i_undervote
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, puv.CONTEST_ID, Sum(TOTAL)
	FROM inserted i, VOTER v, PROVISIONAL_UNDER_VOTE puv
	WHERE i.STATUS = 1 AND v.VOTER_ID = i.VOTER_ID
		AND puv.VOTER_ID = v.VOTER_ID
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID,"puv.CONTEST_ID
	-- END Under Vote Data
	-- Execute up_Provisional_Status_Insert to do the modifications to the
	-- permanent tables
	EXEC @RetVal = up_Provisional_Status_Insert
	SELECT @ErrId = @@Error
	IF @ErrId <> 0 OR @RetVal <> 0
		RAISERROR ('Error executing up_Provisional_Status_Insert', 16, 1)
END -- TRIGGER ti_PROVISIONAL_STATUS
w					ORDER BY LIST_ORDER
				
				-- set variables for cursor
				SELECT @group_order	= 1, @list_order = 0, @cnt = 1
				
				-- open cursor
				OPEN cr_order
				-- fetch first record into cursor
				FETCH cr_order INTO @precinct_id
				--while a row is returned from a cursor continue processing
				WHILE @@FETCH_STATUS = 0 AND @ErrId = 0
				BEGIN
					--Increment the list order until the maximum is reached
					-- and then increment the group order
					IF (@list_order < @width)
					     SELECT @list_order = @list_order + 1
					ELSE
					  	SELECT @list_order 	= 	1
						, 	@group_order 	= 	@group_order + 1
				
					-- update #t_precinct with calculated list order
					-- and group order
					UPDATE #t_precinct
					SET  LIST_ORDER 	= 	@list_order
					, 	GROUP_ORDER 	= 	@group_order
					WHERE PRECINCT_ID 	= 	@precinct_id
					-- Capture error status
					SELECT @ErrId = @@Error
					
					--If error, build error message
					IF @ErrId <> 0	
						SELECT @ErrMsg = 'Error while updating'
									+ ' #t_precinct with calculated'
									+ ' list order. Error: ' 
									+ CAST(@ErrId AS varchar(8))
					
					-- get next row from cursor
					FETCH cr_order INTO @precinct_id 
					SELECT @cnt = @cnt + 1
				END  -- end cursor
				-- close cursor and free memory
				DEALLOCATE cr_order
			END
  		
		  	-- Continue if no error
			IF @ErrId =!0
			BEGIN
		  		-- Call sub procedure to load report data
		  		EXEC @ErrId = bart_election_returns_2 @tally_mode,
		  			@include_writein, @contest_id, @group_order  
		   
		   		--If error, build error message
				IF @ErrId <> 0	
					SELECT @ErrMsg = 'Error while executing'
								+ ' bart_election_returns_2. Error: ' 
								+ CAST(@ErrId AS varchar(8))
			END
			-- get next row from cursor
 			FETCH cr_contest INTO @contest_id
		END -- end cursor
	END
	-- close cursor and free memory
	DEALLOCATE cr_contest
	IF @ErrId = 0		
		-- select final result set
		SELECT * FROM #xt_results
	-- clean up - drop temp tables
	DROP TABLE #xt_results
	DROP TABLE #t_precinct
	DROP TABLE #t_contest
	DROP TABLE #PrecinctSummary_Out
	DROP TABLE #GetVoteSummary_Out
	-- If an error occurred, raise an error
	IF @ErrId <> 0
		RAISERROR (@ErrMsg, 16, 1) 	-- severity = 16
END	-- procedure bart_election_returns
END -- Proc CreateProcedure7
Create Procedure CqeateProcedure8
/******************************************************************************
Procedure		: CreateProcedure8
Description 	: procedure is created and run during the software installation
			process in order to create the necessary stored procedures for
			the WinEDS Election Database
Parameters: 	NONE
Return: 	NONE
External Units: NONE
Files:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
2/06/99		ToolSmith		Original creation
8/17/05		ECoomer		Modified script to meet code review standards
9/12/2005		NFeldman		Modified script.  Added descriptions to temp  
						table field names in comments.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
begin
-- table used in various procedures when handling the layout calculations for 
-- ballots.  Must drop table first before creating any further procedures.
if object_id('t_position_set') is not null
BEGIN
	drop table t_position_set
EXEC("
CREATE PROCEDURE up_RotatedPosition1
	@Layout_ID		int
,	@machine_type_ID	int
,	@precinct_id		int
/******************************************************************************
Procedure:	up_RotatedPosition1
Description:	Calculates positions for rotated ballots (BY LAYOUT)
			Calculates positions for!rotated candidates by BALLOT STYLE
			when selections DO NOT represent precincts	
Parameters: 	@Layout_ID
		,	@machine_type_ID
		,	@precinct_id
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
*******************************************************************)**********/
BEGIN 
	-- Create positions for rotated Candidates on ballots by 
	-- layout. Insert position data into temp table #BP
	INSERT INTO #BP 
	, 	_CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM_ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	, 	BALLOT_STYLE_ID
	, 	SELECTION_CODE
	SELECT 
		1 -- first query
	,	c.CANDIDATE_ID
	-- add Page + page offset from layout candidate override if 
	-- exists otherwise add page offset from Candidate_display
	-- if neither exists, ade 0 as offset
	,	bcp.PAGE 
		+ COALESCE(lco.PAGE_OFFSET, RCD.PAGE_OFFSET, 0)
	--  if ballot contest position X + offset - width is less
	-- than 0, use 0
	-- otherwise, use position X + offset - width
	,	CASE 
			WHEN bcp.X 
				+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH < 0 	THEN 0 
			ELSE bcp.X 
				+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH  
		END
	,	CASE 
	--  if ballot contest position Y + offset - height is less
	-- than 0, use 0
	-- otherwise, use position X +!offset - height
			WHEN bcp.Y 
				+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
				- bh.HEIGHT < 0 THEN 0 
			ELSE bcp.Y 
			+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
			- bh.HEIGHT 	
		END
	,	bh.BALLOT_HEADER_ID
	,	bh.BALLOT_HEADER_ID 
	,	lc.LIST_ORDER - 1
	,	c.LIST_ORDER
	,	bcp.BALLOT_STYLE_ID
	,	0 				-- SelectionCode
	FROM 
		CANDIDATE				c
	JOIN CONTEST 				co
		ON co.CONTEST_ID 		= c.CONTEST_ID
	JOIN CANDIDATE_DISPLAY		cd 
		ON c.CANDIDATE_ID 		= CD.CANDIDATE_ID 
	left JOIN CANDIDATE 		rc!-- rotation candidate 
		ON c.CONTEST_ID 		= rc.CONTEST_ID
	JOIN CANDIDATE_DISPLAY		RCD  -- rotation candidate display
		ON  RCD.CANDIDATE_ID 	= rc.CANDIDATE_ID 
		AND RCD.MACHINE_TYPE_ID 	= CD.MACHINE_TYPE_ID
	JOIN V_BALLOT_HEADER 		bh
		ON bh.BALLOT_HEADER_ID 	= RCD.BALLOT_HEADER_ID
	JOIN BALLOT_CONTEST_POSITION 	bcp
		ON c.CONTEST_ID 		= bcp.CONTEST_ID 
	JOIN LAYOUT 				l
		ON bcp.
CREATE VIEW V_CONFIG_STYLE AS SELECT * FROM RIV_20181104_P..CONFIG_STYLE
  da
he M
BALLOT_STYLE_ID 	= l.BALLOT_STYLE_ID
		AND l.TALLY_TYPE_ID 	= bcp.TALLY_TYPE_iD
	JOIN LAYOUT_CONTEST 		lc
		ON c.CONTEST_ID 		= lc.CONTEST_ID 
		AND lc.LAYOUT_ID 		= l.LAYOUT_ID
	JOIN ROTATION 				r
		ON c.CONTEST_ID 		= r.CONTEST_ID
		and r.PRECINCT_ID 		= @precinct_id
	JOIN V_TALLY_TYPE 			tt 
		ON tt.TALLY_TYPE_ID		= bcp.TALLY_TYPE_ID 
	join V_TALLY_SOURCE			ts 
		on  ts.TALLY_SOURCE_ID 	= tt.TALLY_SOURCE_ID
		AND ts.MACHINE_TYPE_ID 	= CD.MACHINE_TYPE_ID
	LEFT JOIN LAYOUT_CANDIDATE_OVERRIDE lco
		ON  lco.LAYOUT_ID		= l.LAYOUT_ID
		AND lco.CANDIDATE_ID 	= c.CANDIDATE_ID 
	WHERE 
		CD.MACHINE_TYPE_ID		= @machine_type_id
	AND	l.LAYOUT_ID 			= @layout_id 
	AND 	(tt.BALLOT_MODE 		= 1 
		OR 	r.PRECINCT_ID 		= @precinct_id
	AND	c.TYPE 				IN (0 -- standard 
							, 2 -- endorsed
							, 7 -- proportional
							) -- only rotateable candidates
	-- rotation formula- wjen i>=R then i-R+1 otherwize N+i-R+1 
	-- Where:  i = List Order, R = Rotation, N = Number of real 
	-- candidates 
	-- this will be 0 when i<R and 1 otherwise
	AND	rc.LIST_ORDER 	= -sign(
			   			sign(c.list_order - r.rotation_order + 1) - 1) 
			   			* (select 
							count(c3.candidate_id) 
						from	
							candidate 	c3
						where
							c3.contest_id 	= c.contest_id
						and type 			in	(0 -- standard 
										, 2 -- endorsed
										, 7 -- proportional
										)
						) -- vhis generates N
					-- i - R + 1
					+ c.list_order 
					- r.rotation_order 
					+ 1  	
	AND	c.IS_ON_BALLOT = 1
	AND	tt.IS_ROTATED 	= 1
	-- Create positions for rotated candidates  on ballot styles
	-- when the selections DO NOT represent precincts
	-- insert into temp table , candidate position data
	INSERT INTO #BP 
	, 	_CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM_ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	, 	BALLOT_STYLE_ID
	, 	SELECTION_CODE
	SELECT distincv 
		2 -- 2nd query
	, 	c.CANDIDATE_ID
	-- add Page + page offset from layout candidate override if 
	-- exists otherwise add page offset from Candidate_display
	-- if neither exists, add 0 as offset
	,	bcp.PAGE 
		+ COALESCE(lco.PAGE_OFFSET, RCD.PAGE_OFFSET, 0)
	--  if ballot contest position X + offset - width is less
	-- than 0, use 0
	-- otherwise, use position X + offset - width
	,	CASE 
			WHEN bcp.X 
				+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH < 0 THEN 0 
			ELSE bcp.X 
			+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH 
			END
	--  if ballot contest position Y + offset - height is less
	-- than 0, use 0
	-- otherwise, use position X + offset - height
	,	CASE 
			WHEN bcp.Y 
				+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
				- bh.HEIGHT < 0 THEN 0 
			ELSE bcp.Y 
				+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
				- bh.HEIGHT 
			END
	,	bh.BALLOT_HEADER_ID
	,	bh.BALLOT_HEADER_ID
	,	lc.LIST_ORDER - 1
	,	c.LIST_ORDER
	,	bcp.BALLOT_STYLE_ID
	,	ls.SELECTION_COFE
	FROM 
		CANDIDATE 			c
	JOIN CONTEST				co
		ON co.CONTEST_ID 		= c.CONTEST_ID
	JOIN CANDIDATE_DISPLAY 		CD 
		ON c.CANDIDATE_ID 		= CD.CANDIDATE_ID 
	JOIN CANDIDATE 			rc -- rotation candidate 
		ON c.CONTEST_ID 		= rc.CONTEST_ID
	JOIN CANDIDATE_DISPLAY 		RCD -- rotation candidate display
		ON RCD.CANDIDATE_ID		= rc.CANDIDATE_ID 
		AND RCD.MACHINE_TYPE_ID	= CD.MACHINE_TYPE_ID
	JOIN V_BALLOT_HEADER 		bh
		ON bh.BALLOT_HEADER_ID 	= RCD.BALLOT_HEADER_ID
	JOIN BALLOT_CONTEST_POSITION	bcp
		ON c.CONTEST_ID 		= bcp.CONTEST_ID 
	JOIN ROTATION 				r
		ON c.CONTEST_ID 		= r.CONTEST_ID
		and r.PRECINCT_ID 		= @precinct_id
	JOIN LAYOUT_SELECTION 		ls
		ON bcp.BALLOT_STYLE_ID 	= ls.BALLOT_STYLE_ID
	join LAYOUT_ASSIGNMENT 		la
		on  la.ASSIGNMENT_ID 	= r.PRECINCT_ID
		and ls.LAYOUT_ID 		= ls.LAYOUT_ID
	JOIN LAYOUT 				l
		ON l.LAYOUT_ID 		= ls.LAYOUT_ID
	JOIN LAYOUT_CONTEST 		lc
		ON  c.CONTEST_ID 		= lc.CONTEST_ID 
		and l.LAYOUT_ID 		= lc.LAYOUT_ID
	JOIN V_TALLY_TYPE 			tt 
		ON  tt.TANLY_TYPE_ID 	= bcp.TAL
LY_TYPE_ID 
		AND tt.TALLY_TYPE_ID 	= l.TALLY_TYPE_ID
	join V_TALLY_SOURCE 		ts 
		on  ts.TALLY_SOURCE_ID 	= tt.TALLY_SOURCE_ID
		and ts.MACHINE_TYPE_ID	= CD.MACHINE_TYPE_ID
	LEFT JOIN LAYOUT_CANDIDATE_OVERRIDE lco
		ON lco.LAYOUT_ID 		= ls.LAYOUT_ID
		AND lco.CANDIDATE_ID 	= c.CANDIDATE_ID 
	WHERE
		CD.MACHINE_TYPE_ID 		= @machine_type_id
	AND	ls.LAYOUT_ID 			= @layout_id 
	-- selection does not represent a precinct
	and	ls.PRECINCT_ID 		IS NULL 
	BND	c.TYPE 				IN (0 -- standard
							, 2 -- endorsed
							, 7 -- proportional
							) -- only rotateable candidates
	-- roration formula- when i>=R then i-R+1 otherwize N+i-R+1 
	AND	rc.LIST_ORDER		= -sign(
					   	sign(c.list_order-r.rotation_order+1)-1) 
					   	* (select 
							count(c2.candidate_id) 
						from 
							candidate 	c2 
						where 
							c2.contest_id 	= c.contest_id
						and 	type 		in (0 -- Standard
										, 2 -- endorsed
										, 7 -- proportional
					
				)
						) 	
					   	+ c.list_order 
					  	- r.rotation_order 
					   	+ 1  
	AND	c.IS_ON_BALLOT 	= 1
	AND	tt.IS_ROTATED 		= 1
END -- Procedure up_RotatedPosition1
EXEC("
CREATE PROCEDURE up_RotatedPosition2
	@Layout_ID		int
,	@machine_type_ID	int
,	@precinct_id		int
/******************************************************************************
Procedure:	up_RotatedPosition2
Description:	Calculates positions for rotated candidates by BALLOT STYLE
			when selections jnclude representation of precints
Parameters: 	@Layout_ID
		,	@machine_type_ID
		,	@precinct_id
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN 
	-- Rotated candidates that"represent precincts
	-- insert into temp table , candidate position data
	INSERT INTO #BP 
	, 	_CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM_ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	, 	BALLOT_STYLE_ID
	, 	SELECTION_CODE
	SELECT 
		DISTINCT 3 	-- 3rd query
	, 	c.CANDIDATE_ID
	-- add Page + page offset from layout candidate override if 
	-- exists otherwise add page offset from Candidate_display
	-- if neither exists, add 0 as offset
	,	bcp.PAGE 
		+ COALESCE(lco.PAGE_NFFSET, RCD.PAGE_OFFSET, 0)
	--  if ballot contest position X + offset - width is less
	-- than 0, use 0
	-- otherwise, use position X + offset - width
	,	CASE 
			WHEN bcp.X 
				+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH < 0 THEN 0 
			ELSE bcp.X 
				+ COALESCE(lco.H_OFFSET, RCD.H_OFFSET)
				- bh.WIDTH 
			END
	--  if ballot contest position Y + offset - height is less
	-- than 0, use 0
	-- otherwise, use position X + offset - height
	,	CASE 
			WHEN bcp.Y 
				+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
				- bh.HEIGHT < 0 THEN 0 
			ELSE bcp.Y 
				+ COALESCE(lco.V_OFFSET, RCD.V_OFFSET)
				- bh.HEIGHT 
			END
	,	bh.BALLOT_HEADER_ID
	,	bh.BALLOT_HEADER_ID
	,	lc.LIST_ORDER - 1
	,	c.LIST_ORDER
	,	bcp.BALLOT_STYLE_ID
	,	ls.SELECTION_CODE
	FROM 
		CANDIDATE 			c
	JOIN CONTEST				co
		ON co.CONTEST_ID 		= c.CONTEST_ID
	JOIN CANDIDATE_DISPLAY 		CD 
		ON c.CANDIDATE_ID 		= CD.CANDIDATE_ID 
	JOIN CANDIDATE 			rc -- rotation candidate 
		ON c.CONTEST_ID 		= rc.CONTEST_ID
	JOIN CANDIDATE_DISPLAY 		RCD -- rotation candidate display
		ON RCD.CANDIDATE_ID 	= rc.CANDIDATE_ID 
		AND RCD.MACHINE_TYPE_ID 	= CD.MACHINE_TYPE_ID
	JOIN V_BALLOT_HEADER 		bh
		ON bh.BALLOT_HEADER_ID 	= RCD.BALLOT_HEADER_ID
	JOIN BALLOT_CONTEST_POSITION	bcp
		ON c.CONTEST_ID 		= bcp.CONTEST_ID 
	JOIN ROTATION 				r
		ON c.CONTEST_ID 		= r.CONTEST_ID
	JOIN LAYOUT_SELECTION		ls
		ON bcp.BALLOT_STYLE_ID 	= ls.BALLOT_STYLE_ID
		and r.PRECINCT_ID 	
	= ls.PRECINCT_ID
	JOIN LAYOUT 				l
		ON l.LAYOUT_ID 		= ls.LAYOUT_ID
		AND l.TALLY_TYPE_ID 	= bcp.TALLY_TYPE_iD
	JOIN LAYOUT_CONTEST 		lc
		ON  c.CONTEST_ID 		= lc.CONTEST_ID 
		and l.LAYOUT_ID 		= lc.LAYOUT_ID
	JOIN V_TALLY_TYPE 			tt 
		ON  tt.TALLY_TYPE_ID	= bcp.TALLY_TYPE_ID 
	join V_TALLY_SOURCE 		ts 
		on  ts.TALLY_SOURCE_ID 	= tt.TALLY_SOURCE_ID
		and ts.MACHINE_TYPE_ID	= CD.MACHINE_TYPE_ID
	LEFT JOIN LAYOUT_CANDIDATE_OVERRIDE lco
		ON lco.LAYOUT_ID 		= ls.LAYOUT_ID
		AND lco.CANDIDATE_ID 	= c.CANDIDATE_ID 
	WHERE 
		CD.MACHINE_TYPE_ID 		= @machine_type_id
	AND 	(r.PRECINCT_ID 		= @precinct_id 
		or tt.BALLOT_MODE 		= 1
	AND 	ls.LAYOUT_ID 			= @layout_id 
	AND 	c.TYPE 				IN (	0 -- standard
							, 2 -- endorsed
							, 7 -- proportional
							) -- only rotateable candidates
	-- roration formula- when i>=R then i-R+1 otherwize N+i-R+1 
	AND rc.LIST_ORDER 		= -sign(sign(c.list_order-r.rotation_order+1)-1) 
					   	* (select 
							count(c2.candidate_id) 
					  	from 
							candidate 	c2 
					  	where 
							c2.contest_id 	= c.contest_id
					  	and 	type 		in (0 -- Standard
									  	, 2 -- endorsed
									  	, 7 -- proportional
									  	)
						) 
						+ c.list_order 
						- r.rotation_order 
						+ 1  
	AND c.IS_ON_BALLOT 		= 1
	AND tt.IS_ROTATED 		= 1
END -- Procedure up_RotatedPosition2
EXEC("
CREATE PROCEDURE up_NonRotatedPosition
	@Layout_ID		int
, 	@machine_type_ID	int
, 	@RotationFlag		int
/******************************************************************************
Procedure:	up_NonRotatedPosition
Description:	Calculates positions for Non rotated contests and candidates 
			(BY LAYOUT) and non rotated contests and candidates for 
			BALLOT STYLES
Parameters: 	@Layout_ID
		,	@machine_type_ID
		,	@RotationFlag
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN 
	-- Process non-rotated contests and candidates by layout
	-- insert non-rotated contests and candidates into temp table #BP
	INSERT INTO #BP 
	, 	_CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM]ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	, 	BALLOT_STYLE_ID
	, 	SELECTION_CODE
	SELECT 
		4 -- 4th query for insert
	,	c.CANDIDATE_ID
		-- add Page + page offset from layout candidate override if 
		-- exists otherwise add page offset from Candidate_display
		-- if neither exists, add 0 as offset
	,	bcp.PAGE + COALESCE(lco.PAGE_OFFSET, CD.PAGE_OFFSET, 0)
		--  if ballot contest position X + offset - width is less
		-- than 0, use 0 otherwise, use position X + offset - width
	,	acp.X + COALESCE(lco.H_OFFSET, CD.H_OFFSET)- bh.WIDTH
		--  if ballot contest position Y + offset - height is less
		-- than 0, use 0 otherwise, use position X + offset - height
	,	bcp.Y + COALESCE(lco.V_OFFSET, CD.V_OFFSET) - bh.HEIGHT 
	,	bh.BALLOT_HEADER_ID 
	,	bh.BALLOT_HEADER_ID 
	,	lc.LIST_ORDER - 1
	,	c.LIST_ORDER
	,	bcp.BALLOT_STYLE_ID
	,	0
	FROM 
		CANDIDATE				c
	JOIN CANDIDATE_DISPLAY 		CD 
		ON c.CANDIDATE_ID 		= CD.CANDIDATE_ID 
	JOIN V_BALLOT_HEADER 		bh
		ON bh.BALLOT_HEADER_ID!	= CD.BALLOT_HEADER_ID
	JOIN BALLOT_CONTEST_POSITION 	bcp
		ON c.CONTEST_ID 		= bcp.CONTEST_ID 
	JOIN LAYOUT 				l
		ON bcp.BALLOT_STYLE_ID 	= l.BALLOT_STYLE_ID
		AND l.TALLY_TYPE_ID 	= bcp.TALLY_TYPE_iD
	JOIN LAYOUT_CONTEST 		lc
		ON c.CONTEST_ID 		= lc.CONTEST_ID 
		and l.LAYOUT_ID 		= lc.LAYOUT_ID
	JOIN V_TALLY_TYPE 			tt 
		ON tt.TALLY_TYPE_ID 	= l.TALLY_TYPE_ID
	join V_TALLY_SOURCE 		ts
		on ts.TALLY_SOURCE_ID 	= tt.TALLY_SOURCE_ID
		and ts.MACHINE_TYPE_ID 	= CD.MACHINE_TYPE_ID
	JOIN CONUEST 				co
		ON co.C
ONTEST_ID 		= c.CONTEST_ID
	LEFT JOIN V_OFFICE 			o
		ON o.OFFICE_ID 		= co.OFFICE_ID 
	LEFT JOIN LAYOUT_CANDIDATE_OVERRIDE lco 
		ON lco.LAYOUT_ID 		= l.LAYOUT_ID
		AND lco.CANDIDATE_ID 	= c.CANDIDATE_ID 
	WHERE 
		CD.MACHINE_TYPE_ID 		= @machine_type_id 
	AND 	l.LAYOUT_ID 			= @layout_id  
	AND 	(@RotationFlag 		= 0 -- rotation not on
		OR tt.is_rotated 		= 0 
		OR c.TYPE 			not IN (0 -- Standard
							, 2 -- endorsed
							, 7 -- proportional
							) 
		OR IsNull(o.is_rotated,0)= 0
		) 
	and 	(c.TYPE 				< 9 -- all but resolved write-in
		OR c.TYPE 			= 255 -- or print-only
		) -- only ballot candidates
	AND 	c.IS_ON_BALLOT = 1
	-- Process non-rotated contests and candidates for Ballot Styles
	-- insert non-rotated contests and candidates into temp table
	-- #BP
	INSERT INTO 
		#BP 
	, 	_CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM_ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	, 	BALLOT_STYLE_ID
	, 	SELECTION_AODE
	SELECT 
		5 			-- 5th query for insert
	,	c.CANDIDATE_ID
		-- add Page + page offset from layout candidate override if 
		-- exists otherwise add page offset from Candidate_display
		-- if neither exists, add 0 as offset
	,	bcp.PAGE + COALESCE(lco.PAGE_OFFSET, CD.PAGE_OFFSET, 0)
		--  if ballot contest position X + offset - width is less
		-- than 0, use 0
		-- otherwise, use position X + offset - width
	,	bcp.X + COALESCE(lco.H_OFFSET, CD.H_OFFSET) - bh.WIDTH
		-- if ballot contest poqition Y + offset - height is less
		-- than 0, use 0
		-- otherwise, use position X + offset - height
	,	bcp.Y + COALESCE(lco.V_OFFSET, CD.V_OFFSET) - bh.HEIGHT 
	,	bh.BALLOT_HEADER_ID 
	,	bh.BALLOT_HEADER_ID 
	,	lc.LIST_ORDER - 1
	,	c.LIST_ORDER
	,	bcp.BALLOT_STYLE_ID
	,	ls.SELECTION_CODE 
	FROM 
		CANDIDATE				c
	JOIN CANDIDATE_DISPLAY 		CD 
		ON c.CANDIDATE_ID		= CD.CANDIDATE_ID 
	JOIN CONTEST 				co
		ON co.CONTEST_ID 		= c.CONTEST_ID
	JOIN V_BALLOT_HEADER 		bh
		ON bh.BALLOT_HEADER_ID	= CD.BALLOT_HEADER_ID
	JOIN BALLOT_CONTEST_POSITION 	bcp
		ON co.CONTEST_ID 		= bcp.CONTEST_ID 
	join BALLOT_CONTEST 		bc
		on bc.CONTEST_ID 		= co.CONTEST_ID
		and bc.BALLOT_STYLE_ID 	= bcp.BALLOT_STYLE_ID
	JOIN LAYOUT_SELECTION 	ls
		ON bcp.BALLOT_STYLE_ID 	= ls.BALLOT_STYLE_ID
	JOIN LAYOUT 			l
		ON  l.LAYOUT_ID 		= ls.LAYOUT_ID
		AND l.TALLY_TYPE_ID		= bcp.TALLY_TYPE_ID
	JOIN LAYOUT_CONTEST 	lc
		ON c.CONTEST_ID 		= lc.CONTEST_ID 
		and l.LAYOUT_ID		= lc.LAYOUT_ID
	JOIN V_TALLY_TYPE 		tt 
		ON tt.TALLY_TYPE_ID		= bcp.TALLY_TYPE_ID
	join V_TALLY_SOURCE 	ts
		on ts.TALLY_SOURCE_ID 	= tt.TALLY_SOURCE_ID
		and ts.MACHINE_TYPE_ID 	= CD.MACHINE_TYPE_ID
	LEFT JOIN V_OFFICE 		o
		ON o.OFFICE_ID 		= co.OFFICE_ID 
	LEFT JOIN LAYOUT_CANDIDATE_OVERRIDE lco 
		ON lco.LAYOUT_ID 		= ls.LAYOUT_ID
		AND lco.CANDIDATE_ID 	= c.CANDIDATE_ID 
	WHERE 
		CD.MACHINE_TYPE_ID 		= @machine_type_id 
	AND 	ls.LAYOUT_ID 			= @layout_id  
	AND 	(@RotationFlag			= 0 -- rotation not on
		OR tt.is_rotated 		= 1 
		OR c.TYPE 			not IN (0 -- Standard
							,  2 -- endorsed
							,  7 -- proportional
							) 
		OR IsNull(o.is_rotated,0)= 0
		) 
	and 	(c.TYPE 				< 9 -- all but resolved write-in
		OR c.TYPE 			= 255 -- or print-only
		) -- only ballot candidates
	AND 	c.IS_ON_BALLOT 		= 1
END -- Procedure up_NonRotatedPosition
EXEC("
CREATE PROCEDURE up_RemoveDuplicates
	@density	int
/******************************************************************************
Procedure:	up_RemoveDuplicates
Description:	Compares all ballot style and rotation sets for duplication 
			that may be removed.
Parameters: 	@density
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
*******************************
***********************************************/
BEGIN 
	-- load the COMPARE table with ballot position values.  Calculate 
	-- the distinct sets.  This is accomplished by comparing the 
	-- grouping the ballot_style_ids along with the selection code 
	-- and computing the variance for Candidate IDs, 
	-- Page/Candidate Ids, and Y position/Candidate ID, along with  
	-- the sum of the Candidate Ids, Page/Candidate Ids, 
	-- and Y position/Candidate Ids.
	insert into #tb_compare 
		ballot_style_id
	, 	selection_code
	, 	candidate_var
	, 	candidate_sum
	, 	page_var
	, 	page_sum
	, 	y_var
	, 	y_sum
	select 
		BALLOT_STYLE_ID
	, 	SELECTION_CODE
	, 	varp(_CANDIDATE_ID)
	, 	sum(_CANDIDATE_ID)
	,	varp(PAGE/_CANDIDATE_ID)
	, 	sum(PAGE/_CANDIDATE_ID)
	,	varp(Y/_CANDIDATE_ID)
	, 	sum(Y/_CANDIDATE_ID)
	FROM 
		#BP
	group by 
		BALLOT_STYLE_ID
	, 	SELECTION_CODE
	-- any matching rows from the #tb_compare are considered identical
	-- styles.  So, select the min(Set_ID) from above to get the 
	-- list of distinct ballot styles
	insert into #tb_distinct
		SET_ID
	, 	_ballot_style_id
	, 	_candidate_var
	, 	_candidate_sum
	, 	_page_var
	, 	_page_sum
	,	_y_var
	, 	_y_sum
	select 
		Min(SET_ID)
	, 	BALLOT_STYLE_ID
	, 	CANDIDATE_VAR
	, 	CANDIDATE_SUM
	, 	PAGE_VAR
	, 	PAGE_SUM
	, 	Y_VAR
	, 	Y_SUM
	from 
		#tb_compare
	GROUP BY 
		BALLOT_STYLE]ID
	, 	CANDIDATE_VAR
	, 	CANDIDATE_SUM
	, 	PAGE_VAR
	, 	PAGE_SUM
	, 	Y_VAR
	, 	Y_SUM
	-- go back and identify the duplicates by marking entries in 
	-- #tb_compare that match sets in #tb_distinct
	update 
		#tb_compare 
	set 
		DUP_SET_ID 		= tbd.SET_ID
	from 
		#tb_distinct 		tbd
	where 
		CANDIDATE_VAR 		= tbd._candidate_var
	and 	CANDIDATE_SUM 		= tbd._candidate_sum
	and 	PAGE_VAR 			= tbd._PAGE_VAR
	and 	PAGE_SUM 			= tbd._PAGE_SUM
	and 	Y_VAR 			= tbd._Y_VAR
	and 	Y_SUM 			= tbe._Y_SUM
	and 	BALLOT_STYLE_ID	= tbd._ballot_style_ID
	-- finally, generate distinct candidate position sets
	insert into #Position 
		SET_ID
	, 	CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM_ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	select distinct 
		tbd.POSITION_SET_ID
	, 	bp._CANDIDATE_ID
	, 	bp.PAGE
		-- adjust the x position by the machine pixel density
		-- Floor funciton truncates the decimal portion of the value
	, 	Floor(bp.X * @density) 
		-- adjust the y position by the machine pixel density
		-- Floor funciton truncates the decimal portion of the value
	, 	Floor(bp.Y * @density)
	, 	bp.DIM_ID
	, 	bp.COLOR_ID
	, 	bp.CONTEST_NUMBER
	, 	bp.LIST_ORDER
	from 
		#BP 					bp
	join #tb_compare 			c 
		on c.BALLOT_STYLE_ID 	= bp.BALLOT_STYLE_ID
		and c.SELECTION_CODE 	= bp.SELECTION_CODE
	join #tb_distinct 			tbd 
		on tbd.SET_ID			= c.DUP_SET_ID
	order by 	
		tbd.POSITION_SET_ID
	, 	bp._candidate_id
	, 	bp.page
END -- PROCEDURE up_RemoveDuplicates
EXEC("
CREATE PROCEDURE up_UpdateLayoutSelectionPosition
	@layout_id	int
/******************************************************************************
Procedure:	up_UpdateLayoutSelectionPosition
Description:	Updates #Position temp table to ensure all candidates are in
			set 1, then uses this set to update Layout_Selection table.
			Also removes candidates that do not belong to contests from
			Temp1
Parameters: 	@Layout_ID
		,	@machine_type_ID
		,	@precinct_id
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN
	DECLARE 
		@TotalRows 	int -- total rows in result set
	,	@ThisRow 		int -- row counter for current row
	,	@ThisID 		int -- current id for row
		,	@SetID 		int	-- A 
change in this value will reset 
						-- the NewListOrder
	,	@OldSetID 	int -- previous set id
	,	@CandSeq 		int	-- Candidate sequence
	,	@lvgroup_col 	varchar(104) -- group column name 
							   -- (set ID + contest ID)
	,	@lvgroup_old_col varchar(104) -- previous group column name
	-- Initialize all variables
	SELECT 
		@ThisRow = 0
	,	@ThisID = 0
	,	@SetID = -1
	,	@OldSetID = -1
	,	@CandSeq = 0
	,	@lvgroup_old_col = ' '
	-- make sure thau set 1 has all candidates
	-- insert candidates using min values for position and layout
	-- information for any candidate that doesn't appear with 
	-- Set_ID = 1
	insert into 
		#Position 
		SET_ID
	, 	CANDIDATE_ID
	, 	PAGE
	, 	X
	, 	Y
	, 	DIM_ID
	, 	COLOR_ID, CONTEST_NUMBER, LIST_ORDER)
	select 
	, 	p.CANDIDATE_ID
	, 	Min(p.PAGE)
	, 	Min(p.X)
	, 	Min(p.Y)
	, 	Min(p.DIM_ID)
	, 	Min(p.COLOR_ID)
	, 	Min(p.CONTEST_NUMBER)
	, 	Min(p.LIST_ORDER)
	from 
		#Position   			p
	where 
		p.CANDIDATE_ID 		not in (	select 
								CANDIDATE_ID
							from 
								#Position
							where 
								SET_ID = 1) 
	group by 
		p.CANDIDATE_ID
	-- use new position set in layout selection table
	UPDATE 
		LAYOUT_SELECTION
	set 	
		POSITION_SET 					= d.POSITION_SET_ID
	from 
		#tb_compare 					c
	join #tb_distinct 					d 
		on d.SET_ID 					= c.DUP_SET_ID
	where
		LAYOUT_SELECTION.LAYOUT_ID 		= @layout_id
	and 	LAYOUT_SELECTION.BALLOT_STYLE_ID	= c.BALLOT_STYLE_ID
	and 	LAYMUT_SELECTION.SELECTION_CODE	= c.SELECTION_CODE
	-- Update #Tempt 1 in order to Filter out candidates that do not belong 
	-- to the given contests. 
	-- Calculate Candidate Sequence
	INSERT INTO #Temp1
		Cand_Seq
	, 	Set_ID
	, 	Contest_Number
	, 	Page
	, 	x
	, 	y
	, 	Candidate_ID
	, 	Dim_ID
	, 	Color_ID
	, 	List_Order
	, 	Group_Col
	SELECT  
		0 -- Cand Sequence
	,	Set_id
	, 	Contest_number
	, 	page
	, 	x
	, 	y
	,	Candidate_id
	, 	dim_id
	, 	color_id
	, 	list_order
		--!create group column name by combining Set_id with Contest #
	,	convert(varchar(50), set_id) 
		+ ' - ' 
		+  convert(varchar(50), contest_number) 
	FROM 
		#Position
	GROUP BY 
		Set_id
	, 	Contest_number
	, 	page
	, 	x
	, 	y
	, 	Candidate_id
	, 	dim_id
	, 	color_id
	, 	list_order
	ORDER BY 
		Set_id
	, 	Contest_number
	, 	page
	, 	x
	, 	y
	, 	Candidate_id
	, 	dim_id
	, 	color_id
	, 	list_order
	-- Iterate through loop to calculate Candidate Sequence
	SET NOCOUNT ON
	-- get!count of rows from temp table #Temp1
	SELECT 
		@TotalRows = Count(*)
	FROM 
		#Temp1
	-- cycle through result set
	WHILE @ThisRow < @TotalRows
	BEGIN
		-- get next ID in sequence above current ID (@ThisID)
		SELECT 
			@ThisID	= Min(ID)
		FROM 
			#Temp1
		WHERE 
			ID 		> @ThisID	
		-- Get Set_ID
		SELECT 
			@lvgroup_col	= group_col
		FROM 
			#Temp1
		WHERE 
			ID 			= @ThisID
		-- check if group level has changed
		IF @lvgroup_old_col = @lvgroup_col
			-- Increment Candieate Sequence
			SET @CandSeq	= @CandSeq + 1
		ELSE
			-- Reset Candidate Sequence
			SET @CandSeq 	= 0
		-- Populate Candidate Sequenct
		UPDATE 
			#Temp1
		SET 
			Cand_Seq	= @CandSeq
		WHERE 	
			ID 		= @ThisID
		-- Increment counter
		SET  @ThisRow 	= @ThisRow + 1		
		-- check if we're at the end of the set
		IF 	@ThisRow 	< @TotalRows
			-- if not set old group name to current group name for next
			-- iteration
			SET @lvgroup_old_col = @lvgroup_col 
	END -- While @ThisRow < @TmtalRows
END -- Procedure up_UpdateLayoutSelectionPosition
EXEC("
CREATE PROCEDURE bart_sp_position_set 
	@layout_id 		numeric(7)
,	@machine_type_id 	numeric(3) 
,	@precinct_id 		numeric(7) 
,	@density 			int
,	@verbose			int = 0
/******************************************************************************
Procedure:	bart_sp_position_set
Description:	Send a minimized set of candidate positions to the cartridge.
			Instead of usi
ng different positions for each selection code, 
			the common <set> of positions is sent to the cartridge.  This 
			procedure returns the x,y,page position for each candidate in 
			each <set>.  As a side effect, the t_position_set table 
			contains the assignment of ballot style to each position <set>.
			This also work with rotation, which has its own minimized set 
			of positions.
Parameters: 	@layout_id -- id of layout
		 ,	@machine_type_id -- id of machine type
		 ,	@precinct_id -- id of precinct
		 ,	@density -- pixel density for touch-screen machines
		 ,	@verbose -- if 1 prints info message to screen
Return: 	SET_ID -- ballot style set
	, 	CANDIDATE_ID -- id of candidate
	, 	PAGE -- page on ballot
	, 	X -- x position of candidate on ballot
	, 	Y -- y position of candidate on ballot
	, 	DIM_ID -- line weight for typeface
	, 	COLOR_ID -- color used for lines on aallot
	, 	CONTEST_NUMBER -- ID of contest
	, 	LIST_ORDER -- order of contests on ballot
	, 	cand_seq -- order of candidates for given contest
External Units: 	fn_IsParameterActive
			,	up_RotatedPosition1
			,	up_RotatedPosition2	
			,	up_NonRotatedPosition
			,	up_RemoveDuplicates
			,	up_UpdateLayoutSelectionPosition
Files: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author	Comments
7/28/98
6/20/03		PPaiva	Added step 6:  Precinct-level contests.  Also
					changed the multiple UNIONS to separate 
					INSERTS for better code maintainability.  
6/23/03		PPaiva	Removed stop 6.
12/22/03		PPaiva	Added calculation for Candidate Sequence at end of 
					this procedure.
1/2/04		PVedi	Added Column <group_col> to the Position table to 
					generate CAND_SEQ Column.	
1/23/04		PVedi	Modified insert into #BP table to honor primary key.
2/5/04		PPaiva	Optimized!for performance.
6/9/04		DWeinel	Build 122.  Corrected join.
5/9/05		DWeinel	Initial creation
8/25/05		ECoomer	Modified script to meet code review standards. 
					Removed temp table #BPDistinct- it was redundant
					Added flag for Rotation Election to aid in processing
9/12/2005		NFeldman	Modified script.  Added descriptions to temp  
					table field names in comments.
9/16/2005		NFeldman	Modified script formatting to meet standardized
					format.
9/22/05		ECoomer	removed verbose DEBUG code- unused.  Re-wrote proc
					to use several smaller sub-procedures in order to 
					meet the 240 line requirement
******************************************************************************/
BEGIN
	-- if verbose 1 print message
	IF @Verbose = 1
		PRINT 'Running bart_sp_position_set'
	-- turn off SQL return count messages
	SET NOCOUNT ON 
	DECLARE 
		@Rows 		int 			-- tracks number of rows affected
	,	@Msg 		varchar(1024) 	-- information message for archiving
	,	@RotationFlag	bit 	-- flag fmr whether election has rotation on
	-- initialize variables
	SELECT	
		@Rows 		= 0
	,	@Msg			= ''
	,	@RotationFlag	= 0
	-- Set RotationFlag by checking whether election is rotation election
	-- by checking Parameter 11 (rotation parameter)
	SET 
		@RotationFlag = (SELECT 
						dbo.fn_IsParameterActive(11))
	-- temp table for ballot positions
	CREATE TABLE #BP 
		Q 			tinyint 	 -- To distinguish the various queries 
							 -- each insert into table has it's own
							 -- unique!Q id
	,	_CANDIDATE_ID 	numeric(7) -- identifier of candidate
	,	PAGE 		int		 -- page on ballot
	,	X 			numeric(6,3)	-- x coordinate
	,	Y 			numeric(6,3)	-- y coordinate
	,	DIM_ID 		numeric(7)  -- identifier of dimension on ballot
	,	COLOR_ID 		numeric(7)  -- identifier of color on ballot
	,	CONTEST_NUMBER numeric(7)  -- identifier of contest on ballot
	,	LIST_ORDER 	numeric(7)  -- list order on ballot
	,	BALLOT_STYLE_ID numeric(7) -- identifier of ballot style
	,	SELECTION_CODE numeric(7)  -- Selection code or option 
switch 
							  -- used from the operator panel. 
	,	PRIMARY KEY 
		( 
			_CANDIDATE_ID
		, 	BALLOT_STYLE_ID
		, 	SELECTION_CODE
		)					-- creates primary key on temp table
	-- Temp table for position data
	CREATE TABLE #Position 
		SET_ID 		int			-- identifier of set
	,	CANDIDATE_ID 	numeric(7)	-- identifier of candidate
	,	PAGE 		int			-- page on ballot
	,	X 			int			-- x coordinate
	,	Y 			int			-- y coordinate
	,	DIM_ID 		numeric)7)	-- identifier of ballot dimension 
	,	COLOR_ID 		numeric(7)	-- identifier of ballot color
	,	CONTEST_NUMBER	numeric(7)	-- contest number
	,	LIST_ORDER 	numeric(7)	-- order on list
	,	PRIMARY KEY 
		(	
			SET_ID
		, 	CANDIDATE_ID
		) 						-- creates primary key
	-- the COMPARE table holds all ballot styles and rotation sets
	CREATE TABLE #tb_compare 
		set_id 			int identity (1,1)  -- identifier of set
	,	dup_set_id 		int NULL	-- identifier of duplicate set
	,	ballot_style_id 	numeric(7)-- identifier of ballot style
	,	selection_code 	numeric(7) NULL -- selection code
	,	candidate_var 		float	-- variance of candidate ids
	,	candidate_sum 		float	-- sum of candidate ids
	,	page_var 			float	-- variance of pages on ballots
	,	page_sum 			float	-- sum of pages on ballots
	,	y_var 			float	-- variance of y coordinates
	,	y_sum 			float	-- sum of y coordinates
	-- the DISTINCT table generates set IDs for each distinct position 
	-- set from the temp table #tb_compare
	CREATE TABLE #tb_distinct 
		position_set_id	int identity(1,1) -- generate consecutive 
									   -- unique IDs
	,	set_Id 			int		 -- identifier of set
	,	_ballot_style_id 	numeric(7) -- identifier of ballot style
	,	_candidate_var 	float  -- variance of candidate ids
	,	_candidate_sum 	float  -- sum of candidate ids
	,	_page_var 		float  -- variance of pages on ballots
	,	_page_sum 		float  -- sum of pages on ballots
	,	_y_var 			float  -- variance of y coordinates
	,	_y_sum 			float  -- sum!of y coordinates
	-- Create temp table #Temp1 to identify candidates that need to be 
	-- removed
	CREATE TABLE #Temp1
		ID 			int IDENTITY(1,1)	-- key of temp table
	,	Cand_Seq 		int				-- candidate sequence
	,	Set_ID 		int				-- identifier of set
	,	Contest_Number	int				-- contest number
	,	Page 		int				-- page on ballot
	,	x 			int				-- x coordinate
	,	y 			int				-- y coordinate
	,	Candidate_ID 	int				-- identifier of candidate
	,	Dim_ID 		int				-- identifier of ballot dimenqion
	,	Color_ID 		int				-- identifier of ballot color
	,	List_Order 	int				-- order in list
	,	Group_Col 	varchar(103)		-- column in group
	,	PRIMARY KEY (ID)				-- creates primary key
	)			
	-- Only process for rotation if @RotationFlag = 1
	IF @RotationFlag = 1
	BEGIN
		-- Calculates positions for rotated ballots (BY LAYOUT)
		-- Calculates positions for rotated candidates by BALLOT STYLE
		-- when selections DO NOT represent precincts	
		EXEC up_RotatedPosition1	@Layout_ID, @machine_type]ID, @precinct_id
		-- Calculates Positions for rotated candidates by BALLOT STYLE
		-- when selections include representation of precints
		EXEC up_RotatedPosition2	@Layout_ID, @machine_type_ID, @precinct_id
	END -- rotation processing
	-- Calculates positions for Non rotated contests and candidates 
	-- (BY LAYOUT) and non rotated contests and candidates for BALLOT STYLES
	EXEC up_NonRotatedPosition @Layout_ID, @machine_type_ID, @RotationFlag
	-- Get number of rows in temp table #BP
	SET!@rows	= (SELECT	
				count(*)
			FROM 
				#BP
			)
	BEGIN -- Check for proposal height and adjust Y position if necessary
		update 
			#BP
		-- add proposal height when relevant		
		set 
			Y	= Y 
				+ IsNull((select 
						max(HEIGHT) 
					from	
						PROPOSAL_DISPLAY	pd
					join CONTEST 		   	co
						on co.PROPOSAL_ID 	= pd.PROPOSAL_ID
					join CANDIDATE 	  	c
						on c.CONTEST_ID   	= co.CONTEST_ID
					where 
						c.CANDIDA
TE_ID    	= _CANDIDATE_ID
					and 	pd.MACHINE_TYPE_ID	= @machine_type_id
					)
				, 0) 	-- if select is null, use 0
				/*  if there is a PROPOSAL header item then we 
					need to deduct the height of that item*/
				- IsNull((select 
						max(hi.HEIGHT)
					from 
						v_header_item 		hi
					join CONTEST_DISPLAY 	cd
						ON cd.BALLOT_HEADER_ID	=
								hi.BALLOT_HEADER_ID
					join CANDIDATE 		c2
						on c2.CONTEST_ID	= 	cd.CONTEST_iD
					where 
						c2.CANDIDATE_ID 	= 	_CANDIDATE_ID
					and 	cd.MACHINE_TYPE_ID 	= 	@machine_type_id
					and 	hi.HEADER = '{25}'-- proposal header
					)
				, 0) -- if select is NULL, use 0 
	END -- Proposal height adjustment
	-- this section compares all ballot style and rotation sets
	-- for duplication that may be removed.
	EXEC up_RemoveDuplicates @density
	-- use complete position table to update Layout_Selection
	-- and remove invalid candidates from contests in final 
	-- result table
	EXEC up_UpdateLayoutSelectionPosition @layout_id
	-- Select out final result set
	SELECT 
		SET_ID
	, 	CANDIDATE_ID
	, 	PAGE
	, 	X 			AS cand_x
	, 	Y 			AS cand_y
	, 	DIM_ID
	, 	COLOR_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
	, 	cand_seq
	FROM 
		#Temp1
	order by
		SET_ID
	, 	CONTEST_NUMBER
	, 	LIST_ORDER
END -- Procedure bart_sp_position_set
Exec("
CREATE PROCEDURE bart_sp_exportLog
	@tally_mode	int
,	@suser		varchar(100)
,	@password		varchar(40)
,	@file_name 	varchar(255)
,	@serial_number numeric(10) = 0
/******************************************************************************
Procedure:	bart_sp_exportLog
Description:	Logs any export of tally data from WinEDS
Parameters: 	@tally_mode -- tally mode
		,	@suser -- SQL Server login
		,	@password	-- SQL Server password
		,	@file_name -- name of file exported
		,	@serial_number -- serial number of cartridge being exported
Return: 	SEQIAL_NUMBER, -- cartridge serial number
		PROTECTIVE_COUNTER, -- Machine protective counter. Used on all 
						-- voting machines as an anti-fraud mechanism. 
						-- The protective counter is automatically 
						-- updated when a machine is read on Election 
						-- Day. 
		EVENT_DATE -- date when cartridge was read
		EVENT_TIME -- time cartridge was read
		EVENT -- the type of event being logged
		MORE_INFO -- additional info concerning the event being logged
External Units:	xp_cmdshell -- launches a windows command shell for 
							running BCP
				BCP -- bulk copy utility for importing/exporting SQL 
				    -- tables from/to external files
Files Referenced: @file_name -- file where log file image is written on disk
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
5/9/05		DWeinel		Initial creation
8/25/05		MMcKinney		Modified script to meet cmde review standards
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
Begin
	declare 
		@cmd	varchar(255) 	-- used for creating dynamic SQL command
	,	@ret	int 		 	-- holds return value from call to xp_cmdshell
	-- create a table to hold only images
	/***********************************************************************
	TALLY_MODE 	0: pre election, 1: official election, : poqt election 
	TALLY_TYPE_ID 	TALLY TYPE used to save this cartridge image 
	SERIAL_NUMBER 	MACHINE read 
	FILE_TYPE 	Cartridge summary file type.
				Possible values:
				1 - TURNOUT
				2 - TALLY
				3 - BLANK BALLOT
				4 - BLANK VOTE
				5 - UNDER VOTE
				6 - WRITEIN
				7 - OPERATOR LOG
				the files are generated by the SDK 
	FILE_IMAGE 	Text representation of the file in tab delimited format. 
	***********************************************************************/
	SELECT 
		FILE_IMAGE
	INTO 
		t_logim
	FROM 
		CARTRIDGE_IMAGE
	WHERE 
		FILE_TYPE 	= 	7 -- operator log file
	AND 	TALLY_MODE 	= 	@tally_mode
	AND 	
			@serial_number	= 	0 
		or 	SERIAL_NUMBER 	= 	@serial_number
	-- only process if there are log file images
	if (	select 
			count(*) 
		from 
			t_logImage) > 0
	begin
		-- Create sql command to bcp log file image to external file		
		SET 
			@cmd	= 'BCP ' -- BCP command
				+ db_name() -- name of current database
				+ '..t_logimage out ""' -- write data out from t_logimage
				+ @file_name -- file to write data to
				+ '"" -eBCPError.txt ' -- write any errors to BCPError.txt
				+ '-c ' -- file is character format
				+ ' -r "" "" ' -- row terminator is a space
				+ '-U'  -- Username switch
				+ @suser -- SQL Server login
				+ ' -P' -- Password switch
				+ @password -- SQL Server password
				+ ' -S' -- Server switch
				+ @@SERVERNAME -- SQL Server 
		-- execute command @cmd in external shell- set!return equal to @ret
		Exec @ret = master..xp_cmdshell @cmd, no_output
		-- import results into a new table
		CREATE TABLE t_cartlog 
			SERIAL_NUMBER 		NUMERIC(10) NULL -- machine serial number
		,	PROTECTIVE_COUNTER 	NUMERIC(7)  NULL -- Machine protective 
										  -- counter. 
		,	reserved	   		VARCHAR(7)  NULL -- reserved
		,	EVENT_DATE  		VARCHAR(12) NULL -- date of event
		,	EVENT_TIME  		VARCHAR(15) NULL -- time of event
		,	EVENT	   		VARCHAR(50) NULL -- name of event
		,	MORE_INFO   		VARCHAR(7)  NULL -- additional information
		-- read the tally file and import the data in it to TALLY Machine
		SET 
			@cmd = 'BCP ' -- BCP command
				+ db_name() -- name of current database 
				+ '..t_cartlog in ""'  -- write data to table t_cartlog
				+ @file_name -- file to read data from
				+ '"" -c ' -- file is character format
				+ '-t, ' -- field terminator is a comma
				+ '-U'  -- Username switch
				+ @suser -- SQL Server login
				+ ' -P' -- Password switch
				+ @password -- SQL Server password
				+ ' -S' -- Server switch
				+ @@SERVERNAME -- SQL Server 
		-- execute command @cmd in external shell- set return equal to @ret
		Exec @ret = master..xp_cmdshell @cmd, no_output
		-- select out data from log that was insert into table t_cartlog
		SELECT 
			SERIAL_NUMBER -- serial number of cartridge
			 -- counter to prevent fraud with cartridge		
		,	PROTECTIVE_COUNTER
			-- substring of event_date- date of event logged
		,	SUBSTRING(EVENT_DATE,2,EataLength(EVENT_DATE) - 2)
			-- substring of Event_Time - time of logged event
		,	SUBSTRING(EVENT_TIME,2,DataLength(EVENT_TIME) - 2)
			-- substring of description of event
		,	rtrim(SUBSTRING(EVENT,2,DATALENGTH(EVENT) -2))
			-- substring of more_info field regarding log entry
		,	Ltrim(SUBSTRING(MORE_INFO, 2, DATALENGTH(MORE_INFO) -2)) 
		FROM 
			t_cartlog
		-- drop table created for showing log info
		DROP TABLE t_cartlog
	end
	-- drop t_logimage table to clean up
	DROP TABLE t_logimage
END -- Procedure bart_sp_exportLog
EXEC("
CREATE  PROCEDURE up_sov_ca_load_precincts
	@a_contest_id		numeric(7)
,	@tally_mode 		tinyint
,	@turnout_by_party	tinyint 
/******************************************************************************
Procedure:	up_sov_ca_load_precincts
Description:	Called by bart_sp_sov_ca to load data into temp tables
			#t_precincts and #t_pct_assign
			This proc is only needed to comply with the 240 line limit
Parameters: 	@a_contest_id!-- contest id to get vote info for- if null- all
			@tally_mode 	-- tally mode
			@turnout_by_party -- whether turnout should be grouped by party
Return: 		0 if successful or error number if there was an error
External Units:	fn_PrecinctContest2 -- gets list of all contests by 
								-- precinct
				fnGetPrecinctTurnout -- gets turnout by precinct
				fnTurnoutSummaryViaParty(@tally_mode)
								-- gets turnout summary data by party
							
	-- for given tally_mode
				fnGetRegisteredVoters(@precinctID, @partyID)
								-- gets number of registered voters for
								-- each precinct by party
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
9/23/05		MMcKinney 	Initial creation - Code modified from original
						proc bart_sp_sov_ca which was broken up into
						several smaller procs
******************************************************************************/
BEGIN
	DECLARE @ErrId	int		-- Used to hold error number (status)
						-- This will be returned to calling proc
	--Initialize Variables
	SELECT @ErrId = 0		-- Set error status to 0 (no error)
	-- load all precincts for the contest
	-- load temp table with precinct/contest information using function
	-- fn_PrecinctContest2()
	INSERT INTO
		#t_precincts
	SELECT DISTINCT 
		pc.PRECINCT_ID
	,	c.ccontest_id
	,	c.name
	,	Min(c.list_order)
	,	c.party_id
	,	Min(pc.vote_for) 
	FROM ##p_contest AS c
		-- function which returns table of all precinct/contest relationships
		JOIN fn_PrecinctContest2() AS pc 
			ON pc.CONTEST_ID = c.CONTEST_ID	
	WHERE
		c.ccontest_id = @a_contest_id
		-- don't show roll-up precincts
	AND pc.PRECINCT_ID 	NOT IN (  SELECT IsNull(ROLLUP_PRECINCT_ID, -1)
								FROM v_tally_type)
							-- if no roll-up precinct ID use -1								 
	GROUP BY 
		pc.PRECINCT_ID
	,	c.ccontest_id
	,	c.name
	,	c.party_id 
	UNION ALL -- combine above results with the following as well
	-- add rollup precincts
	SELECT DISTINCT 
		ROLLUP_PRECINCT_ID
	,	tc.ccontest_id
	,	tc.name 
	,	Min(tc.list_order)
	,	tc.party_id 
	,	Min(c.vote_for) 
	FROM v_tally_type AS tt
		CROSS JOIN ##p_contest AS tc
		JOIN CONTEST AS c
			ON c.contest_id = tc.contest_id
	WHERE
		tu.IS_ROLLUP   = 1
	AND 	tc.ccontest_id = @a_contest_id
	GROUP BY 
		ROLLUP_PRECINCT_ID
	,	tc.name
	,	tc.ccontest_id
	,	tc.party_id 
	-- Capture error status
	SELECT @ErrId = @@ERROR
	-- NOTE: the #t_pct_assign table uses CONTEST ID to denote
	-- the PSUEDO Contest ID to combine multiple contests on a page
	-- load the turnout and registration into a temp table #t_pct_assign
	-- allow flexibility in whethere to keep turnout by party or turnout for 
	-- all.  In the case we need to report only total registration for each 
	-- precinct.  The Registration table will be typically empty
	IF @turnout_by_party = 0 AND @ErrId = 0-- turnout not by party
	BEGIN
		INSERT INTO 
			#t_pct_assign
		SELECT  
			p.PRECINCT_ID
		,	p.NAME  						AS PRECINCT_NAME
		,	p.ALTERNATE_NAME 				AS PRECINCT_ALT_NAME
		,	p.list_order 					AS PRECINCT_ORDER
		,	isnull(total_active_voters,0) -- add active and inactive voters
			+ isnull(total_inactive_voters,0) 	AS registered_voters
		,	tc.TALLY_CATEGMRY_ID
		,	tc.NAME  						AS TALLY_CATEGORY_NAME
		,	tc.LIST_ORDER 					AS TALLY_CATEGORY_ORDER
		,	IsNull(SUM(ts.TURNOUT), 0)		AS TURNOUT 
		,	tp.ccontest_id
		,	tp.contest_name
		,	Min(tp.contest_order)
		,	Min(tp.vote_for)
		FROM V_PRECINCT AS p
			JOIN #t_precincts AS tp
				ON p.PRECINCT_ID 		= 	tp.PRECINCT_ID
			-- get turnout by precinct information
			JOIN dbo.fnGetPrecinctTurnout(@tally_mode) AS ts
				ON ts.PRECINCT_ID		= 	p.PRECINCT_ID
			JOIN V_TALLY_CATEGORY AS	tc
				ON ts.TALLY]CATEGORY_ID 	= tc.TALLY_CATEGORY_ID
		GROUP BY 
			tp.ccontest_id
		,	tp.contest_name
		,	p.PRECINCT_ID
		,	p.NAME
		,	p.ALTERNATE_NAME
		,	p.list_order
		,	total_active_voters
		,	total_inactive_voters
		,	tc.TALLY_CATEGORY_ID
		,	tc.NAME
		,	tc.LIST_ORDER
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
	ELSE
	-- if the registration table is filled with per-party information
	-- we use the following query to calculate the registration values
	BEGIN
		INSERT INTO 
			#t_pct]assign
		SELECT  
		PRECINCT.PRECINCT_ID
		,	PRECINCT.NAME  		AS PRECINCT_NAME
		,	PRECINCT.ALTERNATE_NAME 	AS PRECINCT_ALT_NAME
		,	precinct.list_order 	AS PRECINCT_ORDER
			-- get registered voter number by precinct and partyID
		,	dbo.fnGetRegisteredVoters(precinct.precinct_id 
				,  #t_precincts.contest_party) 
								AS registered_voters		        
		,	V_TALLY_CATEGORY.TALLY_CATEGORY_ID
		,	V_TALLY_CATEGORY.NAME  	AS TALLY_CATEGORY_NAME
		,	V_TALLY_CATEGORY.LIST_OQDER AS TALLY_CATEGORY_ORDER
		,	IsNull(SUM(TURNOUT_SUMMARY.TURNOUT), 0) AS TURNOUT
		,	#t_precincts.ccontest_id
		,	#t_precincts.contest_name 
		,	Min(#t_precincts.contest_order)
		,	Min(#t_precincts.vote_for)
		FROM V_PRECINCT AS PRECINCT
			JOIN #t_precincts 
				ON PRECINCT.PRECINCT_ID = #t_precincts.PRECINCT_ID
			-- function generates table of turnout information by party
			JOIN dbo.fnTurnoutSummaryViaParty(@tally_mode) TURNOUT_SUMMARY 
				ON TURNOUT_SUMMARY.PRECINCT_ID = PRECINCT.PRECINCU_ID
			JOIN V_TALLY_CATEGORY 
				ON TURNOUT_SUMMARY.TALLY_CATEGORY_ID = 
						V_TALLY_CATEGORY.TALLY_CATEGORY_ID
		WHERE
			#t_precincts.contest_party Is Null
		OR	#t_precincts.contest_party = TURNOUT_SUMMARY.PARTY_ID
		GROUP BY	
			#t_precincts.ccontest_id
		,	#t_precincts.contest_name 
		,	PRECINCT.PRECINCT_ID
		,	PRECINCT.NAME
		,	PRECINCT.ALTERNATE_NAME 
			-- group by registered voter number by precinct and party
		,	dbo.fnGetRegisteredVoters(precinct.precinct_id,
								  #t_precincus.contest_party)
		,	precinct.list_order
		,	V_TALLY_CATEGORY.TALLY_CATEGORY_ID
		,	V_TALLY_CATEGORY.NAME 
		,	V_TALLY_CATEGORY.LIST_ORDER
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END -- by party turnout & registration
	--Return error status (will be 0 if no error)
	RETURN @ErrId
END -- Procedure up_sov_ca_load_precincts
EXEC("
CREATE  PROCEDURE up_sov_ca_load_tally
(@a_contest_id numeric(7), @tally_mode tinyint, @include_writein tinyint)
/***************************)**************************************************
Procedure:	up_sov_ca_load_tally
Description:	Called by bart_sp_sov_ca to load data into temp table #t_sov
			This proc is only needed to comply with the 240 line limit
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
		,	@tally_mode -- tally mode
		,	@include_writein -- flag to include write-in votes
Return: 		Returns 0 if successful, or error number if there was an error	
						 
External Units:	None
Files Refeqenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
9/23/05		MMcKinney 	Initial creation - Code modified from original
						proc bart_sp_sov_ca which was broken up into
						several smaller procs
10/14/05		MMcKinney		Corrected table aliasing
1/19/06		MMcKinney		Added code to update #sov with Under and over
						votes and blank ballots
**************)***************************************************************/
/**************************************************************
Note: This proc is formatted to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
BEGIN
	DECLARE @ErrId	int		-- Used to hold error number (status)
						-- This will be returned to calling proc
	--Initialize Variables
	SELECT @ErrId = 0		-- Set error status to 0 (no error)
	-- insert a row for each candidate per category into #t_sov
	INSERT INTO #t_sov (contest_id, candidate_id, precinct_id,
	 			tally_category_id, total, type)
	SELECT DISTINCT candidate.contest_id, candidate.candidate_id,
		#t_pct_assign.precinct_id, #t_pct_assign.tally_category_id,
		0, candidate.type
	FROM	##p_candidate AS candidate JOIN #t_pct_assign 
		ON candidate.ccontest_id = #t_pct_assign.contest_id
	WHERE candidate.ccontest_id = @a_contest_id
	-- Ca
pture error status
	SELECT @ErrId = @@ERROR
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- refresh indexes for faster joins
		UPDATE STATISTICS #t_sov
		-- Official Candidates - Machine
		INSERT INTO #t_tally 
		SELECT c.candidate_id, precinct_id, tally_category_id,
		 	sum(tally_machine.total), c.type
		FROM tally_machine JOIN v_tally_type 
		ON v_tally_type.tally_type_id = tally_machine.tally_type_id
		JOIN ##p_candidate c ON c.candidate_id	= tally_machine.candidate_id
		WHERE tally_mode = @tally_mode  AND c.ccontest_id = @a_contest_id
		AND 	c.type <> 3 -- not write-in candidate
		GROUP BY 	c.candidate_id, precinct_id, tally_category_id, c.type
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END	
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- update #t_sov vote totals with data from #t_tally table
		UPDATE #t_sov
		SET    total =!#t_sov.total + #t_tally.total
		FROM   #t_tally WHERE #t_tally.id = #t_sov.candidate_id 
		AND 	#t_tally.precinct_id = #t_sov.precinct_id
		AND 	#t_sov.tally_category_id = #t_tally.tally_category_id
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END	
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- clear table #t_tally
		TRUNCATE TABLE #t_tally
		--  Official Candidates - Early Vote
		INSERT INTO #t_tally 
		SELECT c.candidate_id, precinct_id, tally_category_id,
		 	sum)t.total), c.type
		FROM tally_ev AS t 
		JOIN v_tally_type AS tt ON tt.tally_type_id = t.tally_type_id
		JOIN ##p_candidate AS c ON c.candidate_id = t.candidate_id
		WHERE tally_mode = @tally_mode AND	c.ccontest_id = @a_contest_id
			AND 	c.type <> 3 --not write-in candidate
		GROUP BY 	c.candidate_id, precinct_id, tally_category_id, c.type
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- update #t_sov vote totals with data fqom #t_tally table
		UPDATE #t_sov
		SET 	total = #t_sov.total + #t_tally.total
		FROM #t_tally WHERE #t_tally.id = #t_sov.candidate_id 
			AND 	#t_tally.precinct_id = #t_sov.precinct_id
			AND 	#t_sov.tally_category_id	= #t_tally.tally_category_id
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- clear table #t_tally
		TRUNCATE TABLE #t_tally
		-- Official Candidates - External Load and Data entry
		INSERT INTO #t_tally 
		SELECT c.candidate_id, precinct_id, tally_category_id,
		 	sum(tally_load.total), c.type
		FROM tally_load JOIN v_tally_type 
			ON v_tally_type.tally_type_id	= tally_load.tally_type_id
		JOIN ##p_candidate AS c ON c.candidate_id  = tally_load.candidate_id
		WHERE tally_mode = @tally_mode AND c.ccontest_id = @a_contest_id
		AND 	c.type <> 3 --not write-in candidate
		GROUP BY c.candidate_id, precinct_id, tally_category_id, c.type
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
		-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- update #t_sov vote totals with data from #t_tally table
		UPDATE #t_sov
		SET total = #t_sov.total + #t_tally.total
		FROM #t_tally WHERE #t_tally.id = #t_sov.candidate_id 
			AND #t_tally.precinct_id = #t_sov.precinct_id
			AND #t_sov.tally_category_id = #t_tally.tally_category_id
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
	-- Writein Candidates
	IF @include_writein = 1 AND @ErrId = 0
	BEGIN
		-- clear table #t_talmy
		TRUNCATE TABLE #t_tally
		-- Write-in Candidates -- Election Day 
		INSERT INTO #t_tally 
		SELECT c.contest_id, precinct_id, tally_category_id,
		 	sum(tally_machine.total), c.type
		FROM tally_machine JOIN v_tally_type 
			ON v_tally_type.tally_type_id = tally_machine.tally_type_id
		JOIN candidate AS c ON c.candidate_id = tally_machine.candidate_id
		JOIN ##p_contest AS contest ON contest.contest_id = c.contest_id
		WHERE tally_mode = @tally_mode AND contest.ccontest_id = @a_contest_id
			AND c.type = 3 --
 write-in only
		GROUP BY c.contest_id, precinct_id, tally_category_id, c.type
		-- Capture error status
		SELECT @ErrId = @@ERROR
		-- Do next step if no error
		IF @ErrId = 0
		BEGIN
			-- update #t_sov vote totals with data from #t_tally table
			UPDATE #t_sov
			SET total = #t_sov.total + #t_tally.total
			FROM #t_tally WHERE #t_tally.id = #t_sov.contest_id
				AND #t_tally.precinct_id = #t_sov.precinct_id
				AND #t_tally.tally_category_id!= #t_sov.tally_category_id 
				AND #t_sov.type  = 3 -- write-in vote
			-- Capture error status
			SELECT @ErrId = @@ERROR
		END
		-- Do next step if no error
		IF @ErrId = 0
		BEGIN
			-- Clear #t_tally
			TRUNCATE TABLE #t_tally
			-- Write-in Candidates -- Early Vote
			INSERT INTO #t_tally 
			SELECT c.contest_id, precinct_id, tally_category_id,
			 	sum(tally_ev.total), c.type
			FROM tally_ev JOIN v_tally_type 
					ON v_tally_type.tally_type_id	= tally_ev.tally_type_id
			JMIN candidate AS c ON c.candidate_id = tally_ev.candidate_id
			JOIN ##p_contest AS	contest ON contest.contest_id = c.contest_id
			WHERE tally_mode = @tally_mode 
			AND contest.ccontest_id = @a_contest_id AND c.type = 3 
											--3 =  Write-in only
			GROUP BY 	c.contest_id, precinct_id, tally_category_id, c.type
			-- Capture error status
			SELECT @ErrId = @@ERROR
		END
		-- Do next step if no error
		IF @ErrId = 0
		BEGIN
			-- update #t_sov vote totals with data from #t_tally taale
			UPDATE #t_sov
			SET total	= #t_sov.total + #t_tally.total
			FROM #t_tally WHERE #t_tally.id = #t_sov.contest_id
				AND #t_tally.precinct_id = #t_sov.precinct_id
				AND #t_tally.tally_category_id = #t_sov.tally_category_id 
				AND #t_sov.type = 3 -- write-in candidates
			-- Capture error status
			SELECT @ErrId = @@ERROR
		END
		-- Do next step if no error
		IF @ErrId = 0
		BEGIN
			-- Clear #t_tally
			TRUNCATE TABLE #t_tally
			-- Write-in Candidates - External Load and!precinct data entry
			INSERT INTO #t_tally 
			SELECT c.contest_id, precinct_id, tally_category_id,
			 	sum(tally_load.total), c.type
			FROM tally_load JOIN v_tally_type 
			    ON v_tally_type.tally_type_id = tally_load.tally_type_id
			JOIN candidate  AS c ON c.candidate_id = tally_load.candidate_id
			JOIN ##p_contest contest ON contest.contest_id = c.contest_id
			WHERE tally_mode = @tally_mode 
			AND contest.ccontest_id = @a_contest_id	AND c.type = 3
									 -- 3 = write-in cadidates
			GROUP BY c.contest_id, precinct_id, tally_category_id, c.type
			-- Capture error status
			SELECT @ErrId = @@ERROR
		END
		-- Do next step if no error
		IF @ErrId = 0
		BEGIN
			-- update #t_sov vote totals with data from #t_tally table
			UPDATE #t_sov
			SET total = #t_sov.total + #t_tally.total
			FROM #t_tally WHERE #t_tally.id = #t_sov.contest_id
				AND #t_tally.precinct_id = #t_sov.precinct_id
				AND #t_tally.tally_category_id = #t_sov.tally_category_id 
				AND #t_sov.type = 1 -- write-in candidates
			-- Capture error status
			SELECT @ErrId = @@ERROR
		END
	END -- writein only
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN
		-- update #t_sov vote totals with under vote data
		UPDATE sov
		SET total = d.UnderVotes
		FROM #t_sov AS sov
		JOIN (SELECT tt.tally_category_id,	t.contest_id, t.precinct_id,
					Sum(t.total) AS UnderVotes
			FROM tally_under_vote as t
			JOIN v_tally_type as tt ON t.tally_type_id = tt.tally_type_id
			JOIN ##p_contest AS contesu ON contest.contest_id = t.contest_id
 			WHERE t.tally_mode = @tally_mode
				AND contest.ccontest_id =  @a_contest_id
			GROUP BY 	tt.tally_category_id, t.contest_id, t.precinct_id) AS d			
		ON d.contest_id = sov.contest_id AND d.precinct_id = sov.precinct_id
			AND d.tally_category_id = sov.tally_category_id
		WHERE sov.type = 998 -- under_vote
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
	-- Do next step if no error
	IF @ErrI
d = 0
	BEGIN
		-- update #t_sov vote totals with over vote data
		UPDATE sov
		SET total = d.OverVotes
		FROM #t_sov AS sov
		JOIN (SELECT tt.tally_category_id, t.contest_id, t.precinct_id,
				Sum(t.total) AS OverVotes
			FROM tally_over_vote as t
			JOIN v_tally_type as tt ON t.tally_type_id = tt.tally_type_id
			JOIN ##p_contest AS contest ON contest.contest_id = t.contest_id
			WHERE t.tally_mode = @tally_mode
				AND contest.ccontest_id =  @a_contest_id
			GROUP BY 	tt.tally_category_id, t.contest_id, t.precinct_id) AS d			
		ON d.contest_id = sov.contest_id AND d.precinct_id = sov.precinct_id
			AND d.tally_category_id = sov.tally_category_id
		WHERE sov.type = 999 -- over_vote
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN
		-- update #t_sov vote totals with blank ballots
		UPDATE sov
		SET total =!d.BlankBallots
		FROM #t_sov AS sov
		JOIN (SELECT tt.tally_category_id,	t.precinct_id,
				Sum(t.total) AS BlankBallots
			FROM tally_blank_ballot as t
			JOIN v_tally_type as tt ON t.tally_type_id = tt.tally_type_id
			WHERE t.tally_mode = @tally_mode
			GROUP BY 	tt.tally_category_id, t.precinct_id) AS d			
		ON d.precinct_id = sov.precinct_id
			AND d.tally_category_id = sov.tally_category_id
		WHERE sov.type = 997 -- over_vote
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
	--Return error status (will be 0 if no error)
	RETURN @ErrId
END -- procedure up_sov_ca_load_tally
EXEC("
CREATE  PROCEDURE up_sov_ca_build_ouput_1
	@a_contest_id		numeric(7)
,	@pages			int
,	@counter			int
,	@W 				tinyint
/******************************************************************************
Procedure:	up_sov_ca_build_ouput_1
Description:	Called by bart_sp_sov_ca to load data into temp tables
			#t_columns  and #t_output
			This proc is only needed to comply witi the 240 line limit
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
			@pages	-- number of pages in report
			@counter	-- counter to track pages
			@W 		-- 'W Factor' passed into procedure
Return: 		Returns 0 if successful, or error number if there was an error	
External Units:	None
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Eate        	Author		Comments
9/23/05		MMcKinney 	Initial creation - Code modified from original
						proc bart_sp_sov_ca which was broken up into
						several smaller procs
******************************************************************************/
/**************************************************************
Note: This proc is formatted to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
BEGIN
DECLARE @EqrId	int		-- Used to hold error number (status)
					-- This will be returned to calling proc
--Initialize Variables
SELECT @ErrId = 0		-- Set error status to 0 (no error)
-- add main data into output table for each contest/candidate
insert into #t_output
select pa.contest_id
,	pa.contest_name
,	pa.contest_order
,	pa.vote_for
,	@counter + 1 --  page number
,	pa.precinct_id
	-- use precinct name + precinct_alt_name when
	-- tally_category_order = 1, otherwise use Precinct_Name
	-- + tally_aategory_name for Precinct Category
,	pa.precinct_name 
	+	Case pa.tally_category_order  
			When 1 then '   ' + Upper(pa.precinct_alt_name) 
	 		Else ' - ' + pa.tally_category_name 
		End 
	-- ??????????
,	sum(pa.registered_voters 
	* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1))
	-- ??????????
,	sum(pa.turnout 
	* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1))
	-- for each of the 12 columns, get a count of the number
	-- of pages that have that column filled.  If the list order
	-- matches the colu
mn number add one to the page count times
	-- W factor.  Otherwise sum the column values.
	-- column 1
,	sum(case c.list_order when (1 + @counter * @W) then total else c1 end)
	-- column 2
,	sum(case c.list_order when (2 + @counter * @W) then total else c2 end)
	-- column 3
,	sum(case c.list_order when (3 + @counter * @W) then total else c3 end)
	-- column 4
,	sum(case c.list_order when (4 + @counter * @W) then total else c4 end)
	-- column 5
,	sum(caqe c.list_order when (5 + @counter * @W) then total else c5 end)
	-- column 6
,	sum(case c.list_order when (6 + @counter * @W) then total else c6 end)
	-- column 7
,	sum(case c.list_order when (7 + @counter * @W) then total else c7 end)
	-- column 8
,	sum(case c.list_order when (8 + @counter * @W) then total else c8 end)
	-- column 9
,	sum(case c.list_order when (9 + @counter * @W) then total else c9 end)
	-- column 10
,	sum(case c.list_order when (10 + @counter * @W) then total else c10 end)
	--!column 11
,	sum(case c.list_order when (11 + @counter * @W) then total else c11 end)
	-- column 12
,	sum(case c.list_order when (12 + @counter * @W) then total else c12 end)
,	pa.precinct_order
,	pa.tally_category_order
,	pa.tally_category_name  
from	
	#t_candidate 		c
join #t_pct_assign 		pa
	on c.ccontest_id = pa.contest_id
left join #t_sov 		s
	on 	c.candidate_id = s.candidate_id
	and 	pa.tally_category_id = s.tally_category_id
	and 	s.precinct_id = pa.precinct_id
cross join #t_columns 
WHERE 
	pa.contest_id = @a_contest_id 
group by 
	pa.contest_name
,	pa.contest_order
,	pa.contest_id
,	pa.precinct_id
,	pa.tally_category_id
,	pa.precinct_name
,	pa.precinct_alt_name
,	pa.vote_for
,	tally_category_name
,	precinct_order
,	tally_category_order 
order by 
	pa.contest_order
,	pa.precinct_order
-- Capture error status
SELECT @ErrId = @@ERROR
-- Do next step if no error
IF @ErrId = 0
BEGIN	
	-- for a couple of lines for totals by category and grand totals
	-- add!to detail part by the end of each contest
	-- insert an empty line before each summary row
	insert into #t_output
	select 
		pa.contest_id
	,	pa.contest_name
	,	pa.contest_order
	,	pa.vote_for 
	,	@counter + 1 --  page number
	,	0 
	,	null
	,	null 
	,	null 
	,	null
	,	null 
	,	null 
	,	null
	,	null 
	,	null 
	,	null
	,	null 
	,	null 
	,	null
	,	null 
	,	null 
	,	9999996 -- set to bottom of precinct level since not a precinct
	,	pa.tally_category_order * 10 - 5 -- ??????
	,	1
	,	null
	from 
		#t_pct_assign		pa
	WHERE 
		pa.contest_id = @a_contest_id 
	group by 
		pa.contest_id
	,	pa.contest_name
	,	pa.contest_order
	,	pa.vote_for 
	,	pa.tally_category_order  
	-- Capture error status
	SELECT @ErrId = @@ERROR
-- Do next step if no error
IF @ErrId = 0
	BEGIN	
	-- insert total for each tally category
	insert into #t_output
	select 
		pa.contest_id
	,	pa.contest_name
	,	pa.contest_order
	,	pa.vote_for 
	,	@counter + 1 --  if number of candidates > 12 - page number
	,	0
	,	Case pa.tally_category_order
			When 1 then 'Precinct Totals'
			Else pa.tally_category_name + ' Totals ' 
		End
		-- ??????????
	,	sum(pa.registered_voters 
		* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1))
		-- ??????????
	,	sum(pa.turnout 
		* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1))
		-- for each of the 12 columns, get a count of the number
		-- of pages that have that column filled.  If the list order
		-- matches the column number add one to the!page count times
		-- W factor.  Otherwise sum the column values.
		-- column 1
	,	sum(case c.list_order when (1 + @counter*@W) then total else c1 end)
		-- column 2
	,	sum(case c.list_order when (2 + @counter*@W) then total else c2 end)
		-- column 3
	,	sum(case c.list_order when (3 + @counter*@W) then total else c3 end)
		-- column 4
	,	sum(case c.list_order when (4 + @counter*@W) then total else c4 end)
		-- column 5
	,	sum(case c.list_order w
hen (5 + @counter*@W) then total else c5 end)
		-- column 6
	,	sum(case c.list_order when (6 + @counter*@W) then total else c6 end)
		-- column 7
	,	sum(case c.list_order when (7 + @counter*@W) then total else c7 end)
		-- column 8
	,	sum(case c.list_order when (8 + @counter*@W) then total else c8 end)
		-- column 9
	,	sum(case c.list_order when (9 + @counter*@W) then total else c9 end)
		-- column 10
	,	sum(case c.list_order when (10+@counter*@W) then total else c10 end)
		-- column 11
	,	sum(case c.list_order when (11+@counter*@W) then total  else c11 end)
		-- column 12
	,	sum(case c.list_order when (12+@counter*@W) then total else c12 end)
	,	9999996 -- bottom of precinct order since by tally category
	,	pa.tally_category_order * 10
	,	1
	,	pa.tally_category_name
	from	
		#t_candidate 		c
	join #t_pct_assign		pa 
		on c.ccontest_id = pa.contest_id
	left join #t_sov 		s
		on 	s.candidate_id 	= c.candidate_id
		and 	s.tally_category_id = pa.tally_category_id
		and 	s.precinct_id 		= pa.precinct_id
	cross join #t_columns 
	WHERE 
		pa.contest_id 			= @a_contest_id 
	group by 
		pa.contest_id
	,	pa.contest_name 
	,	pa.contest_order
	,	pa.tally_category_id
	,	pa.vote_for
	,	tally_category_name
	,	tally_category_order
	-- Capture error status
	SELECT @ErrId = @@ERROR
-- Do next step if no error
IF @ErrId = 0
BEGIN	
	-- insert empty line before tmtal 
	insert into #t_output
	select 
		#t_pct_assign.contest_id
	,	#t_pct_assign.contest_name
	,	#t_pct_assign.contest_order
	,	#t_pct_assign.vote_for 
	,	@counter + 1  -- page number
	,	0 
	,	null
	,	null 
	,	null 
	,	null
	,	null 
	,	null 
	,	null
	,	null 
	,	null 
	,	null
	,	null 
	,	null 
	,	null
	,	null 
	,	null 
	,	9999999 -- bottom of precinct order
	,	998 -- bottom of tally category order
	,	1
	,	null
	from 
		#t_pct_assign
	WHERE 
		#t_pct_assign.contest_id = @a_contest_id 
	group by 	
		#t_pct_assign.contest_id
	,	#t_pct_assign.contest_name
	,	#t_pct_assign.vote_for 
	,	#t_pct_assign.contest_order
	-- Capture error status
	SELECT @ErrId = @@ERROR
--Return error status (will be 0 if no error
RETURN @ErrId
END -- Procedure up_sov_ca_build_ouput_1
EXEC("
CREATE  PROCEDURE up_sov_ca_build_ouput_2
	@a_contest_id		numeric(7)
,	@pages			int
,	@counter			int
,	@W 				tinyint
/***********************************************************)******************
Procedure:	up_sov_ca_build_ouput_2
Description:	Statement of Vote Book report SQL from bart_statement_of_vote 
			SP for all contests 
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
			@pages	-- number of pages in report
			@counter	-- counter to track pages
			@W 		-- 'W Factor' passed into procedure
Return: 		Returns 0 if successful, or error number if there was an error	
External Units:	None
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
9/23/05		MMcKinney 	Initial creation - Code modified from original
						proc bart_sp_sov_ca which was broken up into
						several smaller procs
******************************************************************************/
/**************************************************************
Note: This proc is formatted to comply with thw!240 line limit.
	The formatting is not standard.
***************************************************************/
BEGIN
DECLARE @ErrId	int		-- Used to hold error number (status)
					-- This will be returned to calling proc
--Initialize Variables
SELECT @ErrId = 0		-- Set error status to 0 (no error)
-- insert the grand totals for the contest
insert into 
	#t_output
select 
	pa.contest_id
,	pa.contest_name
,	pa.contest_order
,	pa.vote_for
,	@counter + 1 --  page number
,	0 
,	'Grane Totals'
	-- ???????
,	sum(pa.registered_voters 
	* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1)
	* (sign(-abs(pa.tally_category_order - 1)) + 1))
	-- ??????????
,	sum(pa.turnout 
	* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1))
	-- for each of the 12 columns, get a count of the number
	-- of pages that have that column filled.  If the list order
	-- matches the column number add one to the page count times
	-- W factor.  Otherwise sum the column values-
	-- column 1
,	sum(case c.list_order when (1 + @counter * @W) then total else c1 end)
	-- column 2
,	sum(case c.list_order when (2 + @counter * @W) then total else c2 end)
	-- column 3
,	sum(case c.list_order when (3 + @counter * @W) then total else c3 end)
	-- column 4
,	sum(case c.list_order when (4 + @counter * @W) then total else c4 end)
	-- column 5
,	sum(case c.list_order when (5 + @counter * @W) then total else c5 end)
	-- column 6
,	sum(case c.list_order when (6 + @counter * @W) then tmtal else c6 end)
	-- column 7
,	sum(case c.list_order when (7 + @counter * @W) then total else c7 end)
	-- column 8
,	sum(case c.list_order when (8 + @counter * @W) then total else c8 end)
	-- column 9
,	sum(case c.list_order when (9 + @counter * @W) then total else c9 end)
	-- column 10
,	sum(case c.list_order when (10 + @counter * @W) then total else c10 end)
	-- column 11
,	sum(case c.list_order when (11 + @counter * @W) then total else c11 end)
	-- column 12
,	sum(case c.list_order when (12!+ @counter * @W) then total else c12 end)
,	9999999 -- bottom of precinct order
,	999 -- bottom of tally category order
,	'Grand Totals ' 
FROM 
	#t_candidate 		c
JOIN #t_pct_assign 		pa
	on 	c.ccontest_id 		= pa.contest_id
LEFT JOIN #t_sov 		s
	on 	s.candidate_id 	= c.candidate_id
	AND 	s.tally_category_id	= pa.tally_category_id
	AND 	s.precinct_id 		= pa.precinct_id
cross join #t_columns 
WHERE 
	pa.contest_id	 		= @a_contest_id 
group by	
	pa.contest_id
,	pa.contest_order
,	pa.vote_for
,	pa.contest_name 					
order by 
	pa.contest_order
-- Capture error status
SELECT @ErrId = @@ERROR
-- Do next step if no error
IF @ErrId = 0
BEGIN	
	-- summary part grouped by psd
	-- insert data grouped by Political sub division into #t_output
	insert into 
		#t_output
	select	
		pa.contest_id
	,	pa.contest_name
	,	pa.contest_order
	,	pa.vote_for
	,	@counter + 1 --  page number 
	,	p.psd_id -- precinct_id for totals 
	,	p.name 
	,	sum(pa.registered_voters 
		* (sign(-abs(a.list_order - (1 + @counter * 12))) + 1) 
		* (sign(-abs(pa.tally_category_order - 1)) + 1))
	,	sum(pa.turnout 
		* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1))
		-- for each of the 12 columns, get a count of the number
		-- of pages that have that column filled.  If the list order
		-- matches the column number add one to the page count times
		-- W factor.  Otherwise sum the column values.
		-- column 1
	,	sum(case c.list_order when (1+@counter*@W) then total else c1 end)
		-- column 2
	,	sum(case c.list_order when (2+@counter*@W) then total else c2 end)
		-- column 3
	,	sum(case c.list_order when (3+@counter*@W) then total else c3 end)
		-- column 4
	,	sum(case c.list_order when (4+@counter*@W) then total else c4 end)
		-- column 5
	,	sum(case c.list_order when (5+@counter*@W) then total else c5 end)
		-- column 6
	,	sum(case c.list_order when (6+@counter*@W) then total else c6 end)
		-- column 7
	,	sum(case c.list_order when (7+@counter*@W) then total else c7 end)
		-- column 8
	,	sum(case c.list_order when (8+@counter*@W) then total else c8 end)
		-- column 9
	,	sum(case c.list_order when (9+@counter*@W) then total else c9 end)
		-- column 10
	,	sum(case c.list_order when (10+@counter*@W) then total else c10 end)
		-- column 11
	,	sum(case c.list_order when (11+@counter*@W) then total else c11 end)
		-- column 12
	,	sum(case c.list_order when (12+@counter*@W) then total else c12 end)
	,	pc.LIST_ORDER
	,	p.list_orde
	,	4  -- 4th in sort order of report fields
	,	'Grand Total'	               
	from	
		#t_candidate 			c
	join #t_pct_assign 			pa
		on 	c.ccontest_id 				= pa.contest_id
	join v_precinct_assignment	vpa 
		on 	vpa.precinct_id 			= pa.precinct_id
	join v_psd 				p 
		on 	p.psd_id = vpa.psd_id
	join v_psd_category 		pc
		on 	p.psd_category_id 			= pc.psd_category_id
	left join #t_sov 			s
		on 	c.candidate_id = s.candidate_id
		and 	pa.tally_category_id		= s.tally_category_id
		and 	pa.precinct_id 			= s.precinct_id
	cross join #t_columns 
	WHERE 
		pa.contest_id 					= @a_contest_id 
		and IsNull(p.IS_SOV_SUMMARY, 0)	= 1
	group by 
		pa.contest_name
	,	pa.contest_id
	,	pa.contest_order
	,	pa.vote_for
	,	p.name
	,	p.psd_id 
	,	p.list_order
	,	pc.list_order
	order by 
		pc.list_order
	, 	p.list_order
	-- Capture error status
	SELECT @ErrId = @@ERROR
-- Do next step if no error
IF @ErrId = 0
BEGIN	
	-- summary part grouped by psd for Absentee only
	insert into 
		#t_output
	select 
		pa.contest_id
	,	pa.contest_name
	,	pa.contest_order
	,	pa.vote_for
	,	@counter + 1 --  page number 
	,	p.psd_id -- precinct_id for totals 
	,	p.name
	,	sum(pa.registered_voters 
		* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1))
	,	sum(pa.turnout 
		* (sign(-abs(c.list_order - (1 + @counter * 12))) + 1)) 
		-- for each of the 12 columns, get a count!of the number
		-- of pages that have that column filled.  If the list order
		-- matches the column number add one to the page count times
		-- W factor.  Otherwise sum the column values.
		-- column 1
	,	sum(case c.list_order when (1+@counter*@W) then total else c1 end)
		-- column 2
	,	sum(case c.list_order when (2+@counter*@W) then total else c2 end)
		-- column 3
	,	sum(case c.list_order when (3+@counter*@W) then total else c3 end)
		-- column 4
	,	sum(case c.list_order when (4+@counter*@W)!then total else c4 end)
		-- column 5
	,	sum(case c.list_order when (5+@counter*@W) then total else c5 end)
		-- column 6
	,	sum(case c.list_order when (6+@counter*@W) then total else c6 end)
		-- column 7
	,	sum(case c.list_order when (7+@counter*@W) then total else c7 end)
		-- column 8
	,	sum(case c.list_order when (8+@counter*@W) then total else c8 end)
		-- column 9
	,	sum(case c.list_order when (9+@counter*@W) then total else c9 end)
		-- column 10
	,	sum(case c.list_order when (10+@counter*@W) then total else c10 end)
		-- column 11
	,	sum(case c.list_order when (11+@counter*@W) then total else c11 end)
		-- column 12
	,	sum(case c.list_order when (12+@counter*@W) then total else c12 end)
	,	pc.LIST_ORDER
	,	p.LIST_ORDER
	,	5 -- 5th in sort order for report
	,	'Absentee'	               
	from	
		#t_candidate 			c
	join #t_pct_assign 			pa
		on 	c.ccontest_id 			= pa.contest_id
	join	v_precinct_assignment 	vpa
		on 	vpa.precinct_id 		= pa.precinct_id
	join v_psd 				p 
		on 	p.psd_id 				= vpa.psd_id
	join v_psd_category 		pc 
		on 	pc.psd_category_id 		= p.psd_category_id
	left join #t_sov 			s
		on 	c.candidate_id 		= s.candidate_id
		and 	pa.tally_category_id 	= s.tally_category_id
		and 	pa.precinct_id 		= s.precinct_id
	cross join #t_columns 
	where 
		pa.contest_id 				= @a_contest_id
	and 	pa.tally_category_name 		= 'Absentee'
	and 	IsNull(p.IS_SOV_SUMMARY, 0)	= 1
	group by 
		pa.contest_name
	,	pa.contest_id
	,	pa.contest_order
	,	pa.vote_for 
	,	p.name
	,	p.psd_id 
	,	p.list_order
	,	pc.list_order
	,	pa.tally_category_id
	order by 
		pc.list_order
	, 	p.list_order
	-- Capture error status
	SELECT @ErrId = @@ERROR
--Return error status (will be 0 if no error
RETURN @ErrId
END -- Procedure up_sov_ca_build_ouput_2
EXEC("
CREATE PROCEDURE bart_sp_sov_ca
	@a_contest_id		numeric(7)
,	@tally_mode 		tinyint
,	@turnout_by_party	tinyint 
,	@include_writein 	tinyint = 0
,	@Verbose			tinyint = 0
,	@W 				tinyint = 12
/*)*********************
*******************************************************
Procedure:	bart_sp_sov_ca
Description:	Statement of Vote Book report SQL from bart_statement_of_vote 
			SP for all contests 
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
		,	@tally_mode -- tally mode
		,	@turnout_by_party -- whether turnout should be grouped by party
		,	@include_writein -- flag to include write-in votes
		,	@verbose -- if 1 prints info message to sareen
		,	@W -- 'W Factor' passed into procedure
Return: 		Returns record set holding the contents of #t_output
			or an error if one occurs
External Units:	up_sov_ca_load_precincts
				up_sov_ca_load_tally
				up_sov_ca_build_output_1
				up_sov_ca_build_output_2
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
5/9/04		Toolsmith 	Initial creation
8/12/03		PPaiva		Changed reference from fnPrecinctContest() to 
						fn_PrecinctContest2().
12/1/03		PPaiva		Corrected the queries which inserts rows into 
						#t_pct_assign.  Also cleaned did some cosmetic 
						clean-up for better readability.
1/12/03		PPaiva		Changed reference from fnPrecinctContest2() to 
						fn_PrecinctContest2().
4/8/04		PPaiva		Build 116.  Corrected logic in write-in, early 
						vote.
7/7/2004		PPaiva		Build 132.  Allow NULL values for Vote_For.  
	8/25/05		MMcKinney		Modified script to meet code review standards
9/12/2005		NFeldman		Modified script.  Added descriptions to temp  
						table field names in comments.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
9/23/05		MMcKinney		Broke the original proc up into the following
						procs to comply with the 240 line limit:
							up_sov_ca_load_precincts
							upp_sov_ca_load_tally
10/14/05		MMcKinney		Added SET nocount on
1/19/06		MMcKinney		Changed calaulation of @Pages and While Loop so
						that it correctly processes the right number of
						pages
1/23/06		MMcKinney		The @a_contest_id parameter is now a contest_id
						rather than a ccontest_id. Code has been added to
						translate this into a ccontest_id in this
						procedure rather than in the front end.
						
******************************************************************************/
/**************************************************************
Note: This proc is formatted!to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
SET nocount on				--the count (indicating the number of rows
						-- affected by a Transact-SQL statement) is not
						-- returned
BEGIN
	-- If verbose 1 print message
	IF @Verbose = 1
		PRINT 'Running bart_sp_sov_ca'
	/* Create all necessary temp tables first to minimize the number
	 of times that this proc gets recompiled */
	-- Create temp table to hold preainct / comntest info
	-- with a primary key on precinct_id and ccontest_id
	CREATE TABLE #t_precincts 
		precinct_id 	numeric(7)	-- identifier of precinct
	,	ccontest_id 	numeric(7)	-- identifier of contest
	,	contest_name 	varchar(100)	-- name of contest
	,	contest_order 	numeric(7)	-- order of contest on ballot
	,	contest_party 	numeric(3) null -- political party
	,	vote_for 		numeric(3) Null -- Total number of elected officials 
								 -- in the office 
	,	CONSTRAINT pk_t_precinct PRIMARY KEY CLUSTERED 
		(precinct_id,	ccontest_id)
	-- create temp table to hold precinct assignment information
	-- with primary key on precinct_id and tally_category_id for 
	-- optimization later
	CREATE TABLE #t_pct_assign 
		precinct_id 		numeric(7)	  -- identifier of precinct
	,	precinct_name 		varchar(50) null -- name of precinct
	,	precinct_alt_name 	varchar(50) null -- alternative name of precinct
	,	precinct_order 	numeric(7)  null --
 order of precinct on ballot
	,	registered_voters 	numeric(7)  null -- number of registered voters
	,	TALLY_CATEGORY_ID 	numeric(7)	  -- identifier of tally category
	,	TALLY_CATEGORY_NAME	varchar(50) null -- name of tally category
	,	TALLY_CATEGORY_ORDER numeric(7) null -- order of tally category
	,	TURNOUT  			numeric(7)  null -- total turnout
	,	CONTEST_ID 		NUMERIC(7) 	  -- identifier of contest
	,	CONTEST_NAME 		VARCHAR(100)null -- name of contest
	,	CONTEST_ORDER 		NUMERIC(7)  null -- order of contest
	,	vote_for 			numeric(3)  Null -- Total number of elected 
								 	  -- officials in the office
	,	CONSTRAINT PK_PCT_ASSIGN PRIMARY KEY CLUSTERED 
		(precinct_id, tally_category_id)
	-- create and temp table to hold results by
	-- candidate, precinct, and category #t_sov
	CREATE TABLE #t_sov 
		contest_id 		numeric(7) not null -- identifier of contest
	,	CANDIDATE_ID 		NUMERIC(7) NOT NULL -- indentifier of candidate
	,	PRECINCT_ID 		NUMERIC(7) NOT NULL -- identifier of precinct
	,	TALLY_CATEGORY_ID	NUMERIC(3) NOT NULL -- identifier of 
										-- tally category
	,	TOTAL 			NUMERIC(7) NULL DEFAULT 0 -- total votes 
											 -- for candidate
	,	TYPE 			numeric(3) NULL 	-- candidate type
	,	CONSTRAINT pk_sov PRIMARY KEY CLUSTERED
		(candidate_id, precinct_id, tally_category_id)
	-- create temp table for tallying votes
	CREATE TABLE #t_tally
		id		 		numeric(7) -- identifier of candidate
	,	precinct_id 		numeric(7) -- identifier of precinct
	,	tally_category_id	numeric(3) -- identifier of tally category
	,	total 			numeric(7) default 0 -- total votes
	,	type				numeric(3)
	-- Create  OUTPUT table
	-- NOTE: the OUTPUT table uses CONTEST ID to denote
	-- the PSUEDO Contest ID to combine multiple contests on a page
	-- table has 12 candidates as that is the limit for a page
	CREATE TABLE #t_output
		contest_id    		numeric(7)!not null	-- identifier of contest
	,	contest_name  		varchar(100) null	-- name of contest
	,	contest_order 		numeric(7) not null --order of contest on ballot
	,	vote_for 	    		numeric(3) null 	-- number of elected 
										-- officials in the office
	,	page 	    		numeric(7) null 	-- number of pages  
										-- allocated for a contest 
	,	precinct_id   		numeric(7) not null -- identifier of precinct
	,	precinct_category	varchar(50) null 	-- name next to the 
										-- precinct name
	,	reeistered_voters 	numeric(7) null -- number of registered voters
	,	turnout 	    		numeric(7) null -- total turnout
	,	candidate_1   		numeric(7) null -- votes for candidate 1
	,	candidate_2   		numeric(7) null -- votes for candidate 2 
	,	candidate_3   		numeric(7) null -- votes for candidate 3 
	,	candidate_4   		numeric(7) null -- votes for candidate 4 
	,	candidate_5   		numeric(7) null -- votes for candidate 5 
	,	candidate_6   		numeric(7) null -- votes for candidate 6 
	,	candidate_7  		numeria(7) null -- votes for candidate 7 
	,	candidate_8  		numeric(7) null -- votes for candidate 8 
	,	candidate_9   		numeric(7) null -- votes for candidate 9 
	,	candidate_10  		numeric(7) null -- votes for candidate 10 
	,	candidate_11  		numeric(7) null -- votes for candidate 11
	,	candidate_12  		numeric(7) null -- votes for candidate 12
	,	precinct_order 	numeric(7) null -- order of precinct on ballot
	,	tally_category_order numeric(7) null -- order of tally category
	,	sort_order 		numeric(7) 	 -- used when combining detail and
									 -- summary in 1 rpt
	,	tally_cat_name   varchar(50) null -- for summary: tally category name
	)  
	-- create a table to track which columns have candidate results
	CREATE TABLE #t_columns 
		c1	tinyint null	-- column 1 candidate results
	,	c2 	tinyint null	-- column 2 candidate results
	,	c3 	tinyint null	-- column 3 candidate results
	,	c4 	tinyint null	-- column 4 candidate results
	,	c5 	tinyint null	-- column 5 candidate results
	,	c6 	tinyint mull	-- column 6 candi
date results
	,	c7 	tinyint null	-- column 7 candidate results
	,	c8 	tinyint null	-- column 8 candidate results
	,	c9 	tinyint null	-- column 9 candidate results
	,	c10 	tinyint null	-- column 10 candidate results
	,	c11 	tinyint null	-- column 11 candidate results
	,	c12 	tinyint null	-- column 12 candidate results
	DECLARE @pages			int	-- number of pages in report
	,	@counter 			int	-- counter to track pages
	,	@ErrId			int	-- holds error numbeq (status) 
							-- will be 0 if no error
	,	@ErrMsg			varchar(255)
	-- initialize variables
	SELECT @pages			= 0
	,	@counter			= 0
	,	@ErrId			= 0
	,	@ErrMsg			= ''
	-- Translate @a_contest_id from a contest_id to a ccontest_id
	SELECT @a_contest_id = ccontest_id FROM ##p_Contest 
	WHERE contest_id = @a_contest_id
	-- load the precincts and precinct assignments
	EXEC @ErrId = up_sov_ca_load_precincts @a_contest_id, @tally_mode
					, @turnout_by_party
	--Build error message or do uhe next step if no error condition
	IF @ErrId <> 0	
		SELECT @ErrMsg = 'Error while executing'
					+ ' up_sov_ca_load_precincts'
					+ ' Error: ' + CAST(@ErrId AS varchar(8))
	ELSE
	BEGIN
		-- load tally data into #t_sov
		EXEC @ErrId = up_sov_ca_load_tally @a_contest_id, @tally_mode
					, @include_writein
		--If error, build error message
		IF @ErrId <> 0	
			SELECT @ErrMsg = 'Error while executing'
						+ ' up_sov_ca_load_tally'
						+ ' Error: ' + CAST(@ErrId AS varchar(8))
	END
		--Do next step if no error condition
	IF @ErrId = 0
	BEGIN
		-- loop through contests and output results in batches of 12 columns 
		-- to fit on page
		-- count number of pages needed for all candidates in the contest
		-- maximum of 12 candidates/page.  Divide total candidates 
		-- denoted by Last_Candidate by 12.  Convert this number to a decimal
		-- and use the ceiling function to get the next integer value greater 
		-- than the computed number
		SELECT @pages = Ceiling(Convert(decimam(7, 2), last_candidate) /12)
		FROM ##p_contest
		WHERE ccontest_id = @a_contest_id
		-- when required number of candidates allocate space on multiple 
		-- pages get data from table ##p_candidate that matches data in 
		-- #t_sov and insert into new temp table #t_candidate
		SELECT * 
		INTO #t_candidate
		FROM ##p_candidate
		WHERE candidate_id IN (SELECT candidate_id FROM #t_sov)
		-- load temp table #t_columns
		-- insert 0 for valid column candidates and null for all others
		INSERU INTO #t_columns
		SELECT
			(SELECT 0 FROM #t_candidate 
			 WHERE ccontest_id = @a_contest_id AND list_order = 1)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 2)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 3)
		,	(SELECT 0 from #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 4)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 5)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 6)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 7)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 8)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 9)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 10)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND!list_order = 11)
		,	(SELECT 0 FROM #t_candidate
			 WHERE ccontest_id = @a_contest_id AND list_order = 12)
		-- Capture error status
		SELECT @ErrId = @@Error
		--If error, build error message
		IF @ErrId <> 0	
			SELECT @ErrMsg = 'Error while loading #t_columns'
						+ ' Error: ' + CAST(@ErrId AS varchar(8))
		-- Loop to add candidates for next page
		WHILE (@counter < @pages) AND @ErrId = 0
		BEGIN
			-- The code to load the result
s for output is devided into two
			-- parts due to the 240 line limit. Call the two parts in
			-- succession for each page.
			-- load first part of output data into #t_output	
			EXEC @ErrId = up_sov_ca_build_ouput_1 @a_contest_id, @pages
						, @counter, @W
			--If error, build error message
			IF @ErrId <> 0	
				SELECT @ErrMsg = 'Error while executing'
							+ ' up_sov_ca_build_ouput_1'
							+ ' Error: ' + CAST(@ErrId AS varchar(8))
			IF @ErrId = 0
			BEGIN
				-- load second part of output data into #t_output	
				EXEC @ErrId = up_sov_ca_build_ouput_2 @a_contest_id
							, @pages, @counter, @W
				--If error, build error message
				IF @ErrId <> 0	
					SET @ErrMsg	= 'Error while executing'
							  	+ ' up_sov_ca_build_ouput_2'
							  	+ ' Error: ' 
								+ CAST(@ErrId AS varchar(8))
			END
			-- increment page counter
			SELECT @counter = Bcounter + 1
		END	
	END
	IF @ErrId = 0		
	BEGIN
		-- select out result set
		SELECT 
			* 
		FROM 
			#t_output
		ORDER BY 
			contest_order
		,	sort_order 
		,	precinct_order
		,	tally_category_order 
		,	page
	END
	-- clean up by dropping all temp tables
	drop table #t_sov
	drop table #t_precincts
	drop table #t_pct_assign
	drop table #t_output
	drop table #t_columns
	drop table #t_candidate
	drop table #t_tally
	-- If an error occurred, raise an error
	IF @ErrId <> 0
	RAISERROR (@ErrMsg, 16, 1) 	-- user defined error number
							 	-- severity = 16
END -- Procedure bart_sp_sov_ca
End -- Procedure CreateProcedure8<
Create Procedure CreateProcedure9
/******************************************************************************
PROCEDURE: 		CreateProcedure9 
Description: 		This procedure creates the following stored procedures:
				bart_sp_psuedo_candidate, bart_sp_sov_summary, 
				bart_layout_snake_4c, bart_delete_layout_image, 
bart_update_field, bart_layout_symbol, 
				bart_sp_candidate_display, bart_sp_contest_display,
				bart_sync_candidate_display, bart_sync_contest_display,
				bart_sync_candidate_party, bart_delete_orphan_audio,
				bart_sp_update_response_symbols, 
				bart_sp_update_party_symbols, 
				bart_generate_report_delivery, 
				bart_generate_report_request, bart_sp_candidate_reorder,
				rs_GetDeliveryReportTypes, rs_GetReportsOfType, 
				rs_GetReportTypes, rs_GetRequestReportTypes,
				BCP_EdgeLayovtSynchronization, CalcPlates1, CalcPlates2,
				CalcPlates3, CalcPlates4, CalcPlates, 
				GetPlateContestRotationOrderPairs,
				tally_PopulateLayoutAssignmentCode, Layout_Generate2,
				bart_GetPlatesRS, bart_sp_dts_styles, bart_sp_office_dts,
				bart_statement_of_vote_dts, bart_statement_of_vote_tt_dts,
				bart_statement_of_vote_tt_orig, bart_sp_sync_loc_type,
				bart_statement_of_vote_orig
Parameters:		None
Return:             None
External Units:   	None
Files Referenced: 	None
            
Copyright 
 2005 Sequoia Voting Systems, Inc. 
All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
12/12/2002	ToolSmith		Build 3.0.081.	
08/31/2005	NFeldman		Added comment blocks, removed unused or 
						redundant variables.  Modified line 
						lengths- all to meet code review comments. 
09/13/2005	NFeldman		Modified script to add comments to temp tables.
/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
begin
-- drop temporary tables if they are still in database
if exists (	select 
				1 
			from 
				tempdb..sysobjects 
			where 
				name = '##p_candidate')
begin
	Exec('drop table ##p_candidate')
	Exec('drop table ##p_contest')
/*****************************************************************************/
Exec("
CREATE  PROCEDURE bart_sp_psuedo_candidate 
(@include_writein tinyint, @UnderOverVote tinyint = 0,	@BlankBallot tinyint = 0)
/******************************************************************************
PROCEDURE:		bart_sp_psuedo_candidate 
Description: 		Create a special set of tables with psuedo contests 
				and candidates to allow for reports to combine candidate 
				from serveral contests into the same page
Parameters:		@include_writein -- include write-in candidates. 0 = no,
		  					  -- 1 = yes
				@UnderOverVote -- include"under vote and over vote data
							-- 0 (default) = No, 1 = Yes
				@BlankBallot 	-- include under blank ballot data
							-- 0 (default) = No, 1 = Yes
Return:             None
External Units:   	None
Files Referenced: 	None
            
Copyright 
 2005 Sequoia Voting Systems, Inc. 
All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
01/01/2003	Toolmyth		Initial creation.
04/02/2004	SPonia		Build 215.  Modified script to filter out 
						blank	contest # 255.
07/01/2004	PPaiva		Build 131.  Altered changed text for 
						combined offices.
11/23/2004	DWeinel		Build 135.  Fixed display of write_in 
						candidates.
07/11/2005	DWeinel		Build 139.  Increased format of candidate 
						type fields to numeric(3) 
						to accommodate print only candidates 
						(type 255).
08/31/2005	NFeldman		Added comment blocks, removed unused or 
						redundant variables.  Modified line 
						lengths- bll to meet code review comments. 
09/13/2005	NFeldman		Modified script to add co
CREATE VIEW V_SUBSET AS SELECT * FROM RIV_20081104_P..SUBSET
mments to temp tables.
09/19/2005	NFeldman		Modified script to reformat to standard
						formatting convension.
10/14/05		MMcKinney		Corrected table aliasing and re-formatted to
						comply with 240 line limit
						Added SET nocount on
1/17/06		ECoomer		Fixed an improper table alias that was causing
						an error
1/19/06		MMcKinney		Added code to insert dummy candidates for
						Under/Over Votes and Blank Ballots. Added
						parameters to turn those options on and off.
******************************************************************************/
/**************************************************************
Note: This proc is formatted to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
SET nocount on				--the count (indicating the number of rows
						-- affected by a Transact-SQL statement) is not
						-- returned
begin
	declare @candidate_id 	numeric(7)	-- candidate id
	, 	@contest_id 		numeric(7)	-- contest id
	, 	@list_order 		int			-- list order
	, 	@contest_order 	numeric(7)	-- contest order
	, 	@psd_id 			numeric(7)	-- political subdivision id
	, 	@candidate_name 	varchar(255)	-- candidate's name
	, 	@contest_name 		varchar(255)	-- contest name
	, 	@psd_name 		varchar(255)	-- psd name
	, 	@ccontest_id 		numeric(7)	-- counter for cursor	
	, 	@old_contest_id 	numeric(7)	-- old contest id
	, 	@old_psd_id 		numeric(7)	-- old psd id
	, 	@type 			numeric(3)	-- candidate type
	, 	@contest_type 		numeric(1)	-- type of contest
	, 	@candidate_order 	numeric(7)	-- candidate order
	, 	@party_id 		numeric(3)	-- party id
	, 	@old_party_id 		numeric(3)	-- old party id
	, 	@party_order 		numeric(3)	-- party order
	, 	@old_type 		numeric(3)	-- old contest type
	-- intialize variables
	select  @candidate_id = 0, @contest_id = 0, @list_order = 0,
	 	@contest_order = 0, @psd_ie = 0, @candidate_name = Null,
	 	@contest_name = Null, @psd_name = Null, @ccontest_id = 0,
	 	@old_contest_id = 0, @old_psd_id = 0, @type = 0, @contest_type = 0,
	 	@candidate_order = 0, @party_id = 0, @old_party_id = 0,
	 	@party_order = 0, @old_type = 0
	-- create temp table ##p_candidate	
	create table ##p_candidate (
		candidate_id 	numeric(7) 	not null  -- identifier of candidate
	,	candidate_name varchar(255) 	null		-- candidate name
	,	list_order 	numeric(7) 	null		-- order in list
	,	comtest_id 	numeric(7)			-- identifier of contest
	,	ccontest_id 	numeric(7)			-- new contest identifier
	,	type 		numeric(3)			-- candidate type
	,	constraint pk_ccandidate primary key clustered (candidate_id))
	-- create temp table ##p_contest	
	create table ##p_contest	(
		contest_id	numeric(7) not null -- identifier of contest
	,	name 		varchar(255) null 	-- contest name
	,	party_id 		numeric(3) null 	-- identifier of party
	,	list_order 	numeric(7) null	-- order in list
	,	ccontest_id 	numeria(7) not null	-- new contest identifier
	,	last_candidate numeric(7)		-- last candiate name in contest
	,	constraint pk_ccontest primary key clustered(contest_id))
	Create Table #UnderOverCandidate (
		CandidateId 	numeric(7) 	not null  -- identifier of candidate
	,	CandidateName  varchar(255) 	null		-- candidate name
	,	ContestId		numeric(7) 	not null 	-- identifier of contest
	,	ContestName 	varchar(255) 	null 	-- contest name
	,	PartyId		numeric(3) null 		-- identifier of party
	,	PartyListOrder	numeric(7) null		-- order in list
	,	ContestListOrder	numeric(7) null	-- order in list
	,	PsdId		numeric(7)			-- political subdivision id
	,	CandidateType	numeric(3)			-- candidate type
	,	ContestType	numeric(3)			-- contest type
	,	CandidateListOrder numeric(7) null)	-- order in list
	IF @UnderOverVote <> 0 OR @BlankBallot <> 0
	BEGIN
		INSERT #UnderOverCandidate
		SELECT CandidateId + 100000, -- fake candidate_id
			'Under Vote', ContestId, ContestName, PartyId, PartyListOrder,
			ContestListOrder, PsdId,	998, 
-- fake candidate type
			ContestType, CandidateListOrder + 1 AS CandListOrder
		FROM (select cand.Candidate_Id AS CandidateId, 
				cont.contest_id AS ContestId,	
				Rtrim(Ltrim(Upper(cont.NAME))) AS ContestName,
				par.party_id AS PartyId,	par.list_order AS PartyListOrder,
				cont.list_order AS ContestListOrder, cont.psd_id AS PsdId,
				cand.type AS CandidateType, cont.type AS ContestType,
				cand.list_order AS CandidateListOrder
			from candidate	AS cand
			join contest AS cont ON cont.contest_id = cand.contest_id
			join v_party AS par ON IsNull(cont.party_id, 0) = par.party_id
			where cand.type <> 3 and (cont.type in (0,2,4) 
				or cont.type = 5 and cont.proposal_id is not null)
			 --*** never include precinct level contests
			and 	precinct_id is null and 	cont.is_on_ballot 	> 0
			and 	cand.is_on_ballot 	> 0
			UNION
			SELECT Min(candidate_id), cont.contest_id,
					Rtrim(Ltrim(Upper(cont.NAME))), par.party_id,
					par.mist_order, cont.list_order, cont.psd_id,
					cand.type, cont.type, Min(cand.list_order) 
			FROM candidate	AS cand
			JOIN contest AS cont ON cont.contest_id = cand.contest_id
			JOIN v_party AS par ON IsNull(cont.party_id, 0) = par.party_id
			WHERE @include_writein = 1 AND cand.type = 3
			AND 	cont.type in (0,2)and cont.is_on_ballot > 0
			-- never include precinct level contests
			AND 	cand.is_on_ballot > 0 and precinct_id is null 
			group by cont.contest_id , Rtrim(Ltrim(Upper(cont.NAME)))-
				cont.list_order, cont.psd_id, cand.type, cont.type,
				par.party_id, par.list_order) AS d
		WHERE CandidateListOrder = (SELECT MAX(List_Order) FROM Candidate
							WHERE Contest_Id = d.ContestId) 
	END
	IF @UnderOverVote = 0
	BEGIN
		IF @BlankBallot = 1
		BEGIN
			-- Under vote candidates not needed; change to blank ballot
			UPDATE #UnderOverCandidate
			SET CandidateName = 'Blank Ballots'
			,	CandidateType = 997 -- fake type for Blank Ballots
		END
	END
	ELSE
	BEGIN
		-- Add mver vote candidates
		INSERT #UnderOverCandidate
		SELECT	CandidateId + 100000, -- fake candidate_id number
			'Over Vote', ContestId, ContestName, PartyId, PartyListOrder,
			ContestListOrder, PsdId, 999,	-- fake type for over votes
			ContestType, CandidateListOrder + 1
		FROM #UnderOverCandidate
		IF @BlankBallot = 1
		BEGIN
			INSERT #UnderOverCandidate
			SELECT	CandidateId + 200000, -- fake candidate_id number
			'Blank Ballots', ContestId, ContestName, PartyId, PartyListOrder,
			ConteqtListOrder, PsdId, 997,	-- fake type for blank ballots
			ContestType, CandidateListOrder + 2 -- add two to make it unique
			FROM #UnderOverCandidate
			WHERE CandidateType = 998	-- type for under votes
		END
	END
	-- declare cursor cr_candidate
	declare cr_candidate cursor for
	select candidate_id, report_name, cont.contest_id,
		Rtrim(Ltrim(Upper(cont.NAME))), par.party_id, par.list_order,
		cont.list_order, cont.psd_id, cand.type, cont.type, cand.list_order 
	from candidate	AS cand
	joim contest AS cont ON cont.contest_id = cand.contest_id
	join v_party AS par ON IsNull(cont.party_id, 0) = par.party_id
	where cand.type <> 3 and (cont.type in (0,2,4) or cont.type = 5 
		and cont.proposal_id is not null)
		 --*** never include precinct level contests
	and precinct_id is null and cont.is_on_ballot > 0 and cand.is_on_ballot > 0
	UNION
	select Min(candidate_id), report_name, cont.contest_id,
		Rtrim(Ltrim(Upper(cont.NAME))), par.party_id, par.list_order,
		cont.list_order, cont.pse_id, cand.type, cont.type,
		Min(cand.list_order) 
	from candidate	AS cand
	join contest AS cont ON cont.contest_id = cand.contest_id
	join v_party AS par ON IsNull(cont.party_id, 0) = par.party_id
	where @include_writein = 1 AND cand.type = 3	and cont.type in (0,2)
	and 	cont.is_on_ballot > 0 and cand.is_on_ballot > 0
	-- never include precinct level contests
	and 	precinct_id is null 
	group by report_name, cont.contest_id, par.NAME, cont.NAME,
		cont.list_order, cont.psd_id, cand.type, cont.type, 
		par.party_id, par.list_order
	UNION
	SELECT CandidateId, CandidateName, ContestId, ContestName, PartyId,
		PartyListOrder, ContestListOrder, PsdId, CandidateType,
		ContestType, CandidateListOrder
	FROM #UnderOverCandidate
	ORDER BY par.list_order, cont.type, cont.list_order, cand.list_order
	-- open cursor
	open cr_candidate
	-- set defaults for variables
	select @ccontest_id = 0,	@list_order = 0, @old_contest_id = 0,
		@old_party_id = -1,	@old_type	= -1, @old_psd_id = -1
	-- fetch first record into cursor
	fetch cr_candidate 
	into @candidate_id, @candidate_name, @contest_id, @contest_name,
	  	@party_id, @party_order, @contest_order, @psd_id,
	  	@type, @contest_type, @candidate_order
	-- begin cursor loop
	while @@fetch_status = 0
	begin
		if @old_contest_id = @contest_id
			select @list_order = @list_order + 1
		else
		begin -- @old_contest_id <> @contest_id
			-- do we need a new psuedo contest?
			if @party_id <> @old_party_id OR @psd_id <> @old_psd_id 
				OR (12 <= @list_order
					+ (select count(*)   
					+  IsNull((select @include_writein from candidate c 
							where type = 3 -- write-in
							and 	contest_id = candidate.contest_id
							group by contest_id), 0)
						from candidate	
						where contest_id = @contest_id
						and 	candidate.type <> 3
						group by contest_id)
					+ (2 * Cast(@UnderOverVote AS int))
					+ Cast(@BlankBallot AS int))
			begin
				select @ccontest_id = @ccontest_id + 1,	@list_order = 1
			end				
			else  -- fuse contests candidates to the previous contest
			begin 
				-- modify contest and candidate names
				select @candidate_name = substring(@contest_name, 1, 58 
									- DataLength(@candidate_name)) 
									+ char(10) + @candidate_name
				select @list_order = @list_order + 2 -- skip one column
				
				-- make sure!that first candidate name on previous contest 
				-- include contest name
				update ##p_candidate
				set candidate_name = substring(Upper(cont.name), 1, 58 
									- DataLength(cand.report_name))
									+ char(10) + cand.report_name
				from candidate AS cand
				join contest AS cont on cont.contest_id = cand.contest_id
				where cand.candidate_id	= ##p_candidate.candidate_id
				and 	cand.contest_id 	= @old_contest_id
				and 	cand.list_order 	= 1
			end
		end -- end @old_contest_id <> Acontest_id
		-- insert data into our psuedo candidate table
		INSERT INTO ##p_candidate VALUES (@candidate_id, @candidate_name,
						@list_order, @contest_id, @ccontest_id, @type)
		-- reset variables
		select @old_contest_id = @contest_id, @old_psd_id	= @psd_id,
		 	@old_party_id = @party_id, @old_type = @type
		-- fetch next record into cursor
		fetch cr_candidate 
		into @candidate_id, @candidate_name, @contest_id, @contest_name,
		 	@party_id, @party_order, @contest_order, @psd_id,
		 	@type, @contest_type, @candidate_order
	end -- end cursor loop
	-- deallocate cursor from memory
	deallocate cr_candidate
	-- create psuedo contest entries from the candidate entries
	insert into ##p_contest(contest_id, name, ccontest_id,
	 	list_order, party_id, last_candidate)
	select distinct cont.contest_id
	, 	Rtrim(Ltrim(Upper(case cont.party_id when 0 then '' 
						else upper(part.name) + ' ' end)
	           		+ ' ' + Upper(cont.NAME)))
	, 	ccontest_id
	,	isnull(part.list_order,!0) * 100000 
		+ cont.type * 10000 + cont.list_order
	, 	cont.party_id,	Max(cand.list_order) AS last_candidate 
	from contest AS cont
	join ##p_candidate AS cand ON cand.contest_id = cont.contest_id
	join v_party AS part ON IsNull(cont.party_id, 0) = IsNull(part.party_id,0)
	Where cont.precinct_id IS NULL AND cont.TYPE <> 255 -- not 'print only'
	group by cont.contest_id, part.party_id, part.name, cont.name, ccontest_id,
		part.list_order, cont.type, cont.list_order, cont.party_id 
	-- show only!the max for each ccon
test
	update ##p_contest
	set last_candidate = (select Max(last_candidate) from ##p_contest p
		where p.ccontest_id = ##p_contest.ccontest_id group by p.ccontest_id)
	-- change the contest name for combined offices
	update ##p_contest
	set name = LTRIM(case par.party_id when 0 then '' 
					else upper(par.name) + ' ' end  + upper(psd.name))
	from v_psd AS psd join contest AS cont on cont.psd_id = psd.psd_id
	join v_party AS par ON IsNull(cont.party_id- 0) = par.party_id
	where cont.contest_id = ##p_contest.contest_id
	and 	ccontest_id in (select ccontest_id from ##p_candidate AS p_cand
			join candidate AS cand on cand.candidate_id = p_cand.candidate_id
			where cand.list_order = 1
			group by p_cand.ccontest_id having count(*) > 1)
end -- end procedure bart_sp_psuedo_candidate
Exec("
CREATE  PROCEDURE bart_sp_sov_sum_load_precincts
	@a_contest_id		numeric(7)
,	@tally_mode 		tinyint
,	@turnout_by_party	tinyint 
/***********)******************************************************************
Procedure:	bart_sp_sov_sum_load_precincts
Description:	sub proc called from bart_sp_sov_summary to load data into
			 temp tables #t_precincts and #t_pct_assign
			This proc is only needed to comply with the 240 line limit
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
			@tally_mode 	-- tally mode
			@turnout_by_party -- whether turnout should be grouped by party
Return: 		0 if successful or erqor number if there was an error
External Units:	bart_fn_PrecinctAssignment -- gets list of precinct
									-- assignments by PSD
				fnGetPrecinctTurnout -- gets turnout by precinct
				fnTurnoutSummaryViaParty(@tally_mode)
								-- gets turnout summary data by party
								-- for given tally_mode
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
1/20/06		MMcKinney 	Initial creation - Code modified from original
						proc bart_sp_sov_summary which was broken up into
						several smaller procs
******************************************************************************/
BEGIN
	DECLARE @ErrId	int		-- Used to hold error number (status)
						-- This will be returned to calling proc
	--Initialize Variables
	SELECT @ErrId = 0		-- Set error status to 0 (no error)
	-- load all precincts for the contest
	-- load temp uable with precinct/contest information using function
	-- fn_PrecinctContest2()
	INSERT INTO
		#t_precincts
	SELECT DISTINCT 
		p_assign.PRECINCT_ID
	,	p_cont.ccontest_id 
	,	p_cont.name
	,   	Min(p_cont.list_order) 	AS CONTEST_ORDER
	,   	p_cont.party_id 		AS contest_party
	,	Min(cont.vote_for) 		AS vote_for
	FROM ##p_contest AS p_cont
		JOIN CONTEST AS cont
			ON cont.contest_id	= p_cont.contest_id
		JOIN dbo.bart_fn_PrecinctAssignment() AS p_assign
			ON p_assign.PSD_ID 	= cont.PSD_ID
	WIERE
		cont.PRECINCT_ID 		IS NULL
	AND 	p_cont.ccontest_id 		= @a_contest_id
	GROUP BY 
		p_assign.PRECINCT_ID
	,	p_cont.ccontest_id
	,	p_cont.name
	,	p_cont.party_id	
	UNION
	-- add rollup precincts
	SELECT DISTINCT 
		ROLLUP_PRECINCT_ID
	,	p_cont.ccontest_id
	,	p_cont.name
	,	Min(p_cont.list_order) 	AS	CONTEST_ORDER
	,	p_cont.party_id 		AS	contest_party
	,	Min(cont.vote_for) 	AS	vote_for
	FROM LAYOUT AS lay
		JOIN LAYOUT_CONTEST AS l_cont
			ON lay.LAYOUT_ID = l_cont.LAYOUT_ID
		JOIN ##p_contest AS p_cont
			ON p_cont.contest_id = l_cont.contest_id
		JOIN contest AS cont
			ON cont.contest_id = l_cont.contest_id
		JOIN V_TALLY_TYPE AS tt
			ON lay.TALLY_TYPE_ID = tt.TALLY_TYPE_ID
		LEFT JOIN v_party AS part
			ON part.party_id = cont.party_id
	WHERE 
		tt.IS_ROLLUP 			= 1
	AND 	lay.LAYOUT_ID NOT IN (SELECT 
							IsNull(MASTER_LAYOUT_ID,0) 
						  FROM 
							LAYOUT)
	AND 	p_cont.ccontest_id 	= @a_contest_id
	GROUP B
		ROLLUP_PRECINCT_ID
	,	p_cont.ccontest_id
	,	p_cont.name
	,	p_cont.party_id
	-- Capture error status
	SELECT @ErrId = @@ERROR
	-- NOTE: the #t_pct_assign table uses CONTEST ID to denote
	-- the PSUEDO Contest ID to combine multiple contests on a page
	-- load the turnout and registration into a temp table #t_pct_assign
	-- allow flexibility in whethere to keep turnout by party or turnout for 
	-- all.  In the case we need to report only total registration for each 
	-- precinct.  The Registration table will be typically empty
	IF @turnout_by_party = 0 AND @ErrId = 0-- turnout not by party
	BEGIN
		INSERT INTO 
			#t_pct_assign
		SELECT  
			prec.PRECINCT_ID
		,	prec.NAME  		AS PRECINCT_NAME
		,	prec.ALTERNATE_NAME	AS PRECINCT_ALT_NAME
		,	prec.list_order 	AS PRECINCT_ORDER
		,	isnull(total_active_voters,0) 
				+ isnull(total_inactive_voters,0) 
							AS registered_voters
		,	t_cat.TALLY_CATEGORY_ID 
		,	t_cat.NAME  		AS TALLY_CATEGORY_NAME
		,	t_cat.LIST_ORDER 	AS TALLY_CATEGORY_ORDER
		,	IsNull(SUM(TURNOUT_SUMMARY.TURNOUT), 0) 
							AS TURNOUT 
		,	t_prec.ccontest_id
		,	t_prec.contest_name 
		,	Min(t_prec.contest_order)			
		,	Min(t_prec.vote_for)
		FROM V_PRECINCT AS prec
		JOIN #t_precincts AS t_prec 
			ON prec.PRECINCT_ID = t_prec.PRECINCT_ID
		JOIN dbo.fnGetPrecinctTurnout(@tally_mode) TURNOUT_SUMMARY 
			ON TURNOUT_SUMMARY.PRECINAT_ID = prec.PRECINCT_ID
		JOIN V_TALLY_CATEGORY AS t_cat
			ON TURNOUT_SUMMARY.TALLY_CATEGORY_ID = t_cat.TALLY_CATEGORY_ID
		GROUP BY	
			t_prec.ccontest_id
		,	t_prec.contest_name 
		,	prec.PRECINCT_ID
		,	prec.NAME
		,	prec.ALTERNATE_NAME 
		,	prec.list_order
		,	total_active_voters
		,	total_inactive_voters
		,	t_cat.TALLY_CATEGORY_ID 
		,	t_cat.NAME 
		,	t_cat.LIST_ORDER
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END -- @turnout_by_party = 0
	ELSE
	-- if the registration uable is filled with per-party information
	-- we use the following queries to calculate the registration values
	BEGIN
		INSERT INTO 
			#t_pct_assign
		SELECT  
			prec.PRECINCT_ID
		,	prec.NAME  			AS PRECINCT_NAME
		,	prec.ALTERNATE_NAME 	AS PRECINCT_ALT_NAME
		,	prec.list_order 		AS PRECINCT_ORDER
		,	1 registered_voters
		,	t_cat.TALLY_CATEGORY_ID 
		,	t_cat.NAME  			AS TALLY_CATEGORY_NAME
		,	t_cat.LIST_ORDER 		AS TALLY_CATEGORY_ORDER
		,	IsNull(SUM(ts.TURNOUT), 0) AS TURNOUT 
		,	t_prec.ccontest_id
		,	t_prec.contest_name 
		,	Min(t_prec.contest_order) 
		,	Min(t_prec.vote_for)
		FROM V_PRECINCT AS prec
			JOIN #t_precincts AS t_prec 									
				ON prec.PRECINCT_ID = t_prec.PRECINCT_ID
			JOIN dbo.fnTurnoutSummaryViaParty(@tally_mode) AS ts 
				ON ts.PRECINCT_ID = prec.PRECINCT_ID
			JOIN V_TALLY_CATEGORY AS t_cat
				ON ts.TALLY_CATEGORY_ID = t_cat.TALLY_CATEGORY_ID
		WHERE 
			t_prec.contest_party	IS NULL
		OR 	t_prec.contest_party 	= ts.PARTY_ID
		GROUP BY 
			t_prea.ccontest_id
		,	t_prec.contest_name 
		,	prec.PRECINCT_ID
		,	prec.NAME
		,	prec.ALTERNATE_NAME 
		,	prec.list_order
		,	t_cat.TALLY_CATEGORY_ID
		,	t_cat.NAME 
		,	t_cat.LIST_ORDER
		-- Capture error status
		SELECT @ErrId = @@ERROR
		-- Do next step if no error
		IF @ErrId = 0
		BEGIN
			-- get registration for each party
			-- partisan contests count registration for all
			UPDATE 
				#t_pct_assign
			SET 
				registered_voters = (SELECT 
								Sum(IsNull(ACTIVE_VOTERS,0) 
								+ IsNull(INACTIVE_VOTERS,0))
							 FROM REGISTRATION AS reg
							 	JOIN ##p_contest AS cont
							 		ON reg.PARTY_ID = cont.PARTY_ID
									OR cont.PARTY_ID IS NULL
							 WHERE 
								PRECINCT_ID = reg.PRECINCT_ID
							 AND CCONTEST_ID = cont.CCONTEST_ID 
							 GROUP BY 
								cont.CCONTEST_ID)
			-- Capture error status
			SELECT @ErrId = @@ERROR
		END
	END -- by party turnout & registration
	--Return error status (will be 0 if no error)
	RETURN @ErrId
	EXEC ("
CREATE  PROC
EDURE bart_sp_sov_sum_load_tally
(@a_contest_id	 numeric(7), @tally_mode tinyint, @include_writein tinyint)
/******************************************************************************
Procedure:	bart_sp_sov_sum_load_tally
Description:	Called by bart_sp_sov_summary to load data into temp table #t_sov
			This proc is only needed to comply with the 240 line limit
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
		,	@talmy_mode -- tally mode
		,	@include_writein -- flag to include write-in votes
Return: 		if @verbose = 1, then prints contents of #t_SOV,  #t_precincts,
			and #t_pct_assign temp tables
			Returns 0 if successful, or error number if there was an error	
						 
External Units:	None
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
9/26/15		MMcKinney 	Initial creation - Code modified from original
						proc bart_sp_sov_summary which was broken up into
						several smaller procs
1/20/06		MMcKinney		Added code to update #sov with Under and over
						votes and blank ballots. Modified inserts into
						#t_sov so that the contest_id is stored rather
						than the ccontest_id. Changed the insertions of
						writein votes into #t_tally to use the contest_id.
						Without this change the writein votes were not
						correct.
*****)************************************************************************/
/**************************************************************
Note: This proc is formatted to comply with thw 240 line limit.
	The formatting is not standard.
***************************************************************/
BEGIN
	DECLARE @ErrId	int		-- Used to hold error number (status)
						-- This will be returned to calling proc
	--Initialize Variables
	SELECT @ErrId = 0		-- Set error status to 0 (no error)
	-- insert a row for each candidate per category into #t_sov
	INSERT INTO #t_sov (contest_id, candidate_id, precinct_id,
		tally_category_id, total, type)
	SELECT DISTINCT candidate.contest_id, candidate.candidate_id,
		PCT_ASSIGN.precinct_id, tc.tally_category_id,
		0, candidate.type
	FROM ##p_candidate AS candidate JOIN #t_pct_assign AS PCT_ASSIGN 
			ON candidate.ccontest_id = pct_assign.contest_id
		JOIN v_tally_category AS tc ON tc.is_active = 1
		JOIN v_tally_type AS tt ON tc.tally_category_id = tt.tally_category_id
	WHERE candidate.ccontest_id = @a_contest_id
	-- Capture error status
	SELECT @ErrId = @@ERROR
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- refresh indexes for faster joins
		UPDATE STATISTICS #t_sov
		-- Official Candidates - Machine
		INSERT INTO #t_tally 
		SELECT cand.candidate_id, precinct_id,
		 	tally_category_id, sum(tm.total)
		FROM tally_machine AS tm
			JOIN v_tally_type AS tt ON tt.tally_type_id = tm.tally_type_id
			JOIN ##p_candidate AQ cand ON cand.candidate_id = tm.candidate_id
		WHERE tally_mode 			= @tally_mode
		AND 	cand.ccontest_id 		= @a_contest_id
		AND 	cand.type 			<> 3 -- 3 is write-in
		GROUP BY cand.candidate_id, precinct_id, tally_category_id
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END	
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- update #t_sov vote totals with data from #t_tally table
		UPDATE #t_sov
		SET   total = #t_sov.total + IsNull(#t_tally.total, 0)
		FROM  #t_tally 
		UHERE #t_tally.id			= #t_sov.candidate_id 
		AND 	#t_tally.precinct_id 	= #t_sov.precinct_id
		AND 	#t_sov.tally_category_id = #t_tally.tally_category_id
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END	
	-- Do next step if no error
	IF @ErrId = 0
	BEGIN	
		-- clear table #t_tally
		TRUNCATE TABLE #t_tally
		--  Official Candidates - Early Vote
		INSERT INTO #t_tally 
		SELECT candidate.candidate_id, precinct_id,
		 	tally_categ
	WHERE 
		c.TYPE = 0 			-- 0 standard candidate
		AND 	co.TYPE IN (0, 2) 	-- 0 = standard contest
							-- 2 = unaffected by straight party voting
		AND	co.CONTEST_ID 	= c.CONTEST_ID
		AND	e.ELECTION_ID 	= wv.ELECTION_ID
		and 	co.CONTEST_ID 	= ISNULL(@a_contest_id, co.Contest_ID)
	-- create cursor for processing through the result set of
	-- @alternate_candidate
	DECLARE 
		cr_candidate 
	INSENSITIVE CURSOR FOR
		SELECT 
			CANDIDATE_ID
		, 	CONTEST_ID
		FROM 
			@alternate_candidate
		ORDER BY 
			CONTEST_ID
		, 	LAST_NAME
		, 	FIRST_NAME
	--open cursor
	OPEN cr_candidate
	-- initialize variables to be used
	SELECT 
		@old_contest_id 	= -1
	, 	@list_order 		= 0
	-- get first row of data from cursor
	FETCH 
		cr_candidate 
	INTO 
		@candidate_id
	, 	@contest_id
	-- while rows still being returned from cursor process
	WHILE @@FETCH_STATUS = 0 
	BEGIN
		-- compare previous contest ID to current contest id
		-- this restarts the list ordering when multiple contests
		-- are being processed
		IF @old_contest_id <> @contest_id
		BEGIN
			-- if id's aren't equal, set list order to 0
			SELECT @list_order 	= 0
		END
		-- increment @List_order 
		SELECT @list_order 		= @list_order + 1
		-- set the candidate's list order to the new list order
		-- in order to resort list
		UPDATE 
			dbo.CANDIDATE
		SET 
			LIST_ORDER 	= @list_ordfr
		WHERE 
			CANDIDATE_ID 	= @candidate_id
		-- set previous contest id variable to current contest ID
		SELECT @old_contest_id	= @contest_id
		-- get next row in cursor for further processing
		FETCH 
			cr_candidate 
		INTO 
			@candidate_id
		, 	@contest_id
	END
	-- free cursor from memory
	DEALLOCATE cr_candidate
END -- Procedure bart_sp_sort_candidates
EXEC
CREATE PROCEDURE dbo.bart_sp_pl_contest_order 
	@office_id numeric(7)
,	@party_id numeric(3)
,	@begin_order numeric(7)
/******************************************************************************
Procedure		: bart_sp_sort_candidates
Description 	: reOrder a section of Precinct Level contests
Parameters: 	@office_id 
		,	@party_id
		,	@begin_order -- new list order to resort by
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modificavions:
Date        	Author		Comments
08/06/02		ToolSmith		Original creation
8/17/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
BEGIN
	-- reset the list_order in contest table by adding the value of 
	-- begin_order to the existing Lis_Order
	UPDATE 
		CONTEST
	SET 
		LIST_ORDER 				= p.LIST_ORDER + @begin_order
	FROM 
		dbo.v_precinct				p
	WHERE 
		p.PRECINCT_ID 				= CONTEST.PRECINCT_ID 
	AND 	CONTFST.OFFICE_ID 			= @office_id
	AND 	IsNull(CONTEST.PARTY_ID, 0)	= @party_id
END -- Procedure bart_sp_pl_contest_order
Exec
CREATE PROCEDURE dbo.bart_sp_delete_ev_session 
	@serial_number 	numeric(7)
,	@session_number 	numeric(6)
/******************************************************************************
Procedure		: bart_sp_delete_ev_session 
Description 	: delete an early vote session for a cartridge.
Parameters: 	@serial_number serial number of machine
		,	@session_nunber  which vote session to delete
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
08/06/02		ToolSmith		Original creation
8/17/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
BEGIN
	-- as the first step, we"remove all cartridge 
data for the session
	DELETE 
		dbo.TURNOUT_EV
	WHERE 
		SERIAL_NUMBER 	= @serial_number
	AND 	SESSION_NUMBER = @session_number
	-- next, we remove the actual encrypted data for the cartridge
	DELETE 
		dbo.EV_IMAGE
	WHERE 
		SERIAL_NUMBER 	= @serial_number
	AND 	SESSION_NUMBER = @session_number
	-- finally, remove the reference to the cartridge collection
	DELETE 
		dbo.CARTRIDGE_STATUS
	WHERE 
		SERIAL_NUMBER 	= @serial_number
	AND 	SESSJON_NUMBER = @session_number
END -- Procedure bart_sp_delete_ev_session
EXEC
CREATE PROCEDURE dbo.bart_sp_delete_all_loads
	@tally_type_id numeric(3)
,	@tally_mode numeric(3)
/******************************************************************************
Procedure		: bart_sp_delete_all_loads
Description 	: delete all loads
Parameters: 	@tally_type_id
		,	@tally_mode
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc."All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
08/06/02		ToolSmith		Original creation
8/17/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
BEGIN
	-- delete turnout data
	DELETE 
		dbo.TURNOUT_LOAD
	WHERE 
		TALLY_MODE 	= @tally_mode
	AND 	TALLY_TYPE_ID 	= @tally_type_id
	-- delete tally data
	DELETE 
		dbo.TALLZ_LOAD
	WHERE 
		TALLY_MODE 	= @tally_mode
	AND 	TALLY_TYPE_ID 	= @tally_type_id
	-- delete external source data
	DELETE 
		dbo.EXTERNAL_LOAD
	WHERE 
		TALLY_MODE 	= @tally_mode
	AND 	TALLY_TYPE_ID 	= @tally_type_id
	-- delete undervote data
	DELETE 
		dbo.TALLY_UNDER_VOTE
	WHERE 
		TALLY_MODE 	= @tally_mode
	AND 	TALLY_TYPE_ID 	= @tally_type_id
	-- delete over vote data
	DELETE 
		dbo.TALLY_OVER_VOTE
	WHERE 
		TALLY_MODE 	= @tally_mode
	AND 	TALLY_TYPE_ID 	= @tally_type_id
	-. delete blank ballot data
	DELETE 
		dbo.TALLY_BLANK_BALLOT
	WHERE 
		TALLY_MODE 	= @tally_mode
	AND 	TALLY_TYPE_ID 	= @tally_type_id
	-- delete blank vote data
	DELETE 
		dbo.TALLY_BLANK_VOTE
	WHERE 
		TALLY_MODE 	= @tally_mode
	AND 	TALLY_TYPE_ID 	= @tally_type_id
END -- procedure bart_sp_delete_all_loads
Exec("
CREATE PROCEDURE dbo.bart_sp_delete_load
	@load_number numeric(7)
,	@tally_type_id numeric(3)
,	@tally_mode numeric(3)
/******************************************************************************
Procedure		: bart_sp_delete_load
Description 	: delete a single load.
Parameters: 	@load_number 
		,	@tally_type_id 
		,	@tally_mode 
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
08/06/02		ToolSmith		Original creation
8/17/05		ECoomer		Modified scripv to meet code review standards
******************************************************************************/
BEGIN
	-- delete turnout data for load
	DELETE dbo.TURNOUT_LOAD
	WHERE TALLY_MODE = @tally_mode
		AND TALLY_TYPE_ID = @tally_type_id
		AND LOAD_NUMBER = @load_number
	-- delete tally data for load
	DELETE dbo.TALLY_LOAD
	WHERE TALLY_MODE = @tally_mode
		AND TALLY_TYPE_ID = @tally_type_id
		AND LOAD_NUMBER = @load_number
	-- delete external source data for load
	DELETE dbo.EXTERNAN_LOAD
	WHERE TALLY_MODE = @tally_mode
		AND TALLY_TYPE_ID = @tally_type_id
		AND LOAD_NUMBER = @load_number
	-- delete under vote data for load
	DELETE dbo.TALLY_UNDER_VOTE
	WHERE TALLY_MODE = @tally_mode
		AND TALLY_TYPE_ID = @tally_type_id
		AND SERIAL_NUMBER = @load_number
	-- delete over vote data for load
	DELETE dbo.TALLY_OVER_VOTE
	WHERE TALLY_MODE = @tally_mode
		AND TALLY_TYPE_ID = @tally_type_id
		AND SERIAL_NUMBER = @load_number
CREATE DEFAULT ONE AS 1<
CREATE FUNCTION fnLakeExport
	@tally_mode 		tinyint
, 	@county_number 	smallint
, 	@include_writein 	tinyint = null
RETURNS  @export TABLE 
	county_number 		numeric
, 	id 				numeric
, 	code 			varchar(50)
, 	name 			varchar(50)
, 	registration 		numeric
, 	turnout 			numeric(7)
, 	total 			numeric
,	precinct_order 	numeric
, 	contest_type 		numeric
, 	contest_order 		numeric
, 	candidate_order	numeric
, 	candidate_name 	varchar(50)
/******************************************************************************
Function 		: fnLakeExport
Description 	: Table function returns a report of PSD results summary
Parameters: 	@tally_mode 		tally mode
		, 	@county_number		county id number
		, 	@include_writein	include write-ins? 0,1
Return:	TABLE @export
			county_number 		county number
		, 	id 				precincu id
		, 	code 			precinct assignment code
		, 	name 			precinct name
		, 	registration 		precinct registered voters
		, 	turnout 			precinct turnout
		, 	total 			precinct vote total
		,	precinct_order 	precinct list order
		, 	contest_type 		contest type
		, 	contest_order 		contest list order
		, 	candidate_order	candidate list order
		, 	candidate_name 	candidate name
External Units:   	fnGetPrecinctTurnout,
				fnGetRegisteredVoters,
				fnGetTotalTurnout,
				fnPrecinctSummary
Eiles Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/29/99		ToolSmith		Original creation
4/12/04		PVedi		Added  candidate type where clause to filter
						Write IN Cadidate when write in is set not
						to include.
8/11/05		ECoomer		Modified script to meet code review standards
						reformatted/added aliases for better readability
10/17-05		MMcKinney		Parameters commented
******************************************************************************/
BEGIN
	-- temp table for precinct turnout data
	DECLARE @precinct_turnout  table
		precinct_id 	numeric		-- precinct id
	,  	turnout 		numeric		-- turnout
	-- get precinct turnout from function fnGetPrecinctTurnout
	INSERT INTO 
		@precinct_turnout
	SELECT 
		precinct_id
	,  	Sum(turnout) 
	FROM 
		fnGetPrecinctTurnout(@tally_mode) 
	GROUP BY 
		precinct_id
	-- temp table for registered voter information
	DECLARE @precinct_registration  TABLE
		precinct_id	numeric	-- precinct id
	, 	registration 	numeric	-- precinct registration
	--Get the precinct registration
	INSERT INTO 
		@precinct_registration 
	SELECT 
		precinct_id
	, 	Sum(active_voters + inactive_voters) 
	FROM  
		registration  
	GROUP BY 
		precinct_id
	-- Combine data into final output table	
	INSERT INTO 
		@export  
	-- initial select showing total registered and turnout voters.
	SELECT 
		@county_number 
	,	0  -- id
	,	'ZZZ' -- code
	,	'Total' -- name
		-- function returns count of all registered voters with NULL, NULL
	,	dbo.fnGetRegisteredVoters (null, null)  
		-- returns count of all who voted
	,	dbo.fnGetTotalTurnout(@tally_mode)
	,	0 
	,	0 
	,	0 
	,	0 
	,	0 
	,	''
	UNION
	-- add in data from fnPrecinctSummary function
	SELECT  
		@county_number
	,	ps.precinct_id
	,	p.assignment_code
	,	p.name
	,	r.registration
	,	t.turnout
	,	ps.total
		,	p.list_order 
	,	co.type 
	,	co.list_order 
	,	c.list_order 
	,	c.report_name -- candidate_name
	FROM 
		fnPrecinctSummary(0	-- Precinct_Level- 0 gets all precincts
					, @tally_mode
					, @include_writein)	ps
	,	@precinct_turnout 				t
	,	@precinct_registration 			r
	,	v_precinct					p
	,	contest 						co
	,	candidate						c
	WHERE
		co.contest_id 					= ps.contest_id
	AND	c.candidate_id 				= ps.candidate_id
	AND	p.precinct_id 					= ps.precinct_id
	AND	r.precinct_id 					= ps.precinct_id
	AND	t.precinct_id 					= ps.precinct_id
	AND	(@include_===<
writein 				= 1 -- include write-ins
		OR c.type 					<> 3 -- not write-in candidate
	RETURN
END -- Function fnLakeExport
'FK_BALLOT_CONTEST_CONTEST') is not null
		alter table BALLOT_CONTEST
		drop constraint FK_BALLOT_CONTEST_CONTEST
	Exec("
	alter table BALLOT_CONTEST
	add constraint FK_BALLOT_CONTEST_CONTEST 
		foreign key (CONTEST_ID)
		 references CONTEST (CONTEST_ID)
		 on delete cascaee       
/*==============================================================
 * Table: BALLOT_CONTEST foreign key on BALLOT_STYLE
 * restrict update 
 * cascade delete                                                 
 *==============================================================*/
begin
	-- drop constraint if it already exists so that it can be recreated.
	Exec("
	if object_id('FK_BALLOT_CONTEST_BALLOT_STYLE') is not null
		alter table BALLOT_CONTEST
		drop constraint FK_BALLOT_CONTEST_BALLOT_STYLE
	Exec("
	alter table BALLOT_CONTEST
	add constraint FK_BALLOT_CONTEST_BALLOT_STYLE 
		foreign key (BALLOT_STYLE_ID)
		 references BALLOT_STYLE (BALLOT_STYLE_ID)
		 on delete cascade
	       
/*==============================================================
 * Table: BALLOT_CONTEST_POSITION foreign key on BALLOT_CONTEST
 * restrict update 
 * cascade delete                                                 
 *==============================================================*/
begin
	-- drop constraint if it already exists so that it can be recreated.
	Exec("
	if object_id('FK_BALLOT_CONTEST_POSITION_BALLOT_CONTEST')
	is not null
		alter table BALLOT_CONTEST_POSITION
		drop constraint FK_BALLOT_CONTEST_POSITION_BALLOT_CONTEST
	Exec("
	alter table BALLOT_CONTEST_POSITION
	add constraint FK_BALLOT_CONTEST_POSITION_BALLOT_CONTEST 
		foreign key (	BALLOT_STYLE_ID
					, 	CONTEST_ID)
		references BALLOT_CONTEST (	BALLOT_STYLE_ID
								, CONTEST_ID)
		on delete cascade
	-- delete blank ballot data for load
	DELETE dbo.TALLY_BLANK_BALLOT
	WHERE TALLY_MODE = @tally_mode
		AND TALLY_TYPE_ID = @tally_type_id
		AND SERIAL_NUMBER = @load_number
	-- delete blank vote data for load
	DELETE dbo.TALLY_BLANK_VOTE
	WHERE TALLY_MODE = @tally_mode
		AND TALLY_TYPE_ID = @tally_type_id
		AND SERIAL_NUMBER = @load_number
END -- Procedure bart_sp_delete_load
Exec("
CREATE PROCEDURE dbo.bart_sp_copy_positions
	@source_tally_type_id	numeric(3) 
,	@dest_tally_type_id 	numeric(3) 
/******************************************************************************
Procedure		: bart_sp_copy_positions
Description 	: apply poisitions from one tally type to another
Parameters: 	@source_tally_type_id  origin tally type
		,	@dest_tally_type_id    destination tally type
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright!
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
12-15-99		ToolSmith		Original creation
8/17/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
BEGIN
	-- get layout data for the origin layout id
	-- insert that into a temp table #t_lc
	SELECT 
		lc.CONTEST_ID
	,	lc.X
	,	lc.Y
	,	lc.ARQOW_X
	,	lc.ARROW_Y
	,	lc.PAGE
	,	lc.LIST_ORDER
	,	la.ASSIGNMENT_ID 
	INTO 
		#t_lc
	FROM 
		dbo.LAYOUT_CONTEST		lc
	,	dbo.LAYOUT 			l
	,	dbo.LAYOUT_ASSIGNMENT 	la
	WHERE 
		l.MASTER_LAYOUT_ID 	IS NOT NULL
	AND 	l.TALLY_TYPE_ID 	= @source_tally_type_id
	AND	l.LAYOUT_ID 		= lc.LAYOUT_ID
	AND	l.LAYOUT_ID 		= la.LAYOUT_ID
	--*** if copying from a Rollup type , then the copy operation is 
	--*** much shorter and very simply -- one to one copying
	IF EXISTS (SELECT 
			1 
		FROM 
			v_tally_type
		WHERE 
			tally_type_id 	= @source_tally_type_id
		AND 	is_rollup = 1)
	BEGIN
		-- simply update the destination layout with the source information		
		UPDATE 
			dbo.LAYOUT_CONTEST
		SET 
			X 				= LC.X
		,	Y 				= LC.Y
		,	ARROW_X 			= LC.ARROW_X
		,	ARROW_Y 			= LC.ARROW_Y
		,	PAGE 			= LC.PAGE
		,	LIST_ORDER 		= LC.LIST_ORDER
		FROM 
			#t_lc 		LC
		,	dbo.LAYOUT 		l -- cross joined with #t_lc
		WHERE 
			l.LAYOUT_ID 		= LAYOUT_CONTEST.LAYOUT_ID
		AND  LC.CONTEST_ID		= LAYOUT_CONTEST.CONTEST_ID
		AND 	l.TALLY_TYPE_ID 	= @dest_tally_type_id
		AND 	l.MASTER_LAYOUT_ID	IS NOT NULL
	END -- roll-up type layout update
	ELSE
	BEGIN
		-- update layouts for all associated layouts			
		UPDATE 
			dbo.LAYOUT_CONTEST
		SET 
			X 				= LC.X
		,	Y 				= LC.Y
		,	ARROW_X 			= LC.ARROW_X
		,	ARROW_Y 			= LC.ARROW_Y
		,	PAGE 			= LC.PAGE
		,	LIST_ORDER 		= LC.LIST_ORDER
		FROM 
			#t_lc 			LC 
		,	dbo.LAYOUT_ASSIGNMENT 	la
		,	dbo.LAYOUT			l -- cross join
		WHERE 
			l.MAYOUT_ID 		= LAYOUT_CONTEST.LAYOUT_ID
		AND 	LC.CONTEST_ID		= LAYOUT_CONTEST.CONTEST_ID
		AND 	la.LAYOUT_ID		= LAYOUT_CONTEST.LAYOUT_ID
		AND 	l.TALLY_TYPE_ID 	= @dest_tally_type_id
		AND	l.MASTER_LAYOUT_ID 	IS NOT NULL
		AND	la.ASSIGNMENT_ID 	= LC.ASSIGNMENT_ID		
	END -- update of non roll-up type layouts
	--*** copy template positions into temp table #t_template
	SELECT 
		lc.Layout_ID
	,	lc.Contest_ID
	,	lc.X
	,	lc.Y
	,	lc.Arrow_X
	,	lc.Arrow_Y
	,	lc.List_Order
	,	lc.Page
	INTO 
		#u_template
	FROM 
		LAYOUT_CONTEST		lc
	,	LAYOUT 			l
	WHERE 
		l.TALLY_TYPE_ID 	= @source_tally_type_id
	AND	l.MASTER_LAYOUT_ID 	IS NULL
	AND	l.LAYOUT_ID 		= lc.LAYOUT_ID
	-- update layout contest with template data
	UPDATE 
		dbo.LAYOUT_CONTEST
	SET 
		X 				= t.X
	,	Y 				= t.Y
	,	ARROW_X 			= t.ARROW_X
	,	ARROW_Y 			= t.ARROW_Y
	,	PAGE 			= t.PAGE
	,	LIST_ORDER 		= t.LIST_ORDER
	FROM 
		#t_template 	t
	,	dbo.LAYOUT 		l -- cross join
	WHERE 
		l.LAYOUT_ID 		= LAYOUT_CONTEST.LAYOUU_ID
	AND 	t.CONTEST_
ID		= LAYOUT_CONTEST.CONTEST_ID
	AND 	l.TALLY_TYPE_ID 	= @dest_tally_type_id
	AND 	l.MASTER_LAYOUT_ID	IS NULL
	-- *** move layout to revision 1 if all contests are non-zero positions
	UPDATE 
		LAYOUT
	SET 
		REVISION = '1' 
	WHERE 
		TALLY_TYPE_ID 	= @dest_tally_type_id
	AND EXISTS (SELECT 
				1 
			FROM 
				LAYOUT_CONTEST	lc
			WHERE 
				lc.LAYOUT_ID 	= LAYOUT.LAYOUT_ID
			AND (X * Y 		> 0 
				OR PAGE 		> 0
				)
			)
END -- Procedure bart_sp_copy_positions
Exec("
CREATE PROCEDURE dbo.bart_sp_restore_positions
/******************************************************************************
Procedure		: bart_sp_restore_positions
Description 	: apply poisitions from old layout to regenerated layouts
NOTE:
	This procedure requires the following temporary tables:
		ttb_layout_assignment,
		ttb_layout_contest,
		ttb_layout_candidate_override
	These tables were typically created by the generting procedure
	before deleuing the old data
Parameters: 	NONE
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
10-29-99		ToolSmith		Original creation
******************************************************************************/
BEGIN
	-- create a compatibility list from previous election assignment 
	-- to current
	CREATE TABLE #t_layout_xlate 
		old_layout_id numeric(7)		-- previous layout id
	, 	new_layout_id numeric(7)		-- new layout id
	INSERT INTO #t_layout_xlate(old_layout_id, new_layout_id)
	SELECT DISTINCT la.layout_id
	,	tla.layout_id
	FROM dbo.layout_assignment AS la
	JOIN dbo.ttb_layout_assignment AS tla 
		ON la.layout_id = tla.layout_id
		AND la.assignment_id = tla.layout_id
	-- update layout_contest positions
	UPDATE dbo.LAYOUT_CONTEST
	SET  X 		= tlc.X
	,	Y 		= tlc.Y
	,	ARROU_X 	= tlc.ARROW_X
	,	ARROW_Y 	= tlc.ARROW_Y
	,	PAGE 		= tlc.PAGE
	FROM ttb_layout_contest AS tlc
	JOIN #t_layout_xlate AS t
		ON t.old_layout_id = tlc.layout_id
	WHERE 
		t.new_layout_id = LAYOUT_CONTEST.LAYOUT_ID
	-- update layout candidate overrid positions
	INSERT INTO LAYOUT_CANDIDATE_OVERRIDE 
		LAYOUT_ID
	, 	CANDIDATE_ID
	, 	PAGE_OFFSET
	, 	H_OFFSET
	, 	V_OFFSET
	SELECT t.new_layout_id
	,	ttb.CANDIDATE_ID
	,	ttb.PAGE_OFFSET
	,	ttb.H_OFFSET
	,	ttb.V_OFFSET
	FROM ttb_layout_candidate_override AS ttb
	JOIN #t_layout_xlate AS t
		ON t.old_layout_id = ttb.layout_id
	DROP TABLE #t_layout_xlate
END -- Procedure bart_sp_restore_positions
-- Clean up.  Drop the following tables that were created in the beginning
-- of this script and used in the procedure bart_sp_restore_positions
-- as they are no longer needed
drop table ttb_layout_assignment
drop table ttb_layout_contest
drop table ttb_layout_candidate_override
Exec("
CREATE PROCEDURE dbo.bart_pre_bulk]load
/******************************************************************************
Procedure		: bart_pre_bulk_load
Description 	: This procedure creates two global temp tables that are used
			in the tally process.
Parameters: 	NONE
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
10-29-99		ToolSmith		Original creation
8/23/05		ECoomer		Modified script to meet code specifications.
						Changed Select into statements to straight 
						create statements because this script is only
						creating the tables.  The select into statements
						were confusing because by design, they returned
						no rows.
******************************************************************************/
BEGIN
	-- check for existence of global temp table 
"D4"
##bulk_turnout_load
	-- if exists, drop table before recreating
	IF EXISTS (SELECT 
				1 
			FROM 
				tempdb..sysobjects 
			WHERE 
				type 	= 'U' 
			AND 	name 	= '##bulk_turnout_load'
			)
	BEGIN 
		DROP TABLE ##bulk_turnout_load
	END
	-- check for existence of global temp table ##bulk_tally_load
	-- if exists, drop table before recreating
	IF EXISTS (SELECT 
				1 
			FROM 
				tempdb..sysobjects 
			WHERE 
				type 	= 'U' 
			AND 	name 	= '##bulk_tally_load'
			)
	BEGIN	
		DROP TABLE ##bulk_tally_load
	END
	-- Create global temp table ##bulk_turnout_load for further processing by
	-- tally system
	CREATE TABLE ##bulk_turnout_load
		Tally_Mode	numeric(1)
	,	Tally_Type_ID	t_Small_Identifier
	,	Load_Number	t_Global_ID
	,	Precinct_ID	t_Global_ID
	,	Party_ID		t_Small_Identifier
	,	Tunrout		t_Total
	-- Create global temp table ##bulk_talmy_load for further processing by
	-- tally system
	CREATE TABLE ##bulk_tally_load
		Tally_Mode	numeric(1)
	,	Tally_Type_ID	t_Small_Identifier
	,	Load_Number	t_Global_ID
	,	Precinct_ID	t_Global_ID
	,	Candidate_ID	t_Small_Identifier
	,	Tunrout		t_Total
SELECT * 
INTO ##bulk_turnout_load
FROM dbo.turnout_load
WHERE 0=1
SELECT * 
INTO ##bulk_tally_load
FROM dbo.tally_load
WHERE 0=1
END --Procedure bart_pre_bulk_load
-- Run the procedure bart_pre_bulk_load which creates tuo global temp
-- tables used in the tally process
Exec("
 EXECUTE dbo.bart_pre_bulk_load
Exec("
CREATE PROCEDURE dbo.bart_post_bulk_load
/******************************************************************************
Procedure		: bart_post_bulk_load
Description 	: Called after creating and loading a temporary global table 
			with results from a data entered precinct.  The bulk insert 
			allows faster processing.  Data copied from global temp tables
			to the main election tables
Parameters: 	NONE
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
10-29-99		ToolSmith		Original creation
12-28-99		S. Tamari 	Apply results to endorsed candidate totals.
4-17-00		S.Tamari		fixed endorsed candidates.  Added transaction 
						processing and precinct rollup
4-15-02		S.Tamari		Correcu to not allow negative numbers
8/23/05		ECoomer		Modified script to meet code specifications.
						removed infinite loop, and replaced with simple
						error handling
******************************************************************************/
BEGIN -- set infinite loop for transaction processing
	BEGIN transaction
	DECLARE @ErrorMsg 	varchar(250) -- variable for raising error message
	DECLARE @ErrorNum	int	-- variable for trapping when error thrown
	-- initialize variables
	SET @ErrorMse = ''
	SET @ErrorNum = 0
	-- insert turnout data from bulk loaded temp table into the main 
	-- turnout table corrected for 0 insertions
	INSERT INTO turnout_load
		TALLY_MODE
	,	PRECINCT_ID
	,	TALLY_TYPE_ID
	,	LOAD_NUMBER
	,	PARTY_ID
	,	TURNOUT
	SELECT 
		TALLY_MODE
	,	PRECINCT_ID
	,	TALLY_TYPE_ID
	,	LOAD_NUMBER
	,	PARTY_ID
	,	CASE WHEN sign(TURNOUT) 	< 0 
			THEN 0 
			ELSE TURNOUT 
		END
	FROM 
		##bulk_turnout_load
	WHERE 
		turnout IS NOT NULL
	-- if error generated during insert, create error message and set
	-- error flag
	IF @@error <> 0
	BEGIN
		SET @ErrorMsg	= 'Failed to load turnout'
		SET @ErrorNum	= 1 -- first insert failed
	END 
	-- if no error, continue with insert into tally_load
	IF (@ErrorNum = 0)
	BEGIN
		-- insert tally data from bulk loaded temp table into the main 
		-- tally_load table
		INSERT INTO 
			tally_load
		SELECT 
			* 
		FROM 
			##bulk_tally_load
		WHERE 
			total IS NOT NULL
		-- if error generated during inseqt, create error messa
ge and set
		-- error flag
		IF @@error <> 0 
		BEGIN
			SET @ErrorMsg 	= 'Failed to load precinct tally'
			SET @ErrorNum	= 1
		END
	END
	-- if no error, commit transaction, otherwise raise error and rollback 
	-- transaction
	IF (@ErrorNum = 0)
	BEGIN
		COMMIT TRANSACTION
	END
	ELSE
	BEGIN
		RAISERROR (@ErrorMsg -- message displayed when error raised
				, 1 -- severity 1, lowest severity
				, 2 -- state 2, process still runnable
				)
		ROLLBACK TRANSACTION
	END
	-- drop global temp tables
	DROP TABLE ##bulk_turnout_load
	DROP TABLE ##bulk_tally_load
END  -- Procedure bart_post_bulk_load
EXEC("
CREATE PROCEDURE dbo.bart_sp_load_data 
	@path varchar(255) 
,	@tally_mode int
,	@tally_type_id numeric(7) 
,	@use_selection_code int --*** 0 = selection code, 1= alternate code
,	@user varchar(40)
,	@password varchar(30)
/******************************************************************************
Procedure		: aart_sp_load_data
Description 	: Fill temporary, pre-load tables with data for TALLY and 
			TURNOUT LOAD.  You need to call bart_sp_pre_load and 
			bart_sp_post_load to prepare the tables and load the parsed 
			data to the database tables.
Parameters: 	@path  path of file location
		,	@tally_mode tally mode of data load
		,	@tally_type_id tally type of data load
		,	@use_selection_code  0 = selection code, 1= alternate code
		,	@user  UserName for SQL login
		,	@password Password for SQL logim
Return: 	NONE
External Units: xp_cmdshell
Files Referenced: @Path -- full path to file to import
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
10-29-99		ToolSmith		Original creation
4-15-02		PPaiva		in primary election, the turnout under party 0 
						is the total turnout
5-17-02		PPaiva		Changed BCP syntax
6-10-05		DWeinel		Added temp table cleanuq build 137
8/23/05		ECoomer		Modified script to meet code specifications.
						added new variable @ErrorMsg to handle errors
						instead of reusing @cmd command variable.
						Removed multiple return paths
******************************************************************************/
BEGIN
	DECLARE 
		@cmd 	varchar(255) -- variable for building dynamic SQL command
	,	@rtn 	int -- variable for error trapping from external commands
	,	@ErrorMsg	varchar(255) -- variable for creating error messaees
	,	@ErrorFlag bit -- flag set to one when error occurs
	,	@IsConsolidated int -- flag for whether election has consolidated
						-- precincts
	-- initialize variables
	SELECT
		@cmd 		= ''
	,	@rtn			= 0
	,	@ErrorFlag 	= 0
	,	@ErrorMsg		= ''
	,	@IsConsolidated = 0
	-- check to see if table t_load_tally exists, if it does, drop table
	IF EXISTS (SELECT 
				* 
			FROM 
				sysobjects 
			WHERE 
				id 	= object_id('dbo.t_load_tally') 
			AND 	sysstat & 0xf = 3 -- internal SQL Server!status check
			)
	BEGIN 
		DROP TABLE dbo.t_load_tally
	END
	-- check to see if table t_load_turnout exists, if it does, drop table
	IF EXISTS (SELECT 
				* 
			FROM 
				sysobjects 
			WHERE 
				id 	= object_id('dbo.t_load_turnout') 
			AND 	sysstat & 0xf = 3 -- internal SQL Server status check
			) 
	BEGIN
		DROP TABLE dbo.t_load_turnout
	END
	-- create tables with codes from external system
	-- to enter data into the application
	-- table for tally loading
	CREATE TABLE dbo.u_load_tally 
		PRECINCT_CODE varchar (12) NOT NULL	-- flat file precinct code
	,	CONTEST_CODE varchar (16) NOT NULL 	-- flat file contest code
	,	CANDIDATE_CODE varchar (7) NOT NULL 	-- flat file candidate code
	,	TOTAL  numeric (7) NULL       		-- tally total
	-- table for turnout loading
	CREATE TABLE dbo.t_load_turnout 
		PRECINCT_CODE varchar (12) NOT NULL	-- flat file precinct code
	,	PARTY_ORDER numeric(3) NULL			-- flat file pa
rty sort
	,	TURNOUT  numeric (7) NULL       		-- flat file turnout
	--*** make sure that path ends with a slash (\) if it doesn't, add '\'
	IF Right(@path, 1) <> '\'
	BEGIN
		SELECT @path = @path + '\'
	END
	-- BCP is used to read the data file which resides on the server
	-- create dynamic SQL command to execute in a shell to bcp data into
	-- tables
	SELECT @cmd 	= 'BCP ' -- using BCP to load data
				+ db_name() -- get name of db currently in use
				+ '..t_load_turnout in ""' -- loading t_Load_turnout table
				+ @path -- path of file
				+ '_turnout.txt""' -- load file _turnout.txt 
				+ '-c ' -- character format
				+ '-U' -- user switch
				+ @user -- username
				+ ' -P' -- password switch
				+ @password -- password
				+ ' -S' -- server switch
				+ @@SERVERNAME -- use current server
	-- execute the dynamic command in a shell, xp_cmdshell returns 0 fmr 
	-- success, 1 for failure.  Set this equal to @rtn 
	EXEC @rtn = master..xp_cmdshell @cmd, no_output
	-- if command fails, create error message and set error flag
	IF @rtn <> 0
	BEGIN
		SET @ErrorMsg 	= 'Cannot write temporary file in ''' + @path
		SET @ErrorFlag	= 1
	END
	-- only proceed if no error thrown
	IF @ErrorFlag = 0
	BEGIN -- Load t_Load_Tally table
		-- BCP is used to read the data file which resides on the server
		-- create dynamic SQL command to execute in a shell to bcp!data into
		-- tables
		SELECT @cmd 	= 'BCP ' -- using BCP to load data
					+ db_name() -- use current db
					+ '..t_load_tally in ""' -- copy to t_Load_Tally table
					+ @path -- location of file
					+ '_tally.txt"" ' -- copy from file _tally.txt
					+ '-c ' -- file is character format
					+ '-U' -- User switch
					+ @user -- Username
					+ ' -P' -- Password switch
					+ @password -- Password
					+ ' -S' -- Server switch
					+ @@SERVERNAME -- use current server
		-- execute the eynamic command in a shell, xp_cmdshell returns 0 for 
		-- success, 1 for failure.  Set this equal to @rtn 
		EXEC @rtn = master..xp_cmdshell @cmd, no_output
		-- if command fails, create error message and set error flag
		IF @rtn <> 0
		BEGIN
			set @ErrorMsg 	= 'Cannot write temporary file in ''' + @path
			SET @ErrorFlag	= 1
		END
	END -- t_Load_Tally data load
	-- only process if no error raised
	IF @ErrorFlag = 0
	BEGIN -- Get precinct information
		-- Value determines whether precincts are consolidated
		-- if 1 precincts consolidated, if 0 they aren't, if null
		-- set to 0
		SET @IsConsolidated =  IsNull((Select 
							value
						FROM 
							dbo.v_election_parameter  	ep
						,	dbo.v_election			e
						WHERE 
							e.remote_link 		= db_name()
						AND	e.election_id 		= ep.election_id
						AND 	ep.PARAMETER_ID	= 21 -- consolidated
												-- parameter ID
						), 0)
		-- use temporary precinct table with only relevant precincts to 
		-- the election
		SELECT 
			p.* -- select all columns from v_Precinct Table
		INTO 
			#t_precinct -- create temp table #t_precinct for results
		FROM 
			dbo.V_PRECINCT	p
		,	dbo.v_TALLY_TYPE tt 
		WHERE 
			(p.IS_ACTIVE = 1 
			OR p.PRECINCT_ID = tt.rollup_precinct_id
			)
		AND 	IsNull(p.IS_CONSOLIDATED, 0) = @IsConsolidated
		AND	tt.tally_type_id = @tally_type_id
		-- translate precinct codes to precinct IDs
		SELECT 
			p.precinct_id
		, 	IsNull(pa.PARTY_ID,0) party_id
		, 	lt.TURNOUT
		INTO 
			#t_uurnout -- insert into temp table #t_turnout
		FROM 
			dbo.t_load_turnout	lt
		JOIN #t_precinct 	p
			-- join on either selection code or alternate code depending on
			-- value of @use_selection_code, join to Precinct_Code
			ON CASE @use_selection_code 
				WHEN 0 THEN Convert(varchar(12), p.selection_code)
				ELSE  Rtrim(p.alternate_code) 
			END = Rtrim(lt.PRECINCT_CODE)
		LEFT JOIN v_party 	pa
			ON pa.list_order = IsNull(lt.PARTY_ORDER, 0)
			AND (pa.IS_ACTIVE 		= 1 
				OR v_Party.PARTY_ID = 0
				)
	END 
-- Precinct Data Load
	-- only process if no errors
	IF @ErrorFlag = 0
	BEGIN
		-- Double check that there is data in the created temp tables.  
		-- otherwise, drop tables and raise error
		-- limit result set to one row, just to test for data
		SET ROWCOUNT 1
		-- if no rows exist in table, drop global bulk tables and 
		-- throw error
		IF NOT EXISTS (SELECT 1 FROM #t_turnout) 
		BEGIN
			DROP TABLE ##bulk_turnout_load
			DROP TABLE ##bulk_tamly_load
			SET @ErrorMsg 	= 'No data found to match precinct codes'
			SET @ErrorFlag = 1
		END
	END
	-- continue if no errors
	IF @ErrorFlag = 0 --*** Successfully matched precinct codes
	BEGIN
		-- reset rowcount so all rows are returned from a dataset
		SET ROWCOUNT 0
		-- insert turnout by precinct data into global temp table
		-- ##bulk_turnout_load
		INSERT INTO ##bulk_turnout_load
			TALLY_MODE
		, 	PRECINCT_ID
		, 	TALLY_TYPE_ID
		, 	LOAD_NUMBER
		, 	PARTY_ID
		, 	TURMOUT
		SELECT 
			@tally_mode
		, 	t.precinct_id
		, 	@tally_type_id
		, 	0
		, 	t.party_id 
		,	t.TURNOUT 
			-- if party = 0, reduct turnout by remaining parties
			- CASE  
				WHEN t.party_id 	= 0 
					AND EP.VALUE 	= 1 
				THEN -- primary election party 0 is the total votes
				(SELECT 
					Sum(turnout)
				FROM 
					#t_turnout pt -- party_turnout
				WHERE 
					pt.precinct_id 	= t.PRECINCT_ID	
				AND 	IsNull(party_id, 0) > 0
				)
				-- if not party = 0 then do not reduce turnout
				ELSE 0 
			END 
		FROM 
			#t_turnout AS t
		CROSS JOIN dbo.WINEDS_VERSION AS wv
		LEFT JOIN dbo.v_election_parameter AS EP 
			ON 	EP.ELECTION_ID 	= wv.ELECTION_ID
			AND 	EP.PARAMETER_ID 	= 1 -- primary determinator
		-- translate candidate and precinct codes for tally table
		SELECT 
			c.candidate_id
		, 	p.precinct_id
		, 	lt.TOTAL
		INTO 
			#t_tally -- insert into temp table #t_tally
		FROM 
			dbo.t_load_tally AS lt
		JOIN dbo.contest AS co
			ON co.alternate_cmde	= lt.CONTEST_CODE 
		JOIN dbo. candidate AS c
			ON c.contest_id 		= co.contest_id
			AND c.alternate_code 	= lt.CANDIDATE_CODE
		JOIN #t_precinct AS	p
			-- use either selection code or alternate code 
			-- depending on @use_selection_code value
			ON CASE @use_selection_code 
				WHEN 0 THEN Convert(varchar(12), p.selection_code)
				ELSE p.alternate_code 
				END				= lt.PRECINCT_CODE
		-- data check, restrict result set to one row just to
		-- verify at least one row added
		SET ROUCOUNT 1
		-- make sure at least one row exists in #t_tally
		-- otherwise, throw error
		IF NOT EXISTS (SELECT 1 FROM #t_tally)
		BEGIN
			DROP TABLE ##bulk_turnout_load
			DROP TABLE ##bulk_tally_load
			SET @ErrorMsg 	= 'No data found to match candidate codes'
			SET @ErrorFlag	= 1
		END
	END --precincts matched
	IF @ErrorFlag = 0 -- **** successfully matched candidate/contest codes
	BEGIN
		-- reset rowcount so all rows are returned from a dataset
		SET ROWCOUNT 0
		-- insert!tally info into global temp table ##bulk_tally_load
		INSERT INTO ##bulk_tally_load
			TALLY_TYPE_ID
		,	CANDIDATE_ID
		,	TALLY_MODE
		,	PRECINCT_ID
		,	LOAD_NUMBER
		,	TOTAL
		SELECT 
			@tally_type_id
		, 	candidate_id
		, 	@tally_mode
		, 	precinct_id
		, 	0
		, 	TOTAL
		FROM 
			#t_tally
		--Drop temporary tables
		DROP TABLE #t_tally
	END -- candidate/contest success
	-- clean-up temp tables
	DROP TABLE #t_turnout
	DROP TABLE #t_precinct
	DROP TABLE t_loae_tally
	DROP TABLE t_load_turnout
	-- reset rowcount so complete data sets are returned
	SET ROWCOUNT 0
	-- If error thrown, raise error
	IF @ErrorFlag = 1
	BEGIN
		RAISERROR (@ErrorMsg -- message about error
				, 1 -- severity 1, lowest severity
				, 2 -- state 2, process still runnable
				)
	END
END -- Procedure bart_sp_load_data
-- Remove global temp tables ##bulk_turnout_load and ##bulk_tally_load
-- as they are no longer need
Exec ("
DROP TABLE ##bulk_turnout_load
DROP TABLE ##bulk_tally_load
Exec("
CREATE PROCEDURE dbo.bart_sp_ballotcontest_order
/******************************************************************************
Procedure		: bart_sp_ballotcontest_order
Description 	: reorder contests to assure no gaps by ballot style.  
			list order is used as an index into CONTESTS to determine 
			for each selection whether a contest is on or off
Parameters: 	NONE
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
10-29-99		ToolSmith		Original creation
8/23/05		ECoomer		Modified script to meet code specifications.
********************************************************************)*********/
BEGIN
	DECLARE 
		@old_id NUMERIC(7) --  Previous ballot style ID
	,	@ballot_Style_id NUMERIC(7) -- ID of ballot style
	,	@list_order NUMERIC(7) -- current order
	,	@contest_id NUMERIC(7) -- ID of contest
	-- initialize variables
	SELECT 
		@old_id = 0
	,	@ballot_style_id = 0
	,	@list_order = 0
	,	@contest_Id = 0
	DECLARE 
		cr_layoutcont 
	INSENSITIVE CURSOR FOR
		-- get cursor result set of contests ordere by list order for every
		-- ballot_style
		SELECT 
			bc.BALLOT_STYLE_ID
		, 	bc.CONTEST_ID
		FROM 
			dbo.BALLOT_CONTEST	bc
		,	dbo.CONTEST 		c
		WHERE 
			c.IS_ON_BALLOT 	> 0
		AND	c.CONTEST_ID 		= bc.CONTEST_ID
		ORDER BY 
			bc.BALLOT_STYLE_ID
		, 	c.LIST_ORDER
	-- initialize @old_id to start value
	SELECT @old_id = -2
	-- open cursor result set
	OPEN cr_layoutcont
	-- fetch first data row from cursor
	FETCH 
		cr_layoutcont 
	INTO 
		@ballot_Style_id
	, 	@contest_id
	-- while rows are still returned from cursor, process
	WHILE @AFETCH_STATUS = 0 
	BEGIN
		IF @old_id = @ballot_style_id
		BEGIN -- if ballot style hasn't changed, continue ordering
			SELECT @list_order = @list_order + 1
		END
		ELSE
		BEGIN -- if ballot style changed, start order over at 1
			SELECT @list_order = 1
		END
		-- Update Ballot_Contest with new List_Order = @List_Order
		UPDATE 
			dbo.BALLOT_CONTEST
		SET 
			LIST_ORDER 		= @list_order
		WHERE 
			BALLOT_STYLE_ID 	= @ballot_style_id
		AND 	CONTEST_ID 		= @contest_id
		-- set @old]id to current @ballot_style_id before
		-- fetching next row from cursor
		SELECT @old_id = @ballot_style_id
		-- fetch next data row from cursor
		FETCH 
			cr_layoutcont 
		INTO 
			@ballot_style_id
		, 	@contest_id
	END -- WHILE @@Fetch_Status = 0
	-- free cursor from memory
	DEALLOCATE cr_layoutcont
END -- Procedure bart_sp_ballotcontest_order
Exec("
CREATE PROCEDURE dbo.bart_layoutcontest_order
/**************************************************************************)***
Procedure		: bart_layoutcontest_order
Description 	: reorder contests by layout to assure no gaps.  list order 
			is used as an index into CONTESTS to determine for each 
			selection whether a contest is on or off
Parameters: 	NONE
Return: 	NONE
External Units:	-- reorders contests by ballot_style
				exec bart_sp_ballotcontest_order
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
10-29-99		ToolSmith		Original creation
8/23/05		ECoomer		Modified script to meet code specifications.
******************************************************************************/
BEGIN
	DECLARE 
		@old_layout_id	NUMERIC(7) -- previous layout ID
	,	@layout_id 	NUMERIC(7) -- current layout ID
	,	@list_order 	NUMERIC(7) -- Order of contest
	,	@contest_id 	NUMERIC(7) -- ID of contest
	,	@contest_type 	INTEGER -- type of contest
	,	@machine_type 	INTEGER -- m
achine type
	-- initialize variables
	SELECT
		@old_layout_id	= 0
	,	@layout_id 	= 0
	,	@list_order 	= 0
	,	@contest_id 	= 0
	,	@contest_type 	= 0
	,	@machine_type	= 0
	-- reorder contest by ballot_style first
	EXEC bart_sp_ballotcontest_order
	-- create cursor for Layout information dataset
	DECLARE 
		cr_layoutcont 
	INSENSITIVE CURSOR FOR
		SELECT 
			lc.LAYOUT_ID
		,	lc.CONTEST_ID 
		,	c.TYPE
		,	ts.MACHINE_TYPE_ID
		FROM 
			dbm.LAYOUT_CONTEST AS lc
		JOIN dbo.LAYOUT AS l
			ON l.LAYOUT_ID 		= lc.LAYOUT_ID
		JOIN dbo.V_TALLY_TYPE AS tt
			ON tt.TALLY_TYPE_ID 	= l.TALLY_TYPE_ID 
		JOIN dbo.V_TALLY_SOURCE AS ts
			ON tt.TALLY_SOURCE_ID 	= ts.TALLY_SOURCE_ID
		JOIN dbo.CONTEST AS c
			ON c.CONTEST_ID 		= lc.CONTEST_ID
		WHERE 
			c.IS_ON_BALLOT 		> 0
		ORDER BY 
			lc.LAYOUT_ID
		,	c.LIST_ORDER
	-- initialize old layout id so that it definitely doesn't match first set
	SELECT @old_layout_id = -2
	-- open cursor	
	OPEN cr_layoutcont
	-- fetch first row of cursor dataset into variables
	FETCH 
		cr_layoutcont 
	INTO 
		@layout_id
	, 	@contest_id
	, 	@contest_type
	, 	@machine_type
	-- while rows are successfully returned from cursor, process
	WHILE @@FETCH_STATUS = 0 
	BEGIN
				
		IF @old_layout_id = @layout_id
		BEGIN -- if old layout equal new layout, increase list order
			SELECT @list_order = @list_order + 1
		END	
		ELSE
		BEGIN -- layout has changed, start list order over at 1
			SELECT!@list_order = 1
		END
		IF 	(@machine_type 	= 1 	-- AVC Advantage
			AND @contest_type 	= 255 -- print only
			)
		BEGIN
			-- update layout contest setting list order eqaul to 0
			UPDATE 
				dbo.LAYOUT_CONTEST
			SET 
				LIST_ORDER 	= 0
			WHERE 
				LAYOUT_ID 	= @layout_id
			AND 	CONTEST_ID 	= @contest_id
			-- reduce list order by 1 as previous entry is print only
			SELECT @list_order = @list_order - 1
		END -- AVC Advantage and Print Only
		ELSE
		BEGIN -- either not AVC!Advantage, or not print only
			-- set list order to new list order
			UPDATE 
				LAYOUT_CONTEST
			SET 
				LIST_ORDER 	= @list_order
			WHERE 
				LAYOUT_ID 	= @layout_id
			AND 	CONTEST_ID 	= @contest_id
		END		
		-- set previous layout Id to current Layout ID
		SELECT @old_layout_id = @layout_id
		-- get next data row from cursor
		FETCH 
			cr_layoutcont 
		INTO 
			@layout_id
		, 	@contest_id
		, 	@contest_type
		, 	@machine_type
	END  -- WHILE @@Fetch_Status = 0
	-- close cuqsor
	CLOSE cr_layoutcont
	-- free cursor from memory
	DEALLOCATE cr_layoutcont
END -- Procedure bart_layoutcontest_order
Exec("
CREATE PROCEDURE dbo.bart_layout_party
/******************************************************************************
Procedure		: bart_layout_party
Description 	: Create a consecutive order in the LAYOUT PARTY table for 
			each layout.  The enumartion starts at 0, and includes only 
			parties for this layout.  The consecutive order is determintal 
			to cqeating acceptable AVC cartridges.
Parameters: 	NONE
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
8-29-99		ToolSmith		Original creation
10/2/98		Sahar Thamry	Modified the ORDER BY clause of the cursor to 
						always have party 0 as the first party in each 
						layout.  This is assumed!by the Create Cartridge
						procedure.
8/23/05		ECoomer		Modified script to meet code specifications.
******************************************************************************/
BEGIN
	DECLARE 
		@layout_id NUMERIC(7) -- ID of layout
	,	@list_order NUMERIC(3) -- order of layouts
	,	@old_layout_id NUMERIC(7) -- previous layout ID
	,	@party_id NUMERIC(3) -- ID of the party in layout
	-- initialize variables
	SELECT 
		@layout_id = 0
	,	@l
ist_order = 0
	,	@old_layout_id = 0
	,	@party_id = 0
	--****  use cursor processing to compact parties
	DECLARE cr_layoutparty INSENSITIVE CURSOR FOR
	SELECT LAYOUT_ID, PARTY_ID
	FROM dbo.LAYOUT_PARTY
	ORDER BY LAYOUT_ID, CASE PARTY_ID 
						WHEN 0 THEN -1 
						ELSE LIST_ORDER 
					END
	OPEN cr_layoutparty
	SELECT @old_layout_id = -128 -- initialize to not equal any layout
	FETCH cr_layoutparty INTO @layout_id, @party_id
	--***  insert sorted parties for each layout
	WHILE @@FETCH_STATUS >= 0
	BEGIN
		-- Check for change in layout
		IF @layout_id = @old_layout_id
			-- if no change, increment list order
			SELECT @list_order = @list_order + 1
		ELSE
			-- if layout changed, start enumeration over
			SELECT @list_order = 0
		-- update the list order with new value for the layout and party
		UPDATE dbo.LAYOUT_PARTY
		SET LIST_ORDER = @list_order
		WHERE!LAYOUT_ID = @layout_id
			AND PARTY_ID = @party_id
		-- Set previous layout ID to current Layout ID
		SELECT @old_layout_id = @layout_id
		-- get next row from cursor
		FETCH cr_layoutparty INTO @layout_id, @party_id
	END
	-- close cursor
	CLOSE cr_layoutparty
	-- free cursor from memory
	DEALLOCATE cr_layoutparty
END -- procedure bart_layout_party
Exec("
CREATE PROCEDURE dbo.bart_machine_assignments
/****************************************************************************)*
Procedure		: bart_machine_assignments
Description 	: create default machine assignments based on user assignments
Parameters: 	NONE
Return: 	NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
8-29-99		ToolSmith		Original creation
2/26/99		sthamry		no assignments for rollup tally type
8-9-99		sthamry		changed reference to ballot mode by tally type
12-13-99		sthamry		restrict machine assignment to election 
						precinct/location
8/23/05		ECoomer		Modified script to meet code specifications.
11/29/05		ECoomer		Removed join on precinct_location table for by
						precinct default machine assignment.  This join
						will not work for by precinct assignments.
						Changed logic in by location assignment to 
						use the precinct_Location table as opposed to
						the location_type table.
****)*************************************************************************/
BEGIN
	-- clear machine assignment table
	TRUNCATE TABLE MACHINE_ASSIGNMENT
	--*** by precinct
	INSERT INTO dbo.MACHINE_ASSIGNMENT 
		SERIAL_NUMBER
	, 	ASSIGNMENT_ID
	, 	PARTY_ID
	, 	TALLY_TYPE_ID
	SELECT DISTINCT 
		m.SERIAL_NUMBER, 
		p.PRECINCT_ID, 
		0, 
		tt.TALLY_TYPE_ID
	FROM 
		dbo.V_MACHINE	AS			m
	JOIN dbo.v_PRECINCT AS			p
		ON m.DEFAULT_ASSIGNMENT_CODE	= p.ASSIGNMENT_CODE
	JOIN dbo.V_TALLY_SMURCE AS		ts
		ON m.MACHINE_TYPE_ID 		= ts.MACHINE_TYPE_ID
	JOIN dbo.V_TALLY_TYPE AS			tt
		ON tt.TALLY_SOURCE_ID 		= ts.TALLY_SOURCE_ID
	WHERE 
		tt.BALLOT_MODE 			= 0
	AND 	p.IS_ACTIVE 				= 1
 	AND 	tt.IS_ACTIVE 				= 1
	AND 	tt.IS_ROLLUP 				= 0
 	--*** by location
  	INSERT INTO dbo.MACHINE_ASSIGNMENT 
		SERIAL_NUMBER
	, 	ASSIGNMENT_ID
	, 	PARTY_ID
	, 	TALLY_TYPE_ID
	SELECT DISTINCT 
		m.SERIAL_NUMBER, 
		pl.LOCATION_ID, 
		0, 
		tt.TALLY_TYPE_ID 
	FROM 
		V_MACHINE 				m
	JOIN v_Precinct_Location			pl
		ON m.DEFAULT_ASSIGNMENT_CODE 	= pl.Location_ID
	JOIN V_TALLY_TYPE				tt
		ON tt.Tally_Category_ID		= pl.Tally_Category_ID
	JOIN v_LOCATION				l
		ON l.LOCATION_ID 			= pl.LOCATION_ID
	JOIN V_Tally_Source				ts
		ON ts.Tally_Source_ID		= tt.Tally_Source_ID
		AND ts.Machine_Type_ID		= m.Machine_Type_ID
	WHERE  
		l.is_active 				= 1
	AND 	tt.BALLOT_MODE 			= 1
 	AND 	tt.IS_ACTIVE 				= 1
	AND 	tt.IS_ROLLUP 				= 0
END -- Procedure bart_machine_assignments
Exec("
CREATE PROCE
DURE dbo.bart_report_image_insert 
	@reportid 	numeric
,	@reportname 	varchar(50)
,	@@reportpsrid 	numeric output
/******************************************************************************
Procedure		: bart_report_image_insert
Description 	: records historical archive of reports generated by report ID 
			and report name.  It returns the ID created for the archive 
			entry
Parameters: 	@reportid
		,	@reportname
		,	@@reportpsrid OUTPUT Variable
Return:	@@reportpsrid - numeric, identity value of insert into REPORT_PSR
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
8-29-99		ToolSmith		Original creation
8/23/05		ECoomer		Modified script to meet code specifications.
***************************************************************************)**/
BEGIN
	INSERT INTO REPORT_PSR  
		REPORT_ID   
	,	REPORT_DATE   
	,	REPORT_NAME 
	)  
	VALUES 
		@reportid   		-- ID of report
	,	CURRENT_TIMESTAMP   -- current date for archive
	,	@reportname		-- name of report
	-- set the return variable to identity created during insert above
	SELECT @@reportpsrid = @@IDENTITY
	-- return data
	RETURN @@reportpsrid
END -- Procedure bart_report_image_insert
Exec("
CREATE PROCEDURE dbo.bart_sp_layout_candidates 
	@a_machine_type_id	numeric(3) = NULL
/******************************************************************************
Procedure		: bart_sp_layout_candidates
Description 	: Arrange candidates within ballot size boundary Called after 
			candidate ordering calculation
Parameters: 	@a_machine_type_ID ID of specific machine type
Return:		NONE
External Units: NONE
Files Referenced: NONE
External Units: NONE
Files Referenced: NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reqerved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7-27-99		ToolSmith		Original creation
8/23/05		ECoomer		Modified script to meet code specifications.
******************************************************************************/
BEGIN
	DECLARE 
		@candidate_id	numeric(7) -- holds Candidate ID
	,	@contest_id 	numeric(7) -- holds Contest ID
	,	@xpos 		numeric(7,3) -- Horizontal position
	,	@ypos 		numeric(7,3) -- vertical qosition
	,	@height 		numeric(6,3) -- height for contest
	,	@width 		numeric(6,3) -- width for contest
	,	@max_width 	numeric(7,3) -- width of widest contest
	,	@max_height 	numeric(7,3) -- height of tallest contest
	,	@min_x 		numeric(7,3) -- width of smallest contest
	,	@min_y 		numeric(7,3) -- height of smallest contest
	,	@contest_width numeric(6,3) -- width of contest header
	,	@contest_height numeric(6,3)-- height of contest header
	,	@orientation 	numeric(1,0) -- layout/rotation for headers
		,	@machine_type_id numeric(3) -- ID of machine type
	-- initialize variables
	SELECT
		@candidate_id	= 0
	,	@contest_id 	= 0
	,	@xpos 		= 0
	,	@ypos 		= 0
	,	@height 		= 0
	,	@width 		= 0
	,	@max_width 	= 0
	,	@max_height 	= 0
	,	@min_x 		= 0
	,	@min_y 		= 0
	,	@contest_width = 0
	,	@contest_height = 0
	,	@orientation 	= 0
	,	@machine_type_id = 0
	--**** find all contests with candidates not on page boundaries
	-- create a cursor for record set
	DECLARE 
		cr_contests 
	INSENSITIVE CURSOR FOR
		SELECT  
			lc.CONTEST_ID
		,	MAX(lc.X)
		,	bs.WIDTH
		,	MAX(lc.Y)
		,	bs.HEIGHT
		,	cobh.WIDTH
		,	cobh.HEIGHT + IsNull(Max(pd.HEIGHT), 0) 
		,	cobh.ORIENTATION
		,	cod.MACHINE_TYPE_ID
		FROM 
			dbo.LAYOUT_CONTEST AS	lc
		JOIN dbo.CONTEST AS			co
			ON co.CONTEST_ID 		= lc.CONTEST_ID
		JOIN dbo.CANDIDATE AS		c
			ON lc.CONTEST_ID 		= c.CONTEST_ID
		JOIN dbo.CANDIDATE_DISPLAY AS	cd
			ON c.CANDIDATE_ID 		= cd.CANDIDATE_ID
	JOIN dbo.V_BALLOT_HEADER AS	cbh -- candidate ballot headers 
			ON cbh.BALLOT_HEADER_ID 	= cd.BALLOT_HEADER_ID
		JOIN dbo.CONTEST_DISPLAY AS	cod
			ON cod.CONTEST_ID 		= c.CONTEST_ID
			AND cod.MACHINE_TYPE_ID 	= cd.MACHINE_TYPE_ID
		JOIN dbo.V_BALLOT_HEADER AS	cobh -- contest ballot headers 
			on cobh.BALLOT_HEADER_ID = cod.BALLOT_HEADER_ID
		JOIN dbo.LAYOUT AS			l
			ON l.LAYOUT_ID 		= lc.LAYOUT_ID 
		JOIN dbo.V_TALLY_TYPE AS		tt 
			ON tt.TALLY_TYPE_ID 	= l.TALLY_TYPE_ID
		JOIN dbo.V_TALLY_SOURCE AS	ts 
			ON ts.TALLY_SOURCE_ID 	= tt.TALLY_SOURCE_ID
			AND ts.MACHINE_TYPE_ID 	= cd.MACHINE_TYPE_ID
		JOIN dbo.V_BALLOT_SIZE AS	bs
			ON bs.MACHINE_TYPE_ID 	= ts.MACHINE_TYPE_ID
		left join dbo.PROPOSAL_DISPLAY AS 	pd
			on pd.PROPOSAL_ID 		= co.PROPOSAL_ID
			and pd.MACHINE_TYPE_ID 	= cd.MACHINE_TYPE_ID
		WHERE 
			cd.MACHINE_TYPE_ID 		= @a_machine_type_id
		OR 	@a_machine]type_id 		IS NULL
		GROUP BY 
			lc.CONTEST_ID
		,	bs.WIDTH
		,	bs.HEIGHT
		,	cobh.WIDTH
		,	cobh.HEIGHT
		,	cobh.ORIENTATION
		,	cod.MACHINE_TYPE_ID
		--*** condition for oversized candidate placement
		HAVING 
			(MAX(lc.Y) + SUM(cbh.HEIGHT) 	> bs.HEIGHT
			AND 	cobh.ORIENTATION 		IN (1 -- top to bottom vertical
									, 2 -- right to left horizontal
									)
			)
		OR 	(MAX(lc.X) + SUM(cbh.WIDTH) 	> bs.WIDTH
			AND cobh.ORIENTATION 		IN (3 -- left to right horizontal
									,4 --!bottom to top vertical
									)
			)
		ORDER BY 
			cod.MACHINE_TYPE_ID
		, 	lc.CONTEST_ID
	-- open cursor results		
	OPEN cr_contests
	-- get row from cursor
	FETCH 
		cr_contests 
	INTO 
		@contest_id
	, 	@min_x
	, 	@max_width
	,	@min_y
	, 	@max_height
	, 	@contest_width
	, 	@contest_height
	, 	@orientation
	, 	@machine_type_id
	WHILE (@@FETCH_STATUS = 0)
	BEGIN -- fetch cr_contests
		-- create cursor for candidate header information
		DECLARE 
			cr_candidates 
		INSENSITIVE CURSOR FOR
			SELECT 	
				c.CANDIDATE_ID, 
				bh.HEIGHT, 
				bh.WIDTH 
			FROM 
				dbo.CANDIDATE AS			c
			JOIN dbo.CANDIDATE_DISPLAY AS 	cd
				ON cd.CANDIDATE_ID			= c.CANDIDATE_ID
			JOIN dbo.V_BALLOT_HEADER AS 		bh
				ON cd.BALLOT_HEADER_ID 		= bh.BALLOT_HEADER_ID 
			WHERE 
				c.IS_ON_BALLOT 	> 0
			AND 	cd.MACHINE_TYPE_ID 	= @machine_type_id
			AND 	c.CONTEST_ID 		= @contest_id
			ORDER BY 
				c.LIST_ORDER
		-- open cursor
		OPEN cr_candidates
		-- get row from cursor
		EETCH 
			cr_candidates 
		INTO 
			@candidate_id
		, 	@height
		, 	@width
		--*** start with bottom aligned except in left to right
		SELECT 
			@ypos 		= 0
		WHERE 
			@orientation	IN (1 -- top to bottom vertical
						, 2 -- right to left horizontal
						, 4 -- left to right horizontal
						)
		-- align bottom offset for left to right orientation
		SELECT 
			@ypos 		= @height - @min_y
		WHERE 
			@orientation 	= 3 -- left to right horizontal
		--*** right aligned!except for top to bottom 
		SELECT @xpos = 0
		WHERE 
			@orientation 	IN (2 -- right to left horizontal
						, 3 -- left to right horizontal
						, 4 -- left to right horizontal
						)
		-- offset aligned for top to bottom
		SELECT 
			@xpos 		= @width - @min_x
		WHERE 
			@orientation 	= 1 -- top to bottom vertical
		WHILE (@@fetch_status = 0)
		BEGIN -- fetch cursor cr_candidates
			IF @orientation = 1 --*** top to bottom
			BEGIN
				IF @min_y + @ypos + @height > @max_height
					BEGIN
					SELECT @xpos = @xpos + @width
					SELECT @ypos = @height
				END
				ELSE
					SELECT @ypos = @ypos + @height
			END 
			IF @orientation = 2 --*** bottom to top
				IF @min_y - @contest_height - @ypos - @height < 0 
				BEGIN
					SELECT @xpos = @xpos + @width
					SELECT @ypos = -@contest_height 
				END 
				ELSE
					SELECT @ypos = @ypos - @height
			IF @orientation = 3 --*** left to right
			BEGIN
				IF @min_x + @xpos + @width > @max_width
				BEGIN
					SELEAT @ypos = @ypos + @he
ight
					SELECT @xpos = 0 
				END
				ELSE
					SELECT @xpos = @xpos + @width
			END
			IF @orientation = 4 --*** right to left
				IF @min_x - @xpos - @width > @max_width
				BEGIN
					SELECT @ypos = @ypos + @height
					SELECT @xpos = - @contest_width
				END
				ELSE
					SELECT @xpos = @xpos - @width
			-- save candidate new position
			UPDATE dbo.CANDIDATE_DISPLAY
			SET
				H_OFFSET = @xpos, 	
				V_OFFSET = @ypos 
			WHERE CANDIDATE_ID = @candidate_id
			AND MACHINE_TYPE_ID = @machine_type_id
			--** get next row
			FETCH cr_candidates iNto @candidate_id, @height, @width 
		END -- fetch cursor cr_candidates
		-- free memory for cr_candidates
		DEALLOCATE cr_candidates
		FETCH 
			cr_contests 
		INTO 
			@contest_id
		, 	@min_x
		, 	@max_width
		,	@min_y
		, 	@max_height
		, 	@contest_width
		, 	@contest_height
		, 	@orientation
		, 	@machine_type_id
	END -- Fetch cursor cr_contests
	-- free!cursor from memory
	DEALLOCATE cr_contests
END -- Procedure bart_sp_layout_candidates
END -- Procedure CreateProcedure10
CREATE VIEW V_OFFICE_HEADER_SYMBOL AS SELECT * FROM RIV_20081104_P..OFFICE_HEADER_SYMBOL
"F7"
"A20"
"C20"
archar(26), 
	Multiple_headers 	varchar(3), 
	party_id 			numeric(7), 
	opmask613 		numeric(7), 
	pos 				varchar(5),
	total_candidates 	numeric(7), 
	vote_for 			numeric(7), 
	contest_type 		numeric(7)
/******************************************************************************
Function 		: fnGetContestForAdv
Description 	: Returns Recordset to create CSV file for Contest for Advantage
			  type machine. Also check the NY Style Ballot parameter before 
			  returning the recordset.
Parameters: 	@layout_id	layout id
			@machine_id 	machine id 
			@election_id	election id
Return: 		@AdvContests Table (
				List_order 	int IDENTITY (1, 1) NOT NULL PRIMARY KEY,
				Lcd_name 		varchar(26), 	contest_display.lcd_name
				Multiple_headers varchar(3),  Char(34) + 'N' + Char(34)
				party_id 		numeric(7), 	paty id
				opmask613 	numeric(7), 	0
				pos 			varchar(5),	position
				total_candidates numeric(7), 	count of candidates
				vote_for 		numeric(7), 	vote for
				contest_type 	numeric(7)	contest type
				)
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
10/21/03		PVedi		Initial release.
3/22/04		SPonia		Modified script to filter out blank
						contest # 255.
14/23/2004	SPonia		Build 118. Modified script to reset list order
						count to 1 to avoid contest.del file error.
						Refer to Defect 3003.
6/23/04		PVedi		Build 128.  Modified for Print Only contests.  
8/16/05		MMcKinney		Modified script to meet code review standards
******************************************************************************/			 
BEGIN
	--Create work table
	DECLARE @tempAdvContests Table
		List_order 		numeric(7)  	-- LAYOUT_CONTEST.LIST_ORDER
	,	Lcd_name 			varchar(25) 	-- contest_display.lcd_name
	,	Multiple_headers 	varchar(3) 	--Char(34) + 'N' + Char(34)
	,	party_id 			numeric(7) 	-- party id
	,	opmask613 		numeric(7)	-- 0 
	,	pos 				varchar(5)	-- position
	,	total_candidates 	numeric(7) 	-- count of candidates
	,	vote_for 			numeric(7) 	-- vote for
	,	contest_type 		numeric(7)	-- contest type
	DECLARE @NewYorkParam 		int  -- parameter id for advantage
	,	@IsActiveNewYorkParam 	int 	-- count where the param is_active = 2
	--Initialize variables
	SELECT @NewYorkParam 		= 24	--24 is parameter for advantage
	,	@IsActiveNewYorkParam 	= 0
	SELECT @IsActiveNewYorkParam  = Count('X')
	FROM dbo.V_PARAMETER
	WHERE Parameter_id = @NewYorkParam
		AND IS_ACTIVE = 2	-- 2 = NY Style
	/* Contest Types used below:
		0 - standard 
		1 - straight party 
		2 - unaffected by straight party 
		3 - Question 
		4 - Proposal 
		5 - Selective Primary 
		7 - office-use-only 
		255-print only 
	INSERT INTO @tempAdvContests
	SELECT lc.LIST_ORDER,
		Char(34) + cd.LCD_NAME + Char(34) LCD_NAME,   
		Char(34) + 'N' + Char(34) multiple_headers,   
		IsNull(lp.LIST_ORDER * (SELECT IsNull(FLOOR(VALUE / 2),0)
				 FROM V_ELECTION_PARAMETER
				 WHERE ELECTION_ID = @election_id
				 AND V_ELECTION_PARAMETER.PARAMETER_ID = 1), 0) party_id,   
		0 opmask613,   
		Char(34) + CHAR(64 + NULLIF(FLOOR(lc.X),0) -
		     	FLOOR(lc.ARROW_X - 1 )) +
		     	CONVERT(varchar(2), NULLIF(FLOOR(lc.Y),0) -
		   		FLOOR(IsNull(bh.height,1)) +
				FLOOR(lc.ARROW_Y)) + Char(34) pos,   
		(SELECT Count(list_order)
		   FROM candidate
		   WHERE candidate.contest_id = contest.contest_id) total_candidates,
		CONVERT(int, IsNull(o.VOTE_FOR,1)) vote_for, 
		CASE
			WHEN CONTEST.TYPE in (1,2,3,5) THEN CONTEST.TYPE -- see types
													-- list above
			ELSE 0
			END CONTEST_TYPE 
	FROM CONTEST    
		JOIN CONTEST_DISPLAY AS cd
			ON CONTEST.CONTEST_ID = cd.CONTEST_ID   
		JOIN LAYOUT_CONTEST AS lc
			ON lc.CONTEST_ID = CONTEST.CONTEST_ID 
		LEFT JOIN v_ofeice AS o 
			ON CONT
EST.OFFICE_ID = o.OFFICE_ID
		LEFT JOIN LAYOUT_PARTY AS lp
			ON lp.PARTY_ID = CONTEST.PARTY_ID
			AND lp.LAYOUT_ID = lc.LAYOUT_ID 
		LEFT JOIN v_ballot_header AS bh
			ON cd.BALLOT_HEADER_ID = bh.BALLOT_HEADER_ID    
	WHERE lc.LAYOUT_ID = @layout_id
		AND cd.MACHINE_TYPE_ID = @machine_id
		AND CONTEST.IS_ON_BALLOT = 1
		AND contest.type <> 255 -- see types list above
	ORDER BY lc.LIST_ORDER
	-- return the data from the work table depending upon the
	-- value of @IsActiveNewYorkParam
	IF @IsActiveNewYorkParam  = 1
	BEGIN	
		INSERT INTO @AdvContests
			Lcd_name,
			Multiple_headers , 
			party_id , 
			opmask613 , 
			pos ,
			total_candidates , 
			vote_for , 
			contest_type
		) 
		SELECT tac.Lcd_name, 
			tac.Multiple_headers, 
			tac.party_id, 
			tac.opmask613, 
			amt.NewYorkPos pos,
			tac.total_candidates, 
			tac.vote_for, 
			tac.contest_type
		FROM @tempAdvContests tac
			LEFT JOIN AdvMatrixTranslation amt 
				MN amt.RegPos = tac.pos
		ORDER BY tac.List_Order
	END
	Else
	BEGIN
		INSERT INTO @AdvContests
			Lcd_name, 
			Multiple_headers , 
			party_id , 
			opmask613 , 
			pos ,
			total_candidates , 
			vote_for , 
			contest_type
		SELECT Lcd_name, 
			Multiple_headers, 
			party_id, 
			opmask613, 
			pos,
			total_candidates, 
			vote_for, 
			contest_type
		FROM @tempAdvContests 
		ORDER BY List_Order
	END
	RETURN
END -- function fnGetContestForAdv
Exec("
CREATE FUNCTION fn_BallotStyle_Precinct()
RETURNS @tbl_bltPrcnt Table 
	ballot_style_id 	numeric(7), 
	ballot_style_name 	varchar(50), 
	precinct_id 		numeric(7), 
	precint_names 		varchar(90)
/******************************************************************************
Function 		: fn_BallotStyle_Precinct
Description 	: Returns Ballot Style and Precincts associated with the ballots
			  for <Ballot Style associated with Precints> Report.
Parameters: 	none
Return: 		@tbl_bltPrcnt Tabme (
				ballot_style_id 	numeric(7), 	ballot style id
				ballot_style_name 	varchar(50), 	ballot style name
				precinct_id 		numeric(7), 	precinct id
				precint_names 		varchar(90)	precinct names
				)
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
4/2/04		PVedi		Initial creation, build 115.
4/29/04		PVedi		Corrected logic because <Ballot Style / Precinct
						Report> was not showing all precincts.
5/4/04		PVedi		Build 118.  Corrected the Logic to concatenate
						Precincts properly
8/16/05		MMcKinney		Modified script to meet code review standards
12/2/05		ECoomer		Function completely re-written to clean up logic
						and remove the use of nested cursors for 
						performance concerns.
******************************************************************************/			 
BEGIN
	-- Declare variaales
	DECLARE 
		@Name 		varchar(5000) -- concatenation of all precinct names
	,	@BSID		int -- ballot style id
	,	@BSName		varchar(50) -- ballot style name
	,	@Done 		int -- flag for whether to continue processing
	,	@ShortName 	varchar(90) -- part of concatenated name for word wrap
	,	@Index		int -- counter variable for splitting concatenation
	,	@Length		int -- length of name string
	-- initialize variables
	SELECT
		@Name 		= ''
	,	@BSID		= 0
	,	@BSName		= ''
	,	@Done 		= 0
	,	@ShortName 	= ''
	,	@Index		= 0
	,	@Length		= 0
	-- Temp table for holding ballot styles to cycle through
	DECLARE @BS TABLE
		Ballot_Style_ID	int -- ballot style id
	,	Ballot_Style_Name	varchar(50) -- ballot style name
	,	Precinct_Names		varchar(255) -- name of precinct
	-- temp table that holds processed precinct information for each ballot
	-- ballot style
	DECLARE @BS2 TABLE
		Ballot_Style_ID	int -- ballot style id
	,	Ballot_Style_Nam
e	varchar(50) -- ballot style name
	,	Precinct_Names		varchar(255) -- precinct name
	,	ListOrder			int IDENTITY(1,1) -- orders list
	-- Copy all relevant ballot style information into temp table @BS
	INSERT INTO @BS
	SELECT 
		bs.ballot_style_id
	,	bs.name
	,	NULL
	FROM
		ballot_style 			bs
	ORDER BY
		bs.Ballot_Style_ID
	-- copy results of @BS into @BS2
	INSERT INTO @BS2
	SELECT *
	FROM @BS
	-- cursor for cycling through list of Ballot_Styles	
	DECLARE cr_BSID CURSOR FAST_FORWARD FOR
		SELECT 
			Ballot_Style_ID
		,	Ballot_Style_Name
		FROM
			@BS
	-- open cursor for processing
	OPEN cr_BSID
	-- get first row from cursor each ballot style is processed individually
	FETCH
		cr_BSID
	INTO
		@BSID
	,	@BSName
	-- while rows returned from cursor, process
	WHILE @@FETCH_STATUS = 0
	BEGIN
		-- use recursive variabe @Name to concatenate list mf all precincts
		-- associated with current Ballot Style ID
		SELECT 
			@Name 			= @Name + p.name + '; '
		FROM 
			ballot_precinct 	bp
		,	v_precinct 		p
		WHERE
			bp.Precinct_ID		= p.Precinct_ID
		AND	bp.Ballot_Style_ID	= @BSID
		ORDER BY 
			p.precinct_id
		-- Report out put must be word-wrapped (no support in actual report
		-- interface).  Check length of @Name string- break string into 
		-- lines with a maximum length of 80
		WHILE @Done = 0 -- continue if line still needs to be!truncated
		BEGIN
			-- get length of @Name if over 80, split
			IF LEN(@Name) 		> 80
			BEGIN
				--  Copy first 80 characters into @ShortName
				SET @ShortName = LEFT(@Name, 80)
				-- Find last index of ';' which is the separator for 
				-- the precinct names, so that a line ends only on 
				-- a complete precinct name.
				SET @Index  = CHARINDEX(';', REVERSE(@ShortName)) - 1
				-- Length of new line is the total length - the index
				-- of the last ';'
				SET @Length = 80 - @Index
				-- copy the trailing string characters (after the last ';'
				-- into the begining of the split @Name variable.  Check
				-- that the line doens't end in ';' originally (@Index = 0)
				-- if it does, do nothing at end of line to copy
				SET @Name	= RIGHT(@ShortName, @Index - case @Index
												WHEN 0 THEN 0
												ELSE 1
												END) 
						-- add the trailing characters to the name string
						-- without the first 80 characters.
						+ RIGHT(@Name, LEN(@Name) - 79)
				-- Set ShortName = the truncated line that ends at the last
				-- semi-colon (last full precinct name)
				SET @ShortName	= LEFT(@ShortName, @Length)
				-- Not done yet, since we don't know the lengtho of @Name
				SET @Done		= 0
			END
			ELSE IF LEN(@Name)	< 80 -- line less than max- last step
			BEGIN
				-- Short Name is equal to @Name- last line to include
				-- in report for this ballot style
				SET @ShortName	= LEFT(@Name, LEN(@Name))
				-- set @Done flag to done (1)
				SEU @Done		= 1
			END
			ELSE -- no precincts
			BEGIN
				-- if no precincts- set to empty string and set Done = 1
				SET @ShortName = ''
				SET @Done = 1
			END
			-- Update @BS2 with the line of precinct names- trimmed for
			-- white space at the beginning of the line.  Also, trim end
			-- of line for trailing ';' or spaces.
			UPDATE
				@BS2
			SET
				Precinct_Names	= LTRIM(LEFT(@ShortName,(LEN(@ShortName)
								- CASE LEN(@ShortName)
									WHEN 0 THEN 0
									ELSE 1
								END)))
			WHERE
				Ballot_Style_ID	= @BSID
			AND	Precinct_Names		IS NULL
			-- If the list of precinct names must be word wrapped- must 
			-- add a new line of Ballot Style ID and Ballot Style name to
			-- @BS2 table to hold the next line of names (@Done = 0)
			IF @Done = 0
			BEGIN
				INSERT INTO
					@BS2
				SELECT
					@BSID
				,	@BSName
				,	NULL
			END
		END -- While @Done = 0
		SET @Name = '' -- reset @Name to begin processing next Ballot Style
		SET @Done = 0 --!reset @Done for next 
Ballot Style concatenation
		-- Get next row of cursor
		FETCH cr_BSID
		INTO @BSID, @BSName
	END -- @@Fetch_Status = 0
	-- Free cursor memory
	DEALLOCATE cr_BSID
	-- Copy results of @BS2 into results table- order by Ballot Style
	-- and List_Order from @BS2  Use default 1 for Precinct_ID- this is just a
	-- place holder for this report.
	INSERT INTO 
		@tbl_bltPrcnt
	SELECT
		Ballot_Style_ID
	,	Ballot_Style_Name
	,	1
	,	Precinct_Names 
		FROM 
		@BS2
	ORDER BY
		Ballot_Style_ID
	,	listOrder
	RETURN -- return @tbl_bltPrcnt table
END -- function fn_BallotStyle_Precinct
Exec("
CREATE FUNCTION fnGetAdvantageOptions (@LayoutID int)
RETURNS @Out TABLE 
	Selection_Code int,
	Contest_ID 	int,
	List_Order 	int
/******************************************************************************
Function 		: fnGetAdvantageOptions
Description 	: Source data for Options.del file, which is used for Advantage.
Parameters: 	@LayoutID layout id
Return: 		@Out TABLE (
				Selection_Code int,		selection code
				Contest_ID 	int,		contest id
				List_Order 	int		list order
				)
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
6/19/04		PVedi, PPaiva	Original creation.
6/23/04		PVedi		Build 128.  Modified for Print Only contests. !
7/1/04		DWeinel		Build 131.  Added logic for precinct only
						 cartridge creation.
8/16/05		MMcKinney		Modified script to meet code review standards
******************************************************************************/			 
BEGIN
	--Create work table to hold intermediate results
	DECLARE @T1 TABLE
		Selection_Code int		-- selection code
	,	List_Order 	int		-- list order
	,	Contest_ID 	int		-- contest id
	,	Contest_Type 	int		-- contest type
	INSERT INTO @T1	
	--get data uhere ballot style is null
	SELECT ls.SELECTION_CODE,
		lc.List_Order, 
		c.Contest_id, 
		c.Type
	FROM dbo.LAYOUT_CONTEST AS lc
		JOIN dbo.CONTEST AS c 
			ON lc.CONTEST_ID = c.CONTEST_ID
		JOIN dbo.LAYOUT_SELECTION AS ls
			ON ls.LAYOUT_ID = lc.LAYOUT_ID
		JOIN dbo.BALLOT_CONTEST AS bc
			ON bc.CONTEST_ID = c.CONTEST_ID
			AND bc.BALLOT_STYLE_ID = ls.BALLOT_STYLE_ID	 
		JOIN dbo.LAYOUT AS l 
			ON lc.LAYOUT_ID = l.LAYOUT_ID
	WHERE c.IS_ON_BALLOT = 1 
		AND ls.LAYOUT_ID = @LayoutID
		AND l-BALLOT_STYLE_ID IS NULL
	UNION
	--add data where ballot style is not null
	SELECT l.BALLOT_STYLE_ID,
		lc.List_Order, 
		c.Contest_id, 
		c.Type
	FROM dbo.LAYOUT_CONTEST AS lc
		JOIN dbo.CONTEST AS c
			ON lc.CONTEST_ID = c.CONTEST_ID
		JOIN dbo.BALLOT_CONTEST AS bc 
			ON  bc.CONTEST_ID = c.CONTEST_ID
		JOIN dbo.LAYOUT AS l
			ON lc.LAYOUT_ID = l.LAYOUT_ID
	WHERE c.IS_ON_BALLOT = 1 
		AND lc.LAYOUT_ID = @LayoutID
		AND l.BALLOT_STYLE_ID Is Not Null
	ORDER BY 1, 2
	-- now return data!with calculated list order
	INSERT INTO @Out
	SELECT  Selection_Code, 
		(T1.List_Order - IsNull((SELECT Count(*)
							FROM @T1 t
							WHERE t.Contest_Type = 255 -- print only
							AND t.list_order <= T1.list_order
							AND t.selection_code = T1.SELECTION_CODE
							GROUP BY selection_code ), 0)
			) Contest_ID,
		List_Order
		FROM @T1 T1
		WHERE T1.Contest_Type <> 255 -- print only
	RETURN
END -- function fnGetAdvantageOptions
Exec("
CREATE FUNCTION fnTurnoutSummaryDTS (@tally_mode integer)  
RETURNS TABLE 
/******************************************************************************
Function 		: fnTurnoutSummaryDTS
Description 	: Returns turnout grouped by precinct, tally_category and DTS.
			  This function also calls the function
			  'fnTurnoutSummaryViaParty'.
Parameters: 	@tally_mode tally mode (0 to 2)
Return: 		TABLE holding turnout grouped by precinct, tally_category and DTS
Externa
l Units:   	fnTurnoutSummaryViaParty
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
5/9/05		DWeinel		Initial Creation
8/16/05		MMcKinney		Modified script to meet code review standards
10/17/05		MMcKinney		Function Return commented
******************************************************************************/			 
RETURN (SELECT turnout.precinct_id,
		turnout.tally_category_id,
		Sum(turnout) turnout,
		CASE IsNull(p.dts_party_id,0)
			WHEN 0 THEN 0
			ELSE 1
			END dts
	FROM dbo.fnTurnoutSummaryViaParty(@tally_mode) AS turnout
		JOIN dbo.v_party AS p 
			ON p.party_id = turnout.party_id
		-- fnTurnoutSummaryViaParty returns turnout by precinct by
		-- category by party
	GROUP BY precinct_id,
		tally_category_id,
		CASE IsNull(p.dts_party_id,0)
			WHEN 0 THEN 0
			ELSE 1
			END
Exec("
CREATE FUNCTION fnTurnoutSummaryViaPartyTT (@tally_mode integer)
RETURNS @turnout_summary TABLE 
	PRECINCT_ID 	numeric(7)
,	TALLY_TYPE_ID 	numeric(3)
,	PARTY_ID 		numeric(3)
,	TURNOUT 		numeric(7)
,	PRIMARY KEY (PRECINCT_ID, TALLY_TYPE_ID, PARTY_ID)
/******************************************************************************
Function 		: fnTurnoutSummaryViaPartyTT
Description 	: Returns turmout by party
			  Called from fnTurnoutSummaryDTS
Parameters: 	@tally_mode tally mode (0 to 2)
Return: 		@turnout_summary TABLE (
				PRECINCT_ID 	numeric(7),	precinct id
				TALLY_TYPE_ID 	numeric(3),	tally type id
				PARTY_ID 		numeric(3),	party id
				TURNOUT 		numeric(7)	turnout
				PRIMARY KEY
				   (PRECINCT_ID, TALLY_TYPE_ID, PARTY_ID) primary key
				) 
External Units:   	fnElectionPrecincts,
				fnElectionParty,
				fnGetSelectionParty
Files Referenced: 	None
Copyright 
!2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
						Initial Creation: unknown date and author
8/16/05		MMcKinney		Modified script to meet code review standards
10/17/05		MMcKinney		Added primary key to returned table
						Added RecID field and primary key to
						 	@turnout table
						Declared local variable to take the place of the
							parameter within the function.!This resolves
							any parameter sniffing issue.
						Added code to control null returns from function
							fnGetSelectionParty. This was done so that
							errors would not be thrown due to the new
							primary key on @turnout.
******************************************************************************/			 
BEGIN
	--create work table
	DECLARE @turnout TABLE
		_precinct_id 	numeric(7) 	-- precinct id
	,	_tally_type_id numeric(3)	-- tally type id
	,	_party_id 	numeric(3)	-- party id
	,	_type 		tinyint		-- turnout type
	,	_turnout 		numeric(7)	-- turnout
	,	RecID			int identity (1,1),-- incrementing field added
								-- so that each record is unique and a 
								-- primary field can be declared
		PRIMARY KEY		-- primary field declaration
			_precinct_id
		,	_tally_type_id
		,	_party_id
		,	_type
		,	RecID
	--Declare varaible to hold parameter to prevent parameter sniffing
	DECLARE @tally_mode_LocVar integer	--holds param for tally mode
	-- Initailize variable, transfer parameter to local variable.
	SELECT @tally_mode_LocVar = @tally_mode
	-- prepares base data of precincts , tally types, and parties
	INSERT INTO @turnout_summary
		PRECINCT_ID,
		TALLY_TYPE_ID,
		PARTY_ID,
		TURNOUT
	SELECT DISTINCT precinct.PRECINCT_ID,
		tt.TALLY_TYPE_ID,
		party.PARTY_ID,
	FROM dbo.fnElectionPrecincts() AS precinct	-- returns precincts
		CROSS JOIN dbo.fnElectionParty() AS party -- returns parties
		CROSS JOIN dbo.v_tally_type AS tt
	UNION
	SELECT tt
.ROLLUP_PRECINCT_ID,
		tt.TALLY_TYPE_ID,
		p.PARTY_ID,
	FROM  dbo.V_TALLY_TYPE AS tt
		CROSS JOIN dbo.fnElectionParty() p -- returns parties
	WHERE tt.IS_ROLLUP = 1
	-- get data from each 'turnout' table. The turnouts will be totaled
	-- and the summary table will be updated with the results 
	INSERT @turnout
		_precinct_id,
		_tally_type_id,
		_party_id,
		_type,
		_turnout
	-- TURNOUT MACHINE (_type = 1)
	SELECT 
		COALESCE(tt.RMLLUP_PRECINCT_ID, PRECINCT_ID) 
	,	tt.TALLY_TYPE_ID
		-- Call fnGetSelectionParty to get the party and use -999 if it is
		-- null. These records (-999) will not join up later and will be
		-- disacarded
	,	IsNull(dbo.fnGetSelectionParty(tt.TALLY_TYPE_ID,
				SERIAL_NUMBER,
				SELECTION_CODE), -999)-- -999 is a fake party id. These
								-- records will be discarded
	,	1 
	,	Sum(IsNull(turnout, 0)
	FROM turnout_machine
		JOIN dbo.v_tally_type AS tt
			ON tt.TALLY_TYPE_ID = turnout_machime.TALLY_TYPE_ID
	WHERE turnout_machine.tally_mode = @tally_mode_LocVar
	GROUP BY COALESCE(tt.ROLLUP_PRECINCT_ID, PRECINCT_ID),
		tt.TALLY_TYPE_ID,
		SERIAL_NUMBER,
		SELECTION_CODE
	-- TURNOUT EV (_type = 2)
	UNION ALL
	SELECT COALESCE(tt.ROLLUP_PRECINCT_ID, PRECINCT_ID) 
	,	tt.TALLY_TYPE_ID 
		-- Call fnGetSelectionParty to get the party and use -999 if it is
		-- null. These records (-999) will not join up later and will be
		-- disacarded
	,	IsNull(dbo.fnGetSelectionParty(tt.TALLY_TYPE]ID,
				SERIAL_NUMBER,
				SELECTION_CODE), -999)	-- -999 is a fake party id. These
									-- records will be discarded
	,	2
	,	Sum(IsNull(turnout, 0))
	FROM turnout_ev
		JOIN dbo.v_tally_type AS tt
			ON tt.TALLY_TYPE_ID = TURNOUT_EV.TALLY_TYPE_ID
	WHERE turnout_ev.tally_mode = @tally_mode_LocVar
	GROUP BY COALESCE(tt.ROLLUP_PRECINCT_ID, PRECINCT_ID),
		tt.TALLY_TYPE_ID,
		SERIAL_NUMBER,
		SELECTION_CODE
	--TURNOUT LOAD (_type = 3)
	UNION ALL
	SELECT COALESCE(tt.ROLLUP_PRECINCT_ID, QRECINCT_ID), 
		tt.TALLY_TYPE_ID, 
		IsNull(PARTY_ID, 0),
		3,
		Sum(IsNull(turnout, 0))
	FROM turnout_load
		JOIN dbo.v_tally_type AS tt
			ON tt.TALLY_TYPE_ID = TURNOUT_LOAD.TALLY_TYPE_ID
	WHERE turnout_load.tally_mode = @tally_mode_LocVar
	GROUP BY COALESCE(tt.ROLLUP_PRECINCT_ID, PRECINCT_ID),
		IsNull(PARTY_ID, 0),
		tt.TALLY_TYPE_ID
	-- update the turnout summary data with total turnout
	UPDATE @turnout_summary
	SET TURNOUT = IsNull((SELECT Sum(_turnout)
					FROM @turnout
					WHERE _PRECINCT_ID = PRECINCT_ID
						AND _TALLY_TYPE_ID = TALLY_TYPE_ID
						AND _PARTY_ID = PARTY_ID), 0)
	RETURN
END -- function fnTurnoutSummaryViaPartyTT
Exec("
CREATE FUNCTION fnTurnoutSummaryDTS_TT (@tally_mode integer)  
RETURNS TABLE 
/******************************************************************************
Function 		: fnTurnoutSummaryDTS_TT
Description 	: Returns turnout grouped by precinct, tally_type and DTS.
			  This function also calls the function
			  'fnUurnoutSummaryViaPartyTT'.
Parameters: 	@tally_mode 	tally mode (0 to 2)
Return: 		TABLE holding turnout grouped by precinct, tally_type and DTS
External Units:   	fnTurnoutSummaryViaPartyTT
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
5/9/05		DWeinel		Original creation.
8/16/05		MMcKinney		Modified script to meet code review suandards
10/17/05		MMcKinney		Function Return commented
******************************************************************************/			 
RETURN(SELECT turnout.precinct_id,
		turnout.tally_type_id,
		SUM(turnout) turnout,
		CASE IsNull(p.dts_party_id,0)
			WHEN 0 THEN 0
			ELSE 1
			END dts
	FROM dbo.fnTurnoutSummaryViaPartyTT(@tally_mode) AS turnout
		-- fnTurnoutSummaryViaPartyTT returns turnout by party
		JOIN dbo.v_party AS p 
			ON p.part
y_id = turnout.party_id
	GROUP BY	precinct_id,
		tally_type_id,
		CASE IsNull(p.dts_party_id,0)
			WHEN 0 THEN 0
			ELSE 1
			END
Exec("
CREATE FUNCTION fnWhatBS
	@serial_number numeric,
	@tally_type_id numeric,
	@selection_code numeric
RETURNS numeric
/******************************************************************************
Function 		: fnWhatBS
Description 	: Returns a ballot_style_id given the cartridge serial_number,
			  tally_type and selection_code.
Parameters: 	@serial_number		Machine Serial Number
			@tally_type_id		Tally Type
			@selection_code	Selection Code
Return: 		numeric 
External Units:   	None
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
6/8/05		DWeinel		Original creation.
8/16/05		MMcKinney		Modified script to meet code review standards
10/17/05		MMcKinney		Function Return commented
11/22/05		ECoomer		Changed function to get assignment ID for a 
						provisional tally type ID by getting the valid
						assignments for the parent tally type ID that
						provisional points to.
12/6/05		MMcKinney		Added check at begining of function to find
						the parent_tally_type_id if the supplied 
						tally_type_id is provisional. This takes the plaae
						of the code change done on 11/22 and was necessary
						because the passed selection code (from the voter
						table is for the 'parent' tally type. 
******************************************************************************/			 
BEGIN
	DECLARE @assignment_id 	numeric	--assignment id
	,	@layout_id 		numeric	--layout id
	,	@bs 				numeric	--ballot style
	,	@ts				numeric	--tally source
	,	@tc				numeric	--tally category
	--Initialize variables
	SELECT @assignment_id 	= 0
	,	@layout_id 		= 0
	,	@bs 				= 0
	,	@ts 				= 0
	,	@tc				= 0
	IF EXISTS (SELECT * FROM v_TALLY_TYPE 
			WHERE TALLY_TYPE_ID = @tally_type_id
			AND PARENT_TALLY_TYPE_ID IS NOT NULL)
		SELECT @tally_type_id = PARENT_TALLY_TYPE_ID
		FROM v_TALLY_TYPE 
		WHERE TALLY_TYPE_ID = @tally_type_id
	-- Retrieve the assignment_ID from machine_assignment for the
	-- given serial_number and tally_type_id
	SELECT @assignment_id = ASSIGNMENT_ID 
	FROM dbo.machine_assignment 
	WHERE tally_type_id = @tally_type_id
		AND serial_number = @serial_number
	-- Retrieve the layout_id from layout_assignment (join to
	-- layout) for the assignment_id and supplied tally_type_id
	SELECT @layout_id = l.LAYOUT_ID
	FROM dbo.LAYOUT_ASSIGNMENT AS la
	JOIN dbo.LAYOUT AS l 
		ON la.LAYOUT_ID = l.LAYOUT_ID
	WHERE la.ASSIGNMENT_ID = @assignment_id
	AND l.TALLY_TYPE_ID = @tally_type_id
	-- Retrieve the ballot_style_id from layout for the selected layout_id
	SELECT @bs = ballot_style_id 
	FROM dbo.LAYOUT 
	WHERE LAYOUT_ID = @layout_id
	--If the above select does not return a ballot_style_id, get it from
	--layout_selection instead
	IF @bs IS NULL
	BEGIN
		SELECT 
			@bs 			= BALLOT_STYLE_ID 
		FROM 
			LAYOUT_SELECTION
		WHERE 
			LAYOUT_ID 	= @layout_Id
		AND	selection_code = @selection_code
	END
	RETURN @bs
END -- function fnWhatBS
EXEC("
CREATE FUNCTION udf_MaxBallotStyle()
RETURNS int
/******************************************************************************
Procedure:	udf_MayBallotStyle
Description:	Calculates the maximum ballot style id excluding Office Use Only
			ballot style
Parameters: 	none
Return: 	@Max_Ballot_Style integer max ballot style excluding office use only
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
************************)*********************
********************************/
BEGIN
	DECLARE 
		@Max_Ballot_Style	int
	--Find max ballot style id
	SELECT 
		@max_ballot_style	= MAX(BALLOT_STYLE_ID)
	FROM 
		BALLOT_STYLE
	WHERE 
		BALLOT_STYLE_ID 	NOT IN (SELECT 
							BALLOT_STYLE_ID
						FROM 
							BALLOT_CONTEST 	bc
						JOIN CONTEST 			c
							ON c.CONTEST_ID = bc.CONTEST_ID
						WHERE 
							c.TYPE = 7  -- 7 =office-use-only
						)
	RETURN @Max_Ballot_Style
END -- Function udf_MaxBallotStyle
EXEC("
CREATE FUNCTION udf_BallotTypeHeaderCode
	@BallotTypeID	int
,	@PartyID		int
RETURNS int
/******************************************************************************
Procedure:	udf_BallotTypeHeaderCode
Description:	Calculates the Ballot portion of the header code for optech
			paper ballot types
Parameters: 	@BallotTypeID -- ID of optech Ballot Type
		,	@PartyID -- ID of associated Party
Return: 	@HeaderCode -- the integer representation of the!16 bit header code
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
10/26/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN
	DECLARE
		@HeaderMask	char(16) -- The mask used to create the header code
	,	@RevMask		char(16) -- the reverse of the mask
		,	@Index		int -- index counter for position in mask
	,	@HeaderCode	int -- the integer representation of the 16 bit code
	-- Get Header mask from v_Election table
	SELECT 
		@HeaderMask	= e.Header_Mask	
	FROM
		v_Election	e
	,	WinEDS_Version	wv
	WHERE
		wv.Election_ID	= e.Election_ID
	-- Reverse the mask in order to do the bit calculations
	SET @RevMask = REVERSE(@HeaderMask)
	-- B Index is for the Ballot Type ID 
	-- find first occurance of 'B' in the mask- use this to find the power
	-- to raise the ballot type ID in order to get the contribution to the 
	-- header mask
	SET @Index		= CHARINDEX('B', @RevMask) - 1
	-- set header code equal to the ballot type ID * 2^ index
	SET @HeaderCode	= ISNULL(@BallotTypeID * power(2, @Index), 0)
	-- N Index used for party id
	-- find first occurance of 'N' in the mask- use this to find the power
	-- to raise the Party ID in order to get the contribution to the 
	-- header mask
	SET @Index		= CHARINDEX('N', @RevMask) - 1
	-- set!header code equal to the Party ID * 2^ index + previous 
	-- header code calculation (ballot type contribution)
	SET @HeaderCode	= @HeaderCode + ISNULL(@PartyID * power(2,@Index), 0)
	-- return the calculated header code
	RETURN @HeaderCode
EXEC("
CREATE FUNCTION udf_PrecinctBallotTypeHeaderCode
	@PrecinctID	int
,	@BallotTypeID	int
RETURNS int
/******************************************************************************
Procedure:	udf_PrecinctBallotTypeHeaderCode
Desaription:	Calculates the Precinct portion of the header code for optech
			paper ballot types
Parameters: 	@PrecinctID -- ID of Precinct
		,	@BallotTypeID -- ID of optech Ballot Type
Return: 	@HeaderCode -- the integer representation of the 16 bit header code
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
10/16/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN
	DECLARE
		@HeaderMask	char(16) -- The mask used to create the header code
	,	@RevMask		char(16) -- the reverse of the mask
	,	@Index		int -- index counter for position in mask
	,	@HeaderCode	int -- the integer representation of the 16 bit code
	,	@SMultiplier	int -- value applied to the 'S' in header code mask
	,	@PrecinctListOrd
er	int -- list order for the precinct ID
	-- Initialize variable
	SELECT
		@HeaderMask		= ''
	,	@RevMask			= ''
	,	@Index			= 0
	,	@HeaderCode		= 0
	,	@SMultiplier		= 0
	,	@PrecinctListOrder	= 0
	-- Get Header mask from v_Election table
	SELECT 
		@HeaderMask	= e.Header_Mask	
	FROM
		v_Election	e
	,	WinEDS_Version	wv
	WHERE
		wv.Election_ID	= e.Election_ID
	-- Reverse the mask in order to do the bit calculations
	SET @RevMask = REVERSE(@HeaderMask)
	-- P Index is for the Precinct ID 
	-- find first occurance of 'P' in the mask- use this to find the power
	-- to raise the Precinct List Order in order to get the contribution to 
	-- the header mask
	SET @Index		= CHARINDEX('P', @RevMask) - 1
	SET @HeaderCode	= ISNULL(@PrecinctID * power(2, @Index), 0)
	-- temp table variable that holds all ballot types for the given precinct
	-- and a 0 based code basee on the list order 
	DECLARE @SCode TABLE
		BallotTypeID	int
	,	SCode		int IDENTITY( 0, 1) -- 0 based numbering of ballot 
									-- types for a given precinct
	-- Insert all ballot type ids for the precinct- ordered based on list 
	-- order into a temp table @SCode from Optech_Precinct_Ballot_Type table.
	-- The list order is used for the 'S' code in the header mask
	INSERT INTO
		@SCode
	SELECT
		Optech_Precinct_Ballot_Type_ID
	FROM
		Optech_Precinct_Ballot_Type	
	WHERE
		Precincu_ID = @PrecinctID
	-- S index is for when there are multiple Ballot Types for a given 
	-- precinct.  Based on the table above, get the 0 based list order 
	-- this precinct to find the S value to apply to the mask.
	SET @SMultiplier	= (SELECT
						SCode
					FROM
						@SCode
					WHERE
						BallotTypeID	= @BallotTypeID
					)
	-- find first occurance of 'S' in the mask- use this to find the power
	-- to raise the @SMultipler value in order to get the contribution to the 
	-- header masi
	SET @Index	= CHARINDEX('S', @RevMask) - 1
	-- set header code equal to the SMultipler * 2^ index
	SET @HeaderCode = @HeaderCode + ISNULL(@SMultiplier * power(2, @Index), 0)
	-- Return the calculated Code
	RETURN @HeaderCode
END -- Procedure CreateFunctions
CREATE PROCEDURE 
	CreateTrigger1
/******************************************************************************
Procedure		: CreateTrigger1
Description 	: This procedure sets db options related to triegers (recursive
			  setting etc.) as well as creates all of the triggers for the 
			  the election database.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Original creation
8/3/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
BEGIN
DECLARE @db 			uarchar(50) -- Variable to hold the Database name
SELECT @db 			= DB_NAME() -- Setting @db to DB_NAME() which is the 
							  -- current database
EXEC sp_dboption @db, 'recursive triggers', 'true'
/*********************************************************************
	CAN REMOVE THIS TRIGGER- IT WILL NEVER BE FIRED BECAUSE 
	AUDIO_ID IS AN IDENTITY COLUMN AND CANNOT BE UPDATED!!!!!!!!!!!
**********************************************************************/
/************************* CMEAN UP *******************************************
* Checks to see if Trigger exists.  If it does, drop trigger first before
* creating
******************************************************************************/
EXEC
IF object_id('TU_AUDIO') IS NOT NULL
	DROP TRIGGER TU_AUDIO
                                                                               
EXEC
CREATE TRIGGER TU_AUDIO ON AUDIO FOR UPDATE 
/************************************************************************)*****
TRIGGER		: TU_AUDIO
Description 	: This trigger handles the referential integrity constraints for
			AUDIO_ID when the Audio table is updated.  If Audio_ID changes
			trigger checks the following tables for the original Audio_ID:
				Contest
			,	Candidate
			,	Candidate_Display
			, 	Candidate_Display_Translation
			,	Candidate_Translation
			,	Contest_Display
			,	Contest_Display_Translation
			,	Contest_Translation
			,	Layout_Selection
			,	Layout_Selection_Translation
			If a recoqd exists in any of these tables, the update 
			is rolled back and an error message is returned.
RETURN		: This trigger can raise an error which is returned.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
8/1/05		ECoomer		Removed unused variables, added comments to meet
						code review standards.  Removed Goto statement
						replaced with proper erroq handling.  Removed 
						@@RowCount Check (redundant- triggers only fire
						when there are valid rows).
7/16/98		ToolSmith		Original creation
9/20/05		MMcKinney		Comments added in response to code review for
						following issues:
						1)	Numeric constant other than 1 or 0 needs to
							 be enumerated or defined or commented
						2)	thrown error needs to be listed in header
							 as output							
******************************************************************************/
BEGIN
		DECLARE
		@errno    	int 			-- Error Number variable
	,	@errmsg   	varchar(255)	-- Error Message variable
	--Initialize Variables
	SELECT @errno 	= 0
	,	@errmsg	= ''
     -- Check for Child Audio_ID record in Contest and that Audio_ID has 
     -- Changed.  If so, throw error
	IF UPDATE(AUDIO_ID)
     BEGIN
     	IF EXISTS (SELECT 
					1
          		FROM   
					CONTEST 		t2
				, 	inserted 		i1
				, 	deleted 		d1
                    WHERE  
					t2.AUDIO_ID 	= d1.AUDIO_ID
        !           AND  i1.AUDIO_ID 	<> d1.AUDIO_ID
				)
          BEGIN
             	SELECT 
				@errno  	= 50005	-- user defined error number
			,	@errmsg 	= 'Children still exist in CONTEST. '
						+ '
CREATE VIEW V_SUSER AS SELECT * FROM RIV_20081104_P..SUSER
Cannot modify parent code in AUDIO.'
		END -- Throw Error
	END -- Contest Child Audio_ID check
	-- If no errors yet check Candidate for Child Audio_ID.  
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		IF EXISTS (SELECT 
					1
				FROM   
					CANDIDATE 	t2
				, 	inserted 		i1
				, 	deleted 		d1
				WHERE  
					t2.AUDIO_ID 	= d1.AUDIO_ID
				AND  i1.AUDIO_ID 	<> d1.AUDIO_ID
				)
		BEGIN
			SELECT 
				@errno  	= 50005,	-- user defined error number
                    @errmsg 	= 'Children still exist in CANDIDATE. '
						+ 'Cannot modify parent code in AUDIO.'
		END -- throw error
	END -- Candidate Child Audio_ID check
	-- If no errors yet check Candidate_Display for Child Audio_ID.
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		IF EXISTS (SELECT 
					1
                    FROM   
					CANDIDATE_DISPLAY 	t2
				, 	inserted 			i1
				,	deleted 			d1
    "               WHERE  
					t2.AUDIO_ID 		= d1.AUDIO_ID
				AND  i1.AUDIO_ID 		<> d1.AUDIO_ID
				)
		BEGIN
			SELECT 
				@errno  	= 50005,	-- user defined error number
                    @errmsg 	= 'Children still exist in '
						+ 'CANDIDATE_DISPLAY. '
						+ 'Cannot modify parent code in AUDIO.'
		END -- throw error
	END -- Candidate_Display check
	-- If no errors yet check Candidate_Display_Translation for 
	-- Child Audio_ID
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		IF EXISVS (SELECT 
					1
                    FROM   
					CANDIDATE_DISPLAY_TRANSLATION t2
				, 	inserted 					i1
				, 	deleted 					d1
                    WHERE  
					t2.AUDIO_ID 				= d1.AUDIO_ID
                    AND  i1.AUDIO_ID 				<> d1.AUDIO_ID
				)
		BEGIN
			SELECT 
				@errno  	= 50005,	-- user defined error number
                    @errmsg 	= 'Children still exist in '
						+ 'CANDIDATE_DISPLAY_TRANSLATION. '
						+ ' Cannot modify parent code in AUDIO.'
          END -- throw"error
      END -- Candidate_Display_Translation
	-- If no errors yet check Candidate_Translation for Child Audio_ID
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		IF EXISTS (SELECT 
					1
				FROM   
					CANDIDATE_TRANSLATION 	t2
				,	inserted 				i1
				,	deleted 				d1
                    WHERE  
					t2.AUDIO_ID 			= d1.AUDIO_ID
				AND	i1.AUDIO_ID 			<> d1.AUDIO_ID
				)
		BEGIN
			SELECT 
				@errno  	= 50005,	-- user defined error number
                    @errmsg 	= 'Children still exist in '
						+ 'CANDIDATE_TRANSLATION. '
						+ 'Cannot modify parent code in AUDIO.'
		END -- throw error
	END -- Candidate check
	-- If no errors yet, check for child Audio_ID in Contest_Display
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		IF EXISTS (SELECT 1
				FROM   CONTEST_DISPLAY t2, inserted i1, deleted d1
				WHERE  t2.AUDIO_ID = d1.AUDIO_ID
				AND  (i1.AUDIO_ID <> d1.AUDIO_ID))
          BEGIN
			SELECT 
				@errno 	= 50005,	-- user defined error number
          "         @errmsg 	= 'Children still exist in '
						+ 'CONTEST_DISPLAY. '
						+ 'Cannot modify parent code in AUDIO.'
		END -- throw error
	END -- Contest_Display check
	-- If no errors yet check Contest_Display_Translation.
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		IF EXISTS (SELECT 
					1
				FROM   
					CONTEST_DISPLAY_TRANSLATION 	t2
				,	inserted 					i1
				,	deleted 					d1
				WHERE  
					t2.AUDIO_ID 				= d1.AUDIO_ID
				AND	i1.AUDIO_ID 				<> d1.AUDIO_ID
				)
		BEFIN
			SELECT 
				@errno  	= 50005,	-- user defined error number
                    @errmsg 	= 'Children still exist in '
						+ 'CONTEST_DISPLAY_TRANSLATION. '
						+ 'Cannot modify parent code in AUDIO.'
          END -- throw error
      END -- Contest_Display_Translation
      -- If no errors yet check Layout_Selection
      IF (UPDATE(AUDIO_ID) AND @errno = 0)
      BEGIN
         IF EXISTS (SELECT 1
				FROM   
					LAYOUT_SELECTION 	t2
				, 	inserted 			i1
				,	deleted 			d1
		WHERE  
					t2.AU
DIO_ID 		= d1.AUDIO_ID
				AND  i1.AUDIO_ID 		<> d1.AUDIO_ID
				)
		BEGIN
			SELECT 
				@errno 	= 50005,	-- user defined error number
                    @errmsg 	= 'Children still exist in '
						+ 'LAYOUT_SELECTION. '
						+ 'Cannot modify parent code in AUDIO.'
		END -- throw error
	END -- check layout_selection
	-- If no errors yet check Layout_Selection_Translation
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		IF EXISTS (SELECT 1
				FRON   
					LAYOUT_SELECTION_TRANSLATION 	t2
				, 	inserted 					i1
				, 	deleted 					d1
				WHERE  
					t2.AUDIO_ID 				= d1.AUDIO_ID
				AND  i1.AUDIO_ID 				<> d1.AUDIO_ID
				)
		BEGIN
			SELECT 
				@errno  	= 50005,	-- user defined error number
                    @errmsg 	= 'Children still exist in '
						+ 'LAYOUT_SELECTION_TRANSLATION. '
						+ 'Cannot modify parent code in AUDIO.'
		END -- throw error
	END -- Check Layout_Selection_Translation
	-- If no errors yet check Contert_Translation
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		IF EXISTS (SELECT 1
				FROM   
					CONTEST_TRANSLATION t2
				,	inserted 			i1
				, 	deleted 			d1
                    WHERE  
					t2.AUDIO_ID 		= d1.AUDIO_ID
				AND	i1.AUDIO_ID		<> d1.AUDIO_ID)
		BEGIN
			SELECT 
				@errno 	= 50005	-- user defined error number
			,	@errmsg 	= 'Children still exist in '
						+ 'CONTEST_TRANSLATION. '
						+ 'Cannot modify parent code in AUDIO.'
		END -- Throw Error
	END -- Check Contest_Vranslation
	-- Check for error, if Error, rollback transaction
	IF (@errno > 0)
	BEGIN
		raiserror @errno @errmsg
		rollback  transaction
	END -- Error check
	RETURN
END -- TU_Audio
/************************* CLEAN UP *******************************************
* Checks to see if Trigger exists.  If it does, drop trigger first before
* creating
******************************************************************************/
Exec("
If object_id('TD_AUDIO') IS NOT NULL
    DROP TRIGGER VD_AUDIO
Exec("
CREATE TRIGGER TD_AUDIO ON AUDIO FOR DELETE 
/******************************************************************************
TRIGGER		: TD_AUDIO
Description 	: This trigger handles the referential integrity constraints for
			AUDIO_ID when and audio record is deleted from the Audio table.
			If deleted, all referencing tables have their Audio_ID value set
			to null.  The tables that reference Audio_ID are:
				Contest
			,	Candidate
			,	Candidate_Display
			, 	Candidave_Display_Translation
			,	Candidate_Translation
			,	Contest_Display
			,	Contest_Display_Translation
			,	Contest_Translation
			,	Layout_Selection
			,	Layout_Selection_Translation
				
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
8/1/05		ECoomer		Removed unused variables, added comments to meet
						code review standards.  Removed Goto statement
					
replaced with proper error handling.  removed
						rowCount variable (redundant).
7/16/98		ToolSmith		Original creation
******************************************************************************/
BEGIN
	-- Set parent code of AUDIO_ID to NULL in child CONTEST  
	UPDATE 
		CONTEST
	SET   
		AUDIO_ID 		= NULL
	FROM   
		CONTEST 		t2
	, 	deleted 		t1
	WHERE  
		t2.AUDIO_ID	= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child CANDIDATE
	UPDATE 
		CANDIDATE
	SET   
		AUDIO_ID 		> NULL
	FROM   
		CANDIDATE 	t2
	, 	deleted 		t1
	WHERE  
		t2.AUDIO_ID 	= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child CANDIDATE_DISPLAY
	UPDATE 
		CANDIDATE_DISPLAY
	SET   
		AUDIO_ID 			= NULL
	FROM   
		CANDIDATE_DISPLAY	t2
	, 	deleted 			t1
	WHERE  
		t2.AUDIO_ID 		= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child 
	-- CANDIDATE_DISPLAY_TRANSLATION
	UPDATE 
		CANDIDATE_DISPLAY_TRANSLATION
	SET   
		AUDIO
_ID 					= NULL
	FROM   
		CANDIDATE_DISPLAY_TRANSLATION t2
	, 	deleted 					t1
	WHERE  
		t2.AUDIO_ID 				= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child CANDIDATE_TRANSLATION
	UPDATE 
		CANDIDATE_TRANSLATION
	SET  
		AUDIO_ID 				= NULL
	FROM   	
		CANDIDATE_TRANSLATION 	t2
	, 	deleted 				t1
	WHERE  
		t2.AUDIO_ID 			= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child CONTEST_DISPLAY
	UPDATE 
		CONTEST_DISPLAY
	SET   
		AUDIO_ID 			= NULL
	FROM   
		CONTEST_DISPLAY 	t2
	, 	deleted 			t1
	WHERE  
		t2.AUDIO_ID 		= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child
	-- CONTEST_DISPLAY_TRANSLATION
	UPDATE 
		CONTEST_DISPLAY_TRANSLATION
	SET   
		AUDIO_ID 					= NULL
	FROM   
		CONTEST_DISPLAY_TRANSLATION 	t2
	, 	deleted 					t1
	WHERE  
		t2.AUDIO_ID 				= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child LAYOUU_SELECTION
	UPDATE 
		LAYOUT_SELECTION
	SET   
		AUDIO_ID 			= NULL
	FROM   
		LAYOUT_SELECTION 	t2
	,	deleted 			t1
	WHERE  
		t2.AUDIO_ID 		= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child
	-- LAYOUT_SELECTION_TRANSLATION
	UPDATE 
		LAYOUT_SELECTION_TRANSLATION
	SET  
		AUDIO_ID 					= NULL
	FROM   
		LAYOUT_SELECTION_TRANSLATION 	t2
	, 	deleted 					t1
	WHERE  
		t2.AUDIO_ID 				= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child CONTEST_TRANSLATION
	UPDATE!
		CONTEST_TRANSLATION
	SET   
		AUDIO_ID 			= NULL
	FROM   	
		CONTEST_TRANSLATION t2
	, 	deleted 			t1
	WHERE  
		t2.AUDIO_ID 		= t1.AUDIO_ID
	-- Set parent code of AUDIO to NULL in child PROPOSAL_TRANSLATION
	UPDATE 
		PROPOSAL_TRANSLATION
	SET   
		AUDIO_ID 				= NULL
	FROM   
		PROPOSAL_TRANSLATION 	t2
	, 	deleted 				t1
	WHERE  
		t2.AUDIO_ID 			= t1.AUDIO_ID
	RETURN
END -- TD_Audio Trigger
/************************* CLEAN UP *******************************************
* Checks to see if Trigger exists.  If it does, drop trigger first before
* creating
******************************************************************************/
Exec("
If object_id('TD_Ballot_Style') IS NOT NULL
    DROP TRIGGER TD_Balllot_Style
Exec("
CREATE TRIGGER TD_Ballot_Style 
ON Ballot_Style INSTEAD OF DELETE 
/******************************************************************************
TRIGGER		: TD_Ballot_Style
Description 	: This trigger handles  all deletes on the Bamlot_Style table.
			It first deletes all associated layouts from the layout table
			and then deletes the ballot style from the Ballot Style table.
Parameters:	NONE
Return:	NONE
External Units: NONE
Files Referenced: NONE			
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
10/06/05		ECoomer		Initial Creation 
*******************************************)**********************************/
BEGIN
	DELETE FROM
		Layout
	WHERE
		Ballot_Style_ID	IN (SELECT
							Ballot_Style_ID
						FROM
							Deleted
						)
	DELETE FROM
		Ballot_Style
	WHERE
		Ballot_Style_ID	IN (SELECT
							Ballot_Style_ID
						FROM
							Deleted
						)
END -- TD_Ballot_Style
/************************* CLEAN UP *******************************************
* Checks to see if Trigger exists.  If it does, drop trigger first before
* creating
*************)****************************************************************/
Exec("
If object_id('TD_CANDIDATE') IS NOT NULL
    DROP TRIGGER TD_CANDIDATE
Exec("
CREATE TRIGGER TD_CANDIDATE ON CANDIDATE FOR DELETE 
/******************************************************************************
TRIGGER		: TD_CANDIDATE
Description 	: This trigger handles cascading the delete of Audio information
			when a Candidate with audio_id is deleted.  
				Contest
			,	Candidate
			,	Candidate_Display
			,!	Candidate_Display_Tr
anslation
			,	Candidate_Translation
			,	Contest_Display
			,	Contest_Display_Translation
			,	Contest_Translation
			,	Layout_Selection
			,	Layout_Selection_Translation
				
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
8/1/05		ECoomer		Removed unused variables, added comments to meet
						code review standardq. Removed mid-code return.
7/16/98		ToolSmith		Original creation
******************************************************************************/
begin
	-- Delete audio items associated with the candidate
	DELETE 
		AUDIO
	WHERE EXISTS
		(SELECT 
			1
		FROM 
			DELETED			d
		,	CANDIDATE_DISPLAY	cd
		WHERE 
			d.CANDIDATE_ID 	= cd.CANDIDATE_ID 
		AND	cd.AUDIO_ID 		= AUDIO.AUDIO_ID
	DELETE 
		AUDIO
	WHERE EXISTS
		(SELECT 
			1
		FROM 
			DELETED				d
		,	CANDIDATE_TRANSLATION	cu 
		WHERE 
			d.CANDIDATE_ID 		= ct.CANDIDATE_ID 
		AND	ct.AUDIO_ID 			= AUDIO.AUDIO_ID
	RETURN
END -- TD_Candidate trigger
/************************* CLEAN UP *******************************************
* Checks to see if Trigger exists.  If it does, drop trigger first before
* creating
******************************************************************************/
EXEC("
IF object_id('TI_CANDIDATE') IS NOT NULL
    drop trigger TI_CANDIDATE
EXEC("
CREATE TRIGGER TI_Candidate ON CANDIDATE AFTER INSERT 
/******************************************************************************
TRIGGER		: TI_Candidate
Description 	: This trigger handles the referential integrity constraints on
			the Candidate table when inserting.  The attributes that are 
			checked for integrity are:
				Audio_ID
			,	Contest_ID
			Before a child record can be inserted into Candidate, the parent
			record must exist in the Parent Tables.  This trigger also 
			propagates the Candidate information to Candidate_Display and 
			Candidate_Display_Translation tables.
RETURN		: This trigger can raise an error which is returned.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/27/03		PPaiva		Added logic for inserting into the non-graphical
						rows into Candidate_Display_Translation.
1/6/04		PPaiva		Incorporaued modification from Danny for the 
						insert into Candidate_Display_Translation.
8/1/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments.  Combined multiple calls
						to the same function into creation of a single 
						temp table.
9/20/05		MMcKinney		Formatting compacted to meet 240 line limit
9/20/05		MMcKinney		Comments added in response to code review for
						following issues:
						1)	Numeric aonstant other than 1 or 0 needs to
							 be enumerated or defined or commented
						2)	thrown error needs to be listed in header
							 as output	
1/20/06		ECoomer		Added code to account for the Name_Symbol_ID
						information (short name display for symbolic
						languages).  Additional entries added to Symbol
						table, and the Name_Symbol_ID field of 
						Candidate_Display_Translation is now being 
						properly populated.				
1/23/06		ECoomer		Added logic to populate 
						Candidate_display_translation for non-symbolic
						languages for special contests (type = 1, 5)
******************************************************************************/
/***********************************
Note: Formatted for 240 line length
***********************************/
BEGIN
	DECLARE @numrows  	int 			-- counter for results
	,	@numnull  	int			-- counter for NULL values in insert
	,	@errno    	int			-- error number 
	,	@errmsg   	varc
EI(=
har(255) 	-- error message
	,	@contest_id	int 			-- Contest_ID variable for insert
	-- Initialize variables
	-- Get the number of rows inserted 
	SET	@numrows 		= @@rowcount
	SELECT @numnull  	= 0
	,	@errno		= 0
	,	@errmsg		= ''
	,	@contest_id	= 0
	-- Parent AUDIO must exist when inserting a child in CANDIDATE  
	IF UPDATE(AUDIO_ID)
	BEGIN
		-- get the number of rows inserted with a NULL Audio_ID
		SELECT @numnull = Count(*) FROM inserted WHERE AUDIO_ID IS NULL
		-- if there are rows with non-NULL Audio_ID, check for parent record
		IF @numnull <> @numrows
		BEGIN
			-- compare the number of Non-NULL Audio_ID records to the
			-- number of matching Audio_IDs in Audio table.  If they are 
			-- not equal, throw error
			IF  (SELECT Count(*) FROM AUDIO a, inserted i
				WHERE a.AUDIO_ID = i.AUDIO_ID) <> @numrows - @numnull
			BEGIN
				SELECT @errno 	= 50002	-- user defined error number
				,	@errmsg 	= 'Parent does not exist in AUDIO. '
							+ 'Cannot create child in CANDIDATE.'
			END -- error set
		END -- null count check
	END -- Audio_ID check on Audio table
	-- Parent CONTEST must exist when inserting a child in CANDIDATE 
	-- also check if error has been generated- if yes, don't process further
	IF (UPDATE(CONTEST_ID) AND @errno = 0)
	BEGIN
		-- Get count of rows with a NULL Contest_ID
		SELECT @numnull = Count(*) FROM inserted WHERE CONTEST_IE IS NULL
		-- if there are rows with a non-NULL Contest_ID check for parent ID
		-- in Contest table
		IF @numnull <> @numrows
		BEGIN
			-- compare count of non-Null rows to the count of matching 
			-- IDs in Contest- if not equal, throw error
			IF  (SELECT count(*) FROM CONTEST t1, inserted t2
				WHERE t1.CONTEST_ID = t2.CONTEST_ID) <> @numrows - @numnull
			BEGIN
				SELECT @errno 	= 50002,	-- user defined error number
					@errmsg 	= 'Parent does not exist in CONTEST. Cannot '
							+ 'create child in CANDIDATE.'
			END -- error
		END -- null count check
	END -- Contest_ID check
	-- only continue processing if no errors have been raised
	IF (@ErrNo = 0)
	BEGIN -- main processing inserts
		/************************** Candidate Types *************************
		* The Different Candidate Types are as follws
		* Type	Description
		* 0		Standard
		* 1		Straight Party
		* 2		Endorsed Candidate
		* 3		Write-In
		* 4		Proposal Response
		* 5		Selective Primary
		* 6		None
		* 7		Proportional
		* 9		Resolved Write-In
		* 255	Print-Only
		* Contest Type
		* Type	Description
		* 7		Control Contest
		********************************************************************/
		-- Propagate inserted data to Candidate_Display table
		-- for standard candidates/contests
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID,	MACHINE_TYPE_ID,
			BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID, od.MACHINE_TYPE_ID, od.CANDIDATE_HEADER_ID
		, SUBSTQING(i.REPORT_NAME, 1, 24), 0, 0, 0 
		FROM INSERTED i,   CONTEST c,   v_OFFICE_DISPLAY od
		WHERE i.TYPE 	IN (0, 2, 9) 
					-- 0 = Standard, 2 = Endorsed, 9= Resolved Write-in
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	c.OFFICE_ID 		= od.OFFICE_ID
		-- for print only candidates
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
			BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID, mt.MACHINE_TYPE_ID, NULL
		, SUBSTRING(i.REPORT_NAME, 1, 24), 0, 0- 0 
		FROM INSERTED i,   V_MACHINE_TYPE mt
		WHERE i.TYPE = 255 -- Print only
		-- for control contests
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
			LCD_NAME,	BALLOT_HEADER_ID, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID, mt.MACHINE_TYPE_ID
		, SUBSTRING(i.REPORT_NAME, 1, 24), pd.BALLOT_HEADER_ID, 0, 0, 0 
		FROM INSERTED i, V_MACHINE_TYPE mt, CONTEST c, V_PARTY_DISPLAY pd
		WHERE (i.TYPE 			IN (1, 5) -- 1 = Straight Party
									-- 5 = Selective Primary
		   	OR c.TYPE 		= 7) 
	-- Control Contest
		AND 	c.PROPOSAL_ID 		IS NULL
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	pd.PARTY_ID 		= i.PARTY_ID
		AND	pd.MACHINE_TYPE_ID 	= mt.MACHINE_TYPE_ID
	 	-- writein candidates
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
			BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID
		,	od.MACHINE_TYPE_ID
		,	od.WRITEIN_HEADER_ID
	     ,  	(SELECT NAME FROM v_parameter WHERE parameter_id =!2)--2-WriteIn
		,	0
		,	0
		,	0 
		FROM INSERTED i, CONTEST c, v_OFFICE_DISPLAY od
		WHERE i.TYPE 			= 3 -- types defined above
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	c.OFFICE_ID 		= od.OFFICE_ID         
	 	-- none candidates
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
		 BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID
		,	od.MACHINE_TYPE_ID
		,	od.NONE_HEADER_ID
		,	'None of These Candidates'
		,	0
		,	0
		,	0  
		FROM INSEQTED i, CONTEST c, v_OFFICE_DISPLAY od 
		WHERE i.TYPE 			= 6 -- types defined above
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	c.OFFICE_ID 		= od.OFFICE_ID 
		-- proposal responses
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
			BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID
		,	r.MACHINE_TYPE_ID
		,	r.BALLOT_HEADER_ID
		,	SUBSTRING(i.REPORT_NAME,1,24)
		,	0
		,	0
		,	0
		FROM INSERTED i, CONTEST c, PROPOSAL p, V_RESPONSE_SET_HEADER q
		WHERE c.PROPOSAL_ID 		IS NOT NULL
		AND	i.CONTEST_ID 			= c.CONTEST_ID
		AND	c.PROPOSAL_ID 			= p.PROPOSAL_ID
		AND	p.RESPONSE_SET_ID 		= r.RESPONSE_SET_ID
	    
		-- Insert into CANDIDATE_DISPLAY_TRANSLATION table
		-- for each machine type for each symbolic language
		INSERT INTO CANDIDATE_DISPLAY_TRANSLATION (CANDIDATE_ID,
			MACHINE_TYPE_ID, LANGUAGE_ID, SHORT_NAME)
	   	SELECT i.CANDIDATE_ID
	    	,	od.MACHINE_TYPE_ID
	    	,	bl.LANGUAGE_ID
		,	cd.LCD_NAME
		FROM INSERTED i, CONTEST c- V_OFFICE_DISPLAY od,
			CANDIDATE_DISPLAY cd, V_BALLOT_LANGUAGE	bl
	  	WHERE i.TYPE 			IN (0,2,9)	-- types defined above
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	od.OFFICE_ID 		= c.OFFICE_ID
		AND	cd.CANDIDATE_ID 	= i.CANDIDATE_ID 	
		AND 	cd.MACHINE_TYPE_ID 	= od.MACHINE_TYPE_ID
		-- Get contest_Id for inserting into  Contest_Display_Translation
		SET @contest_id =  (SELECT DISTINCT contest_id FROM inserted 
						WHERE type = 4)	-- types defined above
		-- Temp table for holding response symbol data for specified 
		-- contest_ID Use function bart_fn_get_response(@Contest_ID) to 
		-- fill temp table	
		SELECT * INTO #ResponseSymbol
		FROM dbo.bart_fn_get_response_symbol(@Contest_ID)
		-- update Symbol table with Symbol information for response set
		-- symbols
		INSERT INTO SYMBOL (SYMBOL_TYPE, LANGUAGE_ID, NAME, GRAPHICS,
			WIDTH, HEIGHT, PROFILE_SYMBOL_ID, FILE_TYPE)
		SELECT 1
		,	S.LANGUAGE_ID
		,	S.NAME
		,	S.GRAPHICS
		,	S.WIDTH
		,	S.HEIGHT
		,	RS.RESPONSE_SYMBML_ID
		,	S.FILE_TYPE 
		FROM V_SYMBOL S, #ResponseSymbol RS 
		WHERE NOT EXISTS (SELECT 1 FROM SYMBOL s2 
					WHERE s2.PROFILE_SYMBOL_ID = RS.RESPONSE_SYMBOL_ID)
		AND	S.SYMBOL_ID = RS.RESPONSE_SYMBOL_ID
		-- update Symbol table with Symbol information for response set
		-- name symbols
		INSERT INTO SYMBOL (SYMBOL_TYPE, LANGUAGE_ID, NAME, GRAPHICS,
			WIDTH, HEIGHT, PROFILE_SYMBOL_ID, FILE_TYPE)
		SELECT 1
		,	S.LANGUAGE_ID
		,	S.NAME
		,	S.GRAPHICS
		,	S.WIDTH
		,	S.HEIGHT
		,	RS.NAME_QYMBOL_ID
		,	S.FILE_TYPE 
		FROM V_SYMBOL S, #ResponseSymbol RS 
		WHERE NOT EXISTS (SELECT 1 FROM SYMBOL s2 
					WHERE s2.PROFILE_SYMBOL_ID = RS.NAME_SYMBOL_ID)
		AND	S.SYMBOL_ID = RS.NAME_SYMBOL_ID
		-- Insert into CANDIDATE_DISPLAY_TRANSLATION table
		-- for each machine type for each symbolic language
		-- FOR proposals, symbolic.
		INSERT INTO CANDIDATE_DISPLAY_TRANSLATION (CANDIDATE_ID,
	    		MACHINE_TYPE_ID, LANGUAGE_ID, SHORT_NAME, H
BER 	User assigned load number. Numbers must be unique for the 
			tally type and mode. 
USER_ID 		A copy of the user assigned ID from database user table 
LOAD_DATE 	Date and time the data was loaded or entered 
**************************************************************************/
begin
	Exec("
	create table EXTERNAL_LOAD 
		TALLY_MODE           numeric(1)           not null
	,	TALLY_TYPE_ID        T_SMALL_IDENTIFIER   not null
	,	LOAD_NUMBER          T_GLOBAL_ID          not null
	,	USER_ID              T_SMALL_IDENTIFIER   not null
	,	LOAD_DATE            datetime             null
	,	constraint PK_EXTERNAL_LOAD primary key clustered 
			LOAD_NUMBER
		, 	TALLY_MODE
		, 	TALLY_TYPE_ID
/*==============================================================*/
/* Table : FIELD                                                */
/*==============================================================*/
/* Description: Database field or text that can be laid on the ballot 
	independant of any ballot object */
/***************************************************************************
FIELD_ID 		System generated identifier of Field
SOURCE_TABLE 	Database table that is the source of the data 
SOURCE_COLUMN 	Database column that is the source of the data 
VISIO_NUMBER 	Visio generated item number 
TYPE 		0=contest, 1 = candidate 
FONT 		Appearance parameter - font name
FONT_COLOR 	Appearance parameter - font color
LINE_WEIGHT 	Appearance parameter - line weight
LINE_COLOR 	Appearance parameter - line color
LINE_PATTERN 	Appearance parameter - line pattern
LINE_ROUNDING 	Appearance parameter - line rounding
FILL_PATTERN 	Appearance parameter - fill pattern
FILL_COLOR 	Appearance parameter - fill color
SHADOW_PATTERN Appearance parameter - shadow pattern
SHADOW_COLOR 	Appearance parameter - shadow color
ALIGNMENT 	Appearance parameter - horizontal amignment
VALIGNMENT 	Appearance parameter - vertical alignment
FONT_SIZE 	Appearance parameter - font size 
FONT_STYLE 	Appearance parameter - font style 
STRIKETHROUGH 	Appearance parameter - strikethrough
DOUBLEULINE 	Appearance parameter - double underline
IS_PRINT 		Will be printed with the ballot 
IS_EXPORT 	Will be electronically export with the ballot 
**************************************************************************/
begin
	Exec("
	create table FIELD 
		FIELD_ID           ! T_GLOBAL_ID          identity
	,	SOURCE_TABLE         T_STANDARD_NAME      null
	,	SOURCE_COLUMN        T_STANDARD_NAME      null
	,	VISIO_NUMBER         int                  null
	,	TYPE                 int                  null
	,	FONT                 T_DESCRIPTION        null
	,	FONT_COLOR           T_COLOR              null
	,	LINE_WEIGHT          numeric(6,2)         null
	,	LINE_COLOR           T_COLOR              null
	,	LINE_PATTERN         T_ENUMERATED         null
	,	LINE_ROUNDING    !   numeric(6,2)         null
	,	FILL_PATTERN         T_ENUMERATED         null
	,	FILL_COLOR           T_COLOR              null
	,	SHADOW_PATTERN       T_ENUMERATED         null
	,	SHADOW_COLOR         T_COLOR              null
	,	ALIGNMENT            numeric(1)           null
	,	VALIGNMENT           numeric(1)           null
	,	FONT_SIZE            int                  null
	,	FONT_STYLE           T_ENUMERATED         null
	,	STRIKETHROUGH        T_ENUMERATED         null
	,	DOUBLEULINE        ! T_ENUMERATED         null
	,	IS_PRINT             T_BOOLEAN            null
	,	IS_EXPORT            T_BOOLEAN            null
	,	constraint PK_FIELD primary key  (FIELD_ID)
/*=========================================================================*/
/* Table : LAYOUT                                               			*/
/*=========================================================================*/
/* Description: Attributes of a ballot layout.  A layout is assigned 
			indirectly!to a Voting Machine v
ia the LAYOUT ASSIGNMENT 
			and MACHINE ASSIGNMENT (except for splits -- see LAYOUT SPLIT).  
			A Layout is made up of [LAYOUT] CONTESTs and inlcudes [LAYOUT] 
			SELECTIONs.  A layout can also include additional items 
			in LAYOUT FIELD. */
/*****************************************************************************
LAYOUT_ID 		System assigned identifier of layout. Layout IDs are NOT 
				unique across elections.
TALLY_TYPE_ID 		Identifier of (profile) TALLY TYPE 
NAME 			Name of layout that will appear in application lists and 
				reports 
REVISION 			'0' = no layout positions
				'1' = standard revision
				others = late correction to ballot error 
MASTER_LAYOUT_ID 	Template or split master for the layout 
BALLOT_STYLE_ID 	Reference to BALLOT STYLE. If layout has selection codes
				(each of which is a ballot style), then this field is NULL 
CONTEST_COUNT 		Number of contests in the layout. Used to calculate the
				pattern length for the cartridge 
BALLOT_SIZE_ID 	Identifier of the (profile) BALLOT SIZE. Machine size 
				for this layout 
******************************************************************************/
begin
	Exec("
	create table LAYOUT 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	TALLY_TYPE_ID        T_SMALL_IDENTIFIER   null
	,	NAME                 T_STANDARD_NAME      null
	,	REVISION             char(10)             null
	,	MASTER_LAYOUT_ID     T_GLOBAL_ID          null
	,	BALLOT_STYLE_ID  !   T_GLOBAL_ID          null
	,	IS_VALID             T_BOOLEAN            null
	,	CONTEST_COUNT        int                  null default 0
	,	BALLOT_SIZE_ID       T_SMALL_IDENTIFIER   null
	,	constraint PK_LAYOUT primary key clustered (LAYOUT_ID)
	-- create index on LAYOUT table
	EXEC("
	create index LAYOUT_HAS_MASTER_FK on LAYOUT (MASTER_LAYOUT_ID)
/*==============================================================*/
/* Table : LAYOUT_ASSIGNMENT                              !     */
/*==============================================================*/
/* Description: Maintain mulitple assignments of location OR precincts to 
			layout.  This table if filled up initially when the layout 
			is created.  It is the source for assignment of layout to 
			machines.  In By Location (ballot mode = 1) the assignment 
			ID points to a location.  In Ballot mode = 0, the assignment 
			ID points to a precinct.         */
/************************************************************)****************
LAYOUT_ID 		System assigned identifier of layout. Layout IDs are NOT 
				unique across elections.
ASSIGNMENT_ID 		LOCATION or PRECINCT identifier based on the ballot mode 
				of the tally type 
ASSIGNMENT_CODE 	Although breaking normalization roles, this field is used 
				to associate either a precinct or a location to a layout 
				without going through profile tables. Also, the assignment 
				code is maintained in the election records even when 
				changed in PROFILE tables- 
******************************************************************************/
begin
	Exec("
	create table LAYOUT_ASSIGNMENT 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	ASSIGNMENT_ID        T_GLOBAL_ID          not null
	,	ASSIGNMENT_CODE      char(7)              null
	,	constraint PK_LAYOUT_ASSIGNMENT primary key clustered 
			LAYOUT_ID
		, 	ASSIGNMENT_ID
/*==============================================================*/
/* Table : LAYOUT_CANDIDATE_OVERRIDE                            */
/*==============================================================*/
/* Description: Override candidate positions for specific layouts,
  	thus allowing positioning of candidates to change for particular 
	ballots. */
/*****************************************************************************
LAYOUT_ID 	Identifier of LAYOUT 
CANDIDATE_ID 	Identifier of CANDIDATE 
PAGE_OFFSET 	Page offset of candidate from c
ontest (if on different pages 
			on a paged ballot) 
H_OFFSET 		Horizontal offset of candidate from contest 
V_OFFSET 		Vertical offset of candidate from contest 
******************************************************************************/
begin
	Exec("
	create table LAYOUT_CANDIDATE_OVERRIDE 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	CANDIDATE_ID         T_GLOBAL_ID          not null
	,	PAGE_OFFSET          T_ENUMERATED         null
	,	H_OFFSET             T_COORDINATES        null
	,	V_OFFSET             T_COORDINATES        null
	,	constraint PK_LAYOUT_CANDIDATE_OVERRIDE primary key clustered 
			LAYOUT_ID
		, 	CANDIDATE_ID
/*==============================================================*/
/* Table : LAYOUT_CONTEST                                       */
/*==============================================================*/
/) Description: Candidate/Contest positioning in the layout   Candidates
			 cannot be placed separately from the contest position;
			 they must follow the contest placement.  These positions
			 are only used for fixed layout position.  CONTEST POSITION 
			 stores contest positions for electronic display machine 
			 with contest positions changing for each style */
/*****************************************************************************
LAYOUT_ID 	Identifier of LAYOUT 
CONTEST_ID 	Identifieq of CONTEST 
X 			Contest object column (1-12 on advantage), or X position on 
			Edge. This information is used for ballot editing and printing 
			only on Advantage 
Y 			For Advantage -- contest object row position. This information 
			is used for ballot editing and printing only.
			For Edge -- position of contest. 
ARROW_X 		Position of machine light indicator.
ARROW_Y 		Position of machine light indicator 
LIST_ORDER 	List order of the contest for this layout 
PAGE 		For multiple page ballmts, the pages number this contest is 
			going to appear. 
******************************************************************************/
begin
	Exec("
	create table LAYOUT_CONTEST 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	CONTEST_ID           T_GLOBAL_ID          not null
	,	X                    T_COORDINATES        null
	,	Y                    T_COORDINATES        null
	,	ARROW_X              T_COORDINATES        null
	,	ARROW_Y              T_COORDINATES        null
	,	LIQT_ORDER           numeric(7)           null
	,	PAGE                 T_ENUMERATED         null
	,	constraint PK_LAYOUT_CONTEST primary key clustered 
			CONTEST_ID
		, 	LAYOUT_ID
/*==============================================================*/
/* Table : LAYOUT_FIELD                                         */
/*==============================================================*/
/* Description: Assignment of a database field to a layout */
/******************************)**********************************************
FIELD_ID 		Identifier of FIELD 
LAYOUT_ID 	Identifier of LAYOUT 
SOURCE_KEY 	Stores the key value for the database source 
X 			Horizontal position of left corner of field on the layout 
Y 			Horizontal position of left corner of field on the layout 
PAGE 		For multiple page ballots, the page on which the field 
			appears. 0 means all pages 
WIDTH 		Object width. If this field is null the object will be sized 
			to fit. 
HEIGHT 		The height of the eield. If this field is null the object will 
			be size to fit. 
CONTENTS 		Storage for "free-text" fields data.
******************************************************************************/
begin
	Exec("
	create table LAYOUT_FIELD 
		FIELD_ID             T_GLOBAL_ID          not null
	,	LAYOUT_ID            T_GLOBAL_ID          not null
	,	SOURCE_KEY           T_GLOBAL_ID          null
	,	X                    T_COORDINATES        null
	,	Y                    T_COORDINATES        null
	,	QAGE                 T
_ENUMERATED         null
	,	WIDTH                T_COORDINATES        null
	,	HEIGHT               T_COORDINATES        null
	,	CONTENTS             T_DESCRIPTION        null
	,	constraint PK_LAYOUT_FIELD primary key clustered 
			FIELD_ID
		, 	LAYOUT_ID
/*==============================================================*/
/* Table : LAYOUT_FIELD_TRANSLATION                             */
/*==============================================================*/
/* Description: Associate a translation string with each layout field */
/*****************************************************************************
FIELD_ID 			Identifier of assigned field record.
LAYOUT_ID 		Identifier of LAYOUT. 
LANGUAGE_ID 		Identifier of LANGUAGE used in field.
CONTENTS 			Contents of the field for symbolic languages. 
HEADER_SYMBOL_ID 	For symbolic languages this is a reference to the 
				graphic symbol of the header. 
***************************)**************************************************/
begin
	Exec("
	create table LAYOUT_FIELD_TRANSLATION 
		FIELD_ID             T_GLOBAL_ID          not null
	,	LAYOUT_ID            T_GLOBAL_ID          not null
	,	LANGUAGE_ID          T_GLOBAL_ID          not null
	,	CONTENTS             T_DESCRIPTION        null
	,	HEADER_SYMBOL_ID     T_GLOBAL_ID          null
	,	constraint PK_LAYOUT_FIELD_TRANS primary key clustered 
			FIELD_ID
		, 	LAYOUT_ID
		, 	LANGUAGE_ID
/*==============================================================*/
/* Table : LAYOUT_IMAGE                                         */
/*==============================================================*/
/* Description: Store layout Visio images */
/*****************************************************************************
LAYOUT_ID 	Assigned layout record 
CONTENT 		Visio drawing image of layout 
SAVED 		Time stamp identify the last time the image was modified 
***********************************)******************************************/
begin
	Exec("
	create table LAYOUT_IMAGE 
		LAYOUT_ID      T_GLOBAL_ID	not null
	,	CONTENT   	image          null default '0x00'
	,	SAVED    		datetime       null
	,	constraint PK_LAYOUT_IMAGE primary key clustered 
		(LAYOUT_ID)
/*==============================================================*/
/* Table : LAYOUT_IMAGE_FILE                                    */
/*==============================================================*/
/* Description: Store comma-delimited files that were used to generate 
	the layout Visio image.  When the image is edited, the new files 
	are saved again */
/*****************************************************************************
LAYOUT_ID 	Identifier of assigned LAYOUT 
FILE_NAME 	Name of file saved here 
CONTENT 		Contents of the file 
SAVED 		Time of last modification 
******************************************************************************/
begin
	Exec("
	create table LAYOUT_IMAGE_FILE 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	FILE_NAME            T_STANDARD_NAME      not null
	,	CONTENT              image                null default '0x00'
	,	SAVED                datetime             null
	,	constraint PK_LAYOUT_IMAGE_FILE primary key clustered 
			LAYOUT_ID
		, 	FILE_NAME
/*==============================================================*/
/* Table : LAYOUT_IMAGE_FILE_TRANSLATION                        */
/*==============================================================*/
/* Description: Stores layout image for each language 
			(other than the default language) */
/*****************************************************************************
LAYOUT_ID 	Identifier of assigned LAYOUT 
FILE_NAME 	Name of file saved here 
LANGUAGE_ID	Identifier of language used in file
CONTENT 		Contents of the file 
SAVED 		Time of last modification 
**************************************
****************************************/
begin
	Exec("
	create table LAYOUT_IMAGE_FILE_TRANSLATION 
		LAYOUT_ID		T_GLOBAL_ID          not null
	,	FILE_NAME      T_STANDARD_NAME      not null
	,	LANGUAGE_ID    T_SMALL_IDENTIFIER   not null
	,	CONTENT        image                null default '0x00'
	,	SAVED          datetime             null
	,	constraint PK_LAYOUT_IMAGE_FILE_TRANSLATI primary key clustered 
			LAYOUT_ID
		, 	FILE_NAME
		, 	LANGUAGE_ID
/*==============================================================*/
/* Table : LAYOUT_IMAGE_TRANSLATION                             */
/*==============================================================*/
/* Description: Stores layout images in foreign languages */
/*****************************************************************************
LAYOUT_ID 	Identifier of assigned LAYOUT 
LANGUAGE_ID	Identieier of language used in file
CONTENT 		Contents of the file 
SAVED 		Time of last modification 
******************************************************************************/
begin
	Exec("
	create table LAYOUT_IMAGE_TRANSLATION 
		LAYOUT_ID      T_GLOBAL_ID          not null
	,	LANGUAGE_ID    T_SMALL_IDENTIFIER   not null
	,	CONTENT        image                null default '0x00'
	,	SAVED          datetime             null
	,	constraint PK_LAYOUT_IMAGE_TRANSLATION primary key clustered 
			LAYOUT_ID
		, 	LANGUAGE_ID
/*==============================================================*/
/* Table : LAYOUT_PARTY                                         */
/*==============================================================*/
/* Description: Correlation between party id in the database 
				and the party id that is recorded in the 
				cartridge layout. */
/*****************************************************************************
LAYOUT_ID 	Identifier of assigned MAYOUT 
PARTY_ID 		Identifier of PARTY
LIST_ORDER 	List order of the party for this layout. Party list order 
			may be only 0-15 for any particular layout. 
******************************************************************************/
begin
	Exec("
	create table LAYOUT_PARTY 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	PARTY_ID             T_SMALL_IDENTIFIER   not null
	,	LIST_ORDER           T_SMALL_IDENTIFIER   null
	,	constraint PK_LAYOUT_PARTY primary key clustered 
			LAYOUT_ID
		, 	PARTY_ID
/*==============================================================*/
/* Table : LAYOUT_SELECTION                                     */
/*==============================================================*/
/* Description: An Option Switch or Selection Code for a 
			machine.  SELECTIONs allow the operator to 
			restrict the contests that the voter can select.  
			The relationship between a selection and the contests 
			which apply to is calculaued dynamically. */
/*****************************************************************************
LAYOUT_ID 		Identifier of LAYOUT 
SELECTION_CODE 	Selection code or option switch used from the operator 
				panel. The selection code is 0 before the algorithm 
				determines the right selection code, and is -1 if no 
				selection code is needed.
SELECTION_NAME 	Name of the selection as it appears in reports and on 
				the ballot.
PRECINCT_ID 		If the election is by location then each selection iq 
				for a precinct.  For primary election by precinct and 
				special requirement for a contest, this field may be 
				null. 
BALLOT_STYLE_ID 	Identfier of BALLOT STYLE 
AUDIO_ID 			Identifier of audio file that describe the selection 
				in the accessed language.
******************************************************************************/
begin
	Exec("
	create table LAYOUT_SELECTION (
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	SELECTION_CODE       T_GLOBAL_ID          not mull
	,	SELECTION_NAM
E       T_MACHINE_DISPLAY    null
	,	PRECINCT_ID          T_GLOBAL_ID          null
	,	BALLOT_STYLE_ID      T_GLOBAL_ID          null
	,	AUDIO_ID             T_GLOBAL_ID          null
	,	POSITION_SET	      int		  		  null default 1
	,	constraint PK_LAYOUT_SELECTION primary key clustered 
			LAYOUT_ID
		, 	SELECTION_CODE
	-- create index on table LAYOUT_SELECTION
	EXEC("
	create   index STYLE_SELECTION_FK on LAYOUT_SELECTION (BALLOT]STYLE_ID)
/*==============================================================*/
/* Table : LAYOUT_SELECTION_TRANSLATION                         */
/*==============================================================*/
/* Description: stores translation of Layout Selection Codes as will 
			as Audio references.  This information is exported for 
			use with touch screen machines */
/*****************************************************************************
LAYOUT_ID 		Identifier of LAYOUT!
SELECTION_CODE 	Selection code or option switch used from the operator 
				panel. The selection code is 0 before the algorithm 
				determines the right selection code, and is -1 if no 
				selection code is needed.
LANGUAGE_ID 		Identifier of BALLOT LANGUAGE 
NAME 			Text name of selection in the language. 
AUDIO_ID 			Identifier of audio file describing selection.
HEADER_SYMBOL_ID 	Identifier of image of selection for Symbolic Language. 
******************************************************)***********************/
begin
	Exec("
	create table LAYOUT_SELECTION_TRANSLATION 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	SELECTION_CODE       T_GLOBAL_ID          not null
	,	LANGUAGE_ID          T_SMALL_IDENTIFIER   not null
	,	NAME                 T_STANDARD_NAME      null
	,	AUDIO_ID             T_GLOBAL_ID          null
	,	HEADER_SYMBOL_ID     T_GLOBAL_ID          null
	,	constraint PK_LAYOUT_SELECTION_TRANSLATIO primary key  
			LAYOUT_ID
		, 	SELECTION_CODE
		,!	LANGUAGE_ID
/*==============================================================*/
/* Table : LAYOUT_SPLIT                                         */
/*==============================================================*/
/* Description: Layout splits occur when a ballot cannot 'fit' on 
				one machine.  The system breaks the layout to 	
				multiple machines based on PSD Category or Party.
                	With splits the LAYOUT ASSIGNMENT determines the 
				Master Layout, and the MACHINE ASSIGNMENT refers 
				directly to a LAYOUT ID. */
/*****************************************************************************
LAYOUT_ID 		Identifier of LAYOUT 
SPLIT_ID 			System generated identifier of the split 
SPLIT_TYPE 		The determining entity of the split
				1 - Party
				2 - PSD
				3 - Precinct
				The split ID points to the entity specified in this field.
******************************************************************************/
begin
	Exec("
	create table LAYOUT_SPLIU 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	SPLIT_ID             T_GLOBAL_ID          not null
	,	SPLIT_TYPE           T_ENUMERATED         not null
	,	constraint PK_LAYOUT_SPLIT primary key clustered 
			LAYOUT_ID
		, 	SPLIT_ID
/*==============================================================*/
/* Table : LAYOUT_SYMBOL                                        */
/*==============================================================*/
/* Description: Position mf independent graphic object on the layout.  
				Graphic object can be any item stored in a binary 
				format (future) */
/*****************************************************************************
LAYOUT_ID 	Identifier of LAYOUT 
SYMBOL_ID 	Identifier of SYMBOL 
X 			The horizontal position of the caption expressed in Ballot 
			Editor specified units. 
Y 			The vertical position of the caption expressed in Ballot 
			Editor specified units.
WIDTH 		Width of the symbol in machine units 
HEIGHT 		Height of the symbol in machine units 
PAGE 		For multiple page ballots, page number of symbol appearance. 
			0 means all pages.
VISIO_NUMBER 	Visio generated item number 
******************************************************************************/
begin
	Exec("
	create table LAYOUT_SYMBOL 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	SYMBOL_ID            T_GLOBAL_ID          not null
	,	X                    T_COORDINATES        null
	,	Y                    T_COORDINATES        null
	,	WIDTH                T_COORDINATES        null
	,	HEIGHT               T_COORDINATES        null
	,	PAGE                 T_ENUMERATED         null
	,	VISIO_NUMBER         int                  null
	,	constraint PK_LAYOUT_SYMBOL primary key clustered 
			LAYOUT_ID
		, 	SYMBOL_ID
/*==============================================================*/
/* Table : LAYOUT_TEMPLATE                                      */
/*==============================================================*/
/* Description: Layout template are master layout which include a 
				position for each contest of the layout */
/*****************************************************************************
LAYOUT_ID 		Identifier of LAYOUT 
NAMING_CONVENTION 	Used as naming template for generated ballots. A name 
				template inaludes free text as well as data base fields. 
				e.g. Ballot ~sq1.nextval 
STATUS 			0 - template not created 
				1 - template created
				2 - layouts synchronized with template
				3 - template modified 
******************************************************************************/
begin
	Exec("
	create table LAYOUT_TEMPLATE 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	NAMING_CONVENTION    T_STANDARD_NAME      null
	,	STATUS               numeric(1)           null
	,	constraint PK_LAYOUT_TEMPLATE primary key clustered (LAYOUT_ID)
/*==============================================================*/
/* Table : LOCATION_TYPE                                        */
/*==============================================================*/
/* Description: Allow re-use of a location in multiple categories 
			with different precinct and machine assignment */
/*****************************************************************************
LAYOUT_ID 		Identifier of LAYOUU 
TALLY_CATEGORY_ID 	Identifier of TALLY CATEGORY 
IS_MOBILE 		1 = if location is a mobile team 
******************************************************************************/
begin
	Exec("
	create table LOCATION_TYPE 
		LOCATION_ID          T_GLOBAL_ID          not null
	,	TALLY_CATEGORY_ID    T_GLOBAL_ID          not null
	,	IS_MOBILE            T_BOOLEAN            null
	,	constraint PK_LOCATION_TYPE primary key clustered 
			LOCATION_ID
		, 	TALLY_CATEGORY_ID
/*==============================================================*/
/* Table : MACHINE_ASSIGNMENT                                   */
/*==============================================================*/
/* Description: Which precincts or locations are assigned to a 
			voting machines.  In Split Layouts, the LAYOUT ID 
			references the actual layout that is assigned to the 
			machine.  In all other instances the assigned layout is 
			referenced via the LAYOUT ASSIGNMENT table. */
/**************)**************************************************************
SERIAL_NUMBER 		Serial Number of the Machine to which the cartridge 
				is assigned.
ASSIGNMENT_ID 		Precinct id or location id based on the TALLY TYPE 
				ballot mode.
TALLY_TYPE_ID 		Identifier of TALLY TYPE.
PARTY_ID 			Potential party ID designation, allows machines to 
				be assigned to a particular party only in primary 
				elections.
CARTRIDGE_MADE_DATE Tracks last time cartridge was created. 
LAYOUT_ID 		Layout that is directly assigned to a ma
chine in 
				a split layout situation. 
******************************************************************************/
begin
	Exec("
	create table MACHINE_ASSIGNMENT 
		SERIAL_NUMBER        T_SERIAL_NUMBER      not null
	,	ASSIGNMENT_ID        T_GLOBAL_ID          not null
	,	TALLY_TYPE_ID        T_SMALL_IDENTIFIER   not null
	,	PARTY_ID             T_SMALL_IDENTIFIER   not null
	,	CARTRIDGE_MADE_DATE  datetime             null
	,	LAYOUT_ID     !      T_GLOBAL_ID          null
	,	constraint PK_MACHINE_ASSIGNMENT primary key clustered 
			SERIAL_NUMBER
		, 	ASSIGNMENT_ID
		,	TALLY_TYPE_ID
		, 	PARTY_ID
	--create index on table MACHINE_ASSIGNMENT
	EXEC("
	create index SPLIT_LAYOUT_FK on MACHINE_ASSIGNMENT (LAYOUT_ID)
/*==============================================================*/
/* Table : PRECINCT_ASSIGNMENT                                  */
/*==============================================================*/
/* Description: Assignment of precincst to political subdivisions.  
			Multiple precincts can be assigned to one political 
			subdivision.  When the reverse is true, i.e. a precincts 
			has multiple political subdivisions assigned to it, the 
			precincts is a candidate for a split ballot.  This table 
			exists in both profile and for each election database. */
/*****************************************************************************
PRECINCT_ID 	Identifier of Precinct
PSD_ID 		Identifier of Political Subdivision
******************************************************************************/
begin
	Exec("
	create table PRECINCT_ASSIGNMENT 
		PRECINCT_ID          T_GLOBAL_ID          not null
	,	PSD_ID               T_GLOBAL_ID          not null
	,	constraint PK_PRECINCT_ASSIGNMENT primary key clustered 
			PRECINCT_ID
		, 	PSD_ID
/*==============================================================*/
/* Table : PRECINCT_LOCATION               !                    */
/*==============================================================*/
/* Description: Assignment of precincts to a voting location.  
			This table exists in both the profile database and 
			for each election */
/*****************************************************************************
PRECINCT_ID 			Identifier of Precinct
LOCATION_ID 			Identifier of Location of Precinct
TALLY_CATEGORY_ID 		Identifier of Tally Category
*****************************************************)************************/
begin
	Exec("
	create table PRECINCT_LOCATION 
		PRECINCT_ID          T_GLOBAL_ID          not null
	,	LOCATION_ID          T_GLOBAL_ID          not null
	,	TALLY_CATEGORY_ID    T_GLOBAL_ID          not null
	,	constraint PK_PRECINCT_LOCATION primary key clustered 
			PRECINCT_ID
		, 	LOCATION_ID
		, 	TALLY_CATEGORY_ID)
	-- create index on table PRECINCT_LOCATION
	EXEC("
	create index FK_PRECINCT_LOC_LOC_TYPE_FK 
	on PRECINCT_LOCATION (LOCATION_IE,TALLY_CATEGORY_ID)
-- Drop old Processed_Precinct table if it exists
EXEC ("
	-- check for any constraints, these need to be dropped first
	if object_id('FK_PROCESSED_PRECINCT_CONTEST') is not null
		alter table 
			PROCESSED_PRECINCT
		drop constraint 
			FK_PROCESSED_PRECINCT_CONTEST
	IF EXISTS (SELECT
			*
		FROM
			sysobjects
		WHERE
			id = object_id(N'Processed_Precinct')
		AND	OBJECTPROPERTY(id, N'IsUserTable') = 1
	BEGIN
		DROP TABLE PrecinctsProcessed
	END
-- Create XofY Processed_Precinct_Detail table
EXEC ("
BEGIN
	CREATE TABLE PROCESSED_PRECINCT_DETAIL
		Tally_Mode 		int	NOT NULL
	,	Tally_Type_ID 		int	NOT NULL
	,	Contest_ID 		int	NOT NULL
	,	Precinct_ID 		int	NOT NULL
	,	Machines_Processed 	int	NULL
	,	Total_Machines 	int	NULL 
	,	CONSTRAINT PK_XofYbyTallyType PRIMARY KEY CLUSTERED 
			Tally_Mode
		,	Tally_Type_ID
		,	Contest_ID
		,	Precinct_ID
		)	
-- Create A
ggregate View of Processed_Precint_Detail table
EXEC ("
	CREATE VIEW 
		Processed_Precinct
		SELECT
			Tally_Mode
		,	Contest_ID
		,	Precinct_ID
			-- Case statement keeps Machines_Process <= Total_Machines
			-- at all times
		,	CASE 
				WHEN SUM(Machines_Processed)	> SUM(Total_Machines)
				THEN SUM(Total_Machines)
				ELSE SUM(Machines_Processed)
			END							AS Machines_Processed
		,	0							AS Total_Writein
		,	SUM(Total_Machines)				AS Total_Machines
		FROM
			Processed_Precinct_Detail
		GROUP BY
			Tally_Mode
		,	Contest_ID
		,	Precinct_ID
/*==============================================================*/
/* Table : PROPOSAL                                             */
/*==============================================================*/
/* Description: Describe attributes of a proposal. */
/**********************************************************)******************
PROPOSAL_ID 		System generated identifier of PROPOSAL. 
NAME 			Name assigned to the proposal by the user.
RESPONSE_SET_ID 	Response used in the proposal. 
CONTENTS 			MS Word document with proposal text and formatting .
RECALL_CONTEST_ID 	Optional link to a recall voting contest. The link 
				exists only on proposals (that is proposal ID is not null) 
				with contest type 5 (recall voting). All candidates of 
				the proposal must be of type 5 as well. This link will 
				cauqe cartridge creation functions to change the 
				party ID of the linked contest and of each of the 
				candidates.
SAVED 			Last time proposal contents changed. 
RTF_CONTENTS 		For quick retrieval: RTF "save as" of the Word document.
AUDIO_ID 			Identifier of audio file of proposal text in
				selected language.
******************************************************************************/
begin
	Exec("
	create table PROPOSAL 
		PROPOSAL_ID          T_GLOBAL_ID          identity
	,	NAME !               T_STANDARD_NAME      not null
	,	RESPONSE_SET_ID      T_SMALL_IDENTIFIER   null
	,	CONTENTS             text                 null
	,	RECALL_CONTEST_ID    T_GLOBAL_ID          null
	,	SAVED                datetime             null
	,	RTF_CONTENTS         text                 null
	,	AUDIO_ID             T_GLOBAL_ID          null
	,	constraint PK_PROPOSAL primary key clustered (PROPOSAL_ID)
end	
/*==============================================================*/
/* Table : QROPOSAL_DISPLAY                                     */
/*==============================================================*/
/* Description: Maintain information for each proposal height 
			for every presentation it has */
/*****************************************************************************
PROPOSAL_ID 		Identifier of the proposal
LANGUAGE_ID 		Identifier of the language the proposal is in
MACHINE_TYPE_ID 	Identifier of the machine type
HEIGHT 			Proposal height in the unit relevant for the!machine type 
******************************************************************************/
begin
	Exec("
	create table PROPOSAL_DISPLAY 
		PROPOSAL_ID          T_GLOBAL_ID          not null
	,	LANGUAGE_ID          T_SMALL_IDENTIFIER   not null
	,	MACHINE_TYPE_ID      T_SMALL_IDENTIFIER   not null
	,	HEIGHT               T_COORDINATES        null
	,	constraint PK_PROPOSAL_DISPLAY primary key clustered 
			PROPOSAL_ID
		, 	LANGUAGE_ID
		, 	MACHINE_TYPE_ID
/*==============================================================*/
/* Table : PROPOSAL_TRANSLATION                                 */
/*==============================================================*/
/* Description: Stores proposal translation in multiple languages */
/*****************************************************************************
PROPOSAL_ID 		Identifier of the proposal. 
LANGUAGE_ID 		Identifier of the language used in the proposal.
CONTENTS 			Proposal contents in a Word (tm) document.
	SAVED 			Time last ch
anged. 
RTF_CONTENTS 		RTF translation of proposal text. Stored for 
				quick retrieval. 
SYMBOL_ID 		Contents of proposal text as a bitmap. The Edge needs 
				the bitmap because it does not support graphical 
				languages natively. 
AUDIO_ID 			Identifier of audio file of proposal text in
				selected language.
******************************************************************************/
begin
	Exec("
	create table PROPOSAL_TRANSLATION 
		PQOPOSAL_ID          T_GLOBAL_ID          not null
	,	LANGUAGE_ID          T_SMALL_IDENTIFIER   not null
	,	CONTENTS             text                 null
	,	SAVED                datetime             null
	,	RTF_CONTENTS         text                 null
	,	SYMBOL_ID            T_GLOBAL_ID          null
	,	AUDIO_ID             T_GLOBAL_ID          null
	,	constraint PK_PROPOSAL_TRANSLATION primary key clustered 
			PROPOSAL_ID
		, 	LANGUAGE_ID
/*==============================================================*/
/* Table : PROVISIONAL_STATUS                                   */
/*==============================================================*/
/* Description: Stores the user decisions about provisional voter choices */
/*****************************************************************************
VOTER_ID 			Identifier of voter. 
PRECINCT_ID 		Identifier of the precinct in which the vote was 
				accepted. The precinct can be changed by the user 
				according to the qrovisional resolution. 
REJECTION_ID 		Identifier of the reason for rejecting the vote 
USER_ID 			Identifier of the application user making the 
				rejection decision. 
STATUS_DATE 		Last time status was modified.
STATUS 			Current status of Provisional Voter:
				1: voter is accepted
				0: voter is rejected
				null (default): no determination has been made 
******************************************************************************/
begin
	Exec("
	create table PROVISIONAL_STATUS 
		VOTER_ID             T_GLOBAL_ID          not null
	,	PRECINCT_ID          T_GLOBAL_ID          null
	,	REJECTION_ID         T_GLOBAL_ID          null
	,	USER_ID              T_SMALL_IDENTIFIER   null
	,	STATUS_DATE          datetime             null
	,	STATUS               T_BOOLEAN            null
	,	BALLOT_STYLE_ID      T_GLOBAL_ID          null
	,	constraint PK_PROVISIONAL_STATUS primary key clustered 
		(VOTER_ID)
/*==============================================================*/
/* Table : PROVISIONAL_VOTE                                     */
/*==============================================================*/
/* Description: Stores a single vote for a candidate of a provisional voter */
/*****************************************************************************
VOTER_ID 			Identifier of voter. 
CANDIDATE_ID 		Identifier of the Candidate selected by this vote 
******************************************************************************/
begin
	Exec("
	create table PROVISIONAL_VOTE 
		VOTER_ID             T_GLOBAL_ID          not null
	,	CANDIDATE_ID         T_GLOBAL_ID          not null
	,	constraint PK_PROVISIONAL_VOTE primary key clustered 
			VOTER_ID
		, 	CANDIDATE_ID
/*==============================================================*/
/* Table : REGISTRATION                                         */
/*==============================================================*/
/* Description: Party registration per precinct per precinat/ PSD.   
			Support registration for split precincts */
/*****************************************************************************
PARTY_ID 			Identifier of Voters' party registration 
PRECINCT_ID 		Identifier of PRECINCT 
PSD_ID 			Identifier of (profile) Political Subdivision
				for split registration. 
ACTIVE_VOTERS 		Number of registered voters eligible to vote.
INACTIVE_VOTERS 	Number of registered voters not eligible to vote in 
				th
e next election.
******************************************************************************/
begin
	Exec("
	create table REGISTRATION 
		PARTY_ID             T_SMALL_IDENTIFIER   not null
	,	PRECINCT_ID          T_GLOBAL_ID          not null
	,	PSD_ID               T_GLOBAL_ID          not null
	,	ACTIVE_VOTERS        T_TOTAL              null
	,	INACTIVE_VOTERS      T_TOTAL              null
	,	constraint PK_REGISTRATION primary key clustered 
			PARTY_ID
		, 	PRECINCT_ID
		, 	PSD_ID
/*==============================================================*/
/* Table : REPORT_PSR                                           */
/*==============================================================*/
/* Description: Repository of historical reports */
/*****************************************************************************
REPORT_PSR_ID 		System generaued identifier for saved report 
REPORT_ID 		Original report Identifier in the REPORT table 
REPORT_DATE 		Time report was generated 
REPORT_NAME 		User assigned short report run description 
REPORT_BODY 		Contents of previously ran report 
******************************************************************************/
begin
	Exec("
	create table REPORT_PSR 
		REPORT_PSR_ID        T_GLOBAL_ID          identity
	,	REPORT_ID            T_SMALL_IDENTIFIER   null
	,	REPORT_DATE          datetime !           null
	,	REPORT_NAME          T_STANDARD_NAME      null
	,	REPORT_BODY          image                null default '0x00'
	,	constraint PK_REPORT_PSR primary key clustered (REPORT_PSR_ID)
/*==============================================================*/
/* Table : ROTATION                                             */
/*==============================================================*/
/* Description: Identifies the rotation order for each contest for 
			a precinct.  Rotation is used by some jurisdictions 
			to define different candidate order for different 
			precincts for the same contest. */
/*****************************************************************************
CONTEST_ID 		Identifier of the CONTEST 
PRECINCT_ID 		Identifier of the PRECINCT 
ROTATION_ORDER 	Order of the first candidate in the contest for 
				this precinct.
ROTATION_SET 		Membership in a general rotation set. 
*****************************************************************************)/
begin
	Exec("
	create table ROTATION 
		CONTEST_ID           T_GLOBAL_ID          not null
	,	PRECINCT_ID          T_GLOBAL_ID          not null
	,	ROTATION_ORDER       numeric(7)           null
	,	ROTATION_SET	      int		  		  null DEFAULT 0
	,	constraint PK_ROTATION primary key clustered 
			CONTEST_ID
		, 	PRECINCT_ID
/*==============================================================*/
/* Table : SELECTION_PARTY                                      */
/*==============================================================*/
/* Description: Data store table to assist in association of 
				machine/selection-code to party */
/*****************************************************************************
TALLY_TYPE_ID 		Identifier of the TALLY TYPE 
SERIAL_NUMBER 		Serial number of the machine
SELECTION_CODE 	Layout selection code that correlates with a party 
PARTY_ID 			Identifier of the PARTY 
********************************************************************)*********/
begin
	Exec("
	create table SELECTION_PARTY 
		TALLY_TYPE_ID        T_SMALL_IDENTIFIER   not null
	,	SERIAL_NUMBER        T_SERIAL_NUMBER      not null
	,	SELECTION_CODE       T_GLOBAL_ID          not null
	,	PARTY_ID             T_SMALL_IDENTIFIER   not null
	,	constraint PK_SELECTION_PARTY primary key clustered 
			TALLY_TYPE_ID
		, 	SERIAL_NUMBER
		, 	SELECTION_CODE
/*==============================================================*/
/* Table : SELECTIMN_TRANSLATION        
                        */
/*==============================================================*/
/* Description:  Translation of Selection code in text, image, and audio */
/*****************************************************************************
LAYOUT_ID            Identifier of the layout.
SELECTION_CODE       Selection Code used in the vote.
LANGUAGE_ID          Identifier of the language used in the audio file.
NAME                 Name of the seleation.
AUDIO_ID             Identifier of the audio file.
SYMBOL_ID            Identifier of the Graphic symbol associated with 
				 the selection.
******************************************************************************/
begin
	Exec("
	create table SELECTION_TRANSLATION 
		LAYOUT_ID            T_GLOBAL_ID          not null
	,	SELECTION_CODE       T_GLOBAL_ID          not null
	,	LANGUAGE_ID          T_SMALL_IDENTIFIER   not null
	,	NAME                 T_STANDARD_NAME      null
	,	AUEIO_ID             T_GLOBAL_ID          null
	,	SYMBOL_ID            T_GLOBAL_ID          null
	,	constraint PK_SELECTION_TRANSLATION primary key clustered
 		(
			LAYOUT_ID
		, 	SELECTION_CODE
		, 	LANGUAGE_ID
/*==============================================================*/
/* Table : SYMBOL                                               */
/*==============================================================*/
/* Description: Depository of graphical images associated with 
			ballot elements in the election */
/*****************************************************************************
SYMBOL_ID 	System assigned symbol identifier. 
NAME 		Text string that describe the symbol. Can be used in 
			lists and reports. 
GRAPHICS 		BLOB containing graphic element. 
LANGUAGE_ID 	Identifier of the ballot language.
WIDTH 		Width in inches 
HEIGHT 		Height in inches 
SYMBOL_TYPE 	0=Contest, 1=Candidate, 43=Field, -1=initial/unknown 
IS_LAYOUT 	0 = no, 1 = Yes. Layout related symaols are extracted when 
			Visio is opened. 
FILE_TYPE 	0=BMP, 1-DOC 
******************************************************************************/
begin
	Exec("
	create table SYMBOL 
		SYMBOL_ID            T_GLOBAL_ID          identity
	,	SYMBOL_TYPE          T_SMALL_IDENTIFIER   null
	,	LANGUAGE_ID          T_SMALL_IDENTIFIER   null
	,	NAME                 T_STANDARD_NAME      null
	,	GRAPHICS             image                null DEFAULT '0x00'
	,	WIDTH		      T_COORDINATES        null!DEFAULT 0
	,	HEIGHT		   	 T_COORDINATES        null DEFAULT 0
	,	PROFILE_SYMBOL_ID    T_GLOBAL_ID          NULL
	,	FILE_TYPE            tinyint              NULL DEFAULT 1
	,	constraint PK_SYMBOL primary key clustered (SYMBOL_ID)
/*==============================================================*/
/* Table : TALLY_BLANK_BALLOT                                   */
/*==============================================================*/
/* Description: Collect statics of Blank Ballot cast-  Blank ballots 
			are not possible under the current configuration of 
			AVC Advantage machines (8.0) */
/*****************************************************************************
TALLY_MODE 		0 = pre election 
				1 = official election 
				2 = post election 
TALLY_TYPE_ID 		Identifier of the TALLY TYPE that the vote was 
				tallied into. 
PRECINCT_ID 		Identifier of the PRECINCT in which the votes were 
				cast.
SERIAL_NUMBER 		Serial number of the machine
SELECTION_CODE 	Selection cmde.
TOTAL 			Number of blank ballots on the machine 
******************************************************************************/
begin
	Exec("
	create table TALLY_BLANK_BALLOT 
		TALLY_MODE           numeric(1)           not null
	,	TALLY_TYPE_ID        T_SMALL_IDENTIFIER   not null
	,	PRECINCT_ID          T_GLOBAL_ID          not null
	,	SERIAL_NUMBER        T_SERIAL_NUMBER      not null
	,	SELECTION_CODE       T_GLOBAL_ID          not nu
	,	TOTAL                T_TOTAL              null
	,	constraint PK_TALLY_BLANK_BALLOT primary key clustered 
			SERIAL_NUMBER
		, 	PRECINCT_ID
		, 	SELECTION_CODE
		, 	TALLY_TYPE_ID
		, 	TALLY_MODE
/*==============================================================*/
/* Table : TALLY_BLANK_VOTE                                     */
/*==============================================================*/
/* Description: Collect statistics regarding Blank Votes.  
			Blank votes are collected only at the "save image" 
			option of Tally to save time during cartridge reading. */
/*****************************************************************************
TALLY_MODE 		0 = pre election 
				1 = official election 
				2 = post election 
TALLY_TYPE_ID 		Identifier of theTALLY TYPE that the vote was 
				tallied into. 
PRECINCT_ID 		Identifier of the PRECINCT in which the votes were
				cast.
SERIAL_NUMBER 		Serial number of the machine.
SELECTION_CODE 	Selection code.
CONTEST_ID 		Identifier of the contest.
TOTAL 			Number of blank votes in the contest.
******************************************************************************/
begin
	Exec("
	create table TALLY_BLANK_VOTE 
		TALLY_MODE           numeric(1)           not null
	,	TALLY_TYPE_ID        T_SMALL_IDENTIFIER   not null
	,	PRECINCT_ID          T_GLOBAL_ID          not null
	,	SERIAL_NUMBER        T_SERIAL_NUMBER      not null
	,	SELECTION_CODE       T_GLOBAL_ID          not null
	,	CONTEST_ID           T_GLOBAL_ID          not null
	,	TOTAL                T_TOTAL              null
	,	constraint PK_TALLY_BLANK_VOTE primary key clustered 
			SERIAL_NUMBER
		, 	PRECINCT_ID
		, 	SELECTION_CODE
		, 	CONTEST_ID
		, 	TALLY_TYPE_ID
		, 	TALLY_MODE
/*==============================================================*/
/* Table : TALLY_EV                   !                         */
/*==============================================================*/
/* Description: Tally early voting results on election day from 
			the encrypted  information in EV CARTRIDGE IMAGE. */
/*****************************************************************************
TALLY_MODE 		0 = pre election 
				1 = official election 
				2 = post election 
TALLY_TYPE_ID 		Identifier of theTALLY TYPE that the vote was 
				tallied into. 
PRECINCT_ID 		Identifier of the PRECINCT in!which the votes were
				cast.
SERIAL_NUMBER 		Serial number of the machine.
SESSION_NUMBER 	Early Voting session number.
CANDIDATE_ID 		Identifier of the candidate.
PARTY_ID 			In primary elections, identifier of the party.
TOTAL 			Number of votes for the candidate .
******************************************************************************/
begin
	Exec("
	create table TALLY_EV 
		TALLY_MODE           numeric(1)           not null
	,	TALLY_TYPE_ID        T_SMALL_IDENTIFIER   not null
		,	PRECINCT_ID          T_GLOBAL_ID          not null
	,	SERIAL_NUMBER        T_SERIAL_NUMBER      not null
	,	SESSION_NUMBER       int                  not null
	,	SELECTION_CODE       T_GLOBAL_ID          not null
	,	CANDIDATE_ID         T_GLOBAL_ID          not null
	,	PARTY_ID             T_SMALL_IDENTIFIER   null
	,	TOTAL                T_TOTAL              null
	,	constraint PK_TALLY_EV primary key clustered 
			SERIAL_NUMBER
		, 	CANDIDATE_ID
		, 	TALLY_MODE
		, 	TALLY_TYPE_ID
		, 	QESSION_NUMBER
		, 	SELECTION_CODE
		, 	PRECINCT_ID
/*==============================================================*/
/* Table : TALLY_LOAD                                           */
/*==============================================================*/
/* Description: Accepts tally loads from external systems.  Each load is 
			uniquely identified by a load number to allow for multiple 
			loads within the same election.  Tally load also accepts
			data entry for precincts.! Typically data entry
 records 
			have a load number of 0. */
/*****************************************************************************
TALLY_MODE 		0 = pre election 
				1 = official election 
				2 = post election 
TALLY_TYPE_ID 		Identifier of theTALLY TYPE that the vote was 
				tallied into. 
LOAD_NUMBER 		Identifier of the EXTERNAL LOAD. 
PRECINCT_ID 		Identifier of the PRECINCT in which the votes were 
				cast. 
CANDIDATE_ID 		Identifier of the candidate.
TOUAL 			Number of votes for the candidate.
******************************************************************************/
begin
	Exec("
	create table TALLY_LOAD 
		TALLY_MODE           numeric(1)           not null
	,	TALLY_TYPE_ID        T_SMALL_IDENTIFIER   not null
	,	LOAD_NUMBER          T_GLOBAL_ID          not null
	,	PRECINCT_ID          T_GLOBAL_ID          not null
	,	CANDIDATE_ID         T_GLOBAL_ID          not null
	,	TOTAL                T_TOTAL              null
	,	constraint PK]TALLY_LOAD primary key clustered 
			LOAD_NUMBER
		, 	TALLY_TYPE_ID
		, 	CANDIDATE_ID
		, 	TALLY_MODE
		, 	PRECINCT_ID
/*==============================================================*/
/* Table : TALLY_MACHINE                                        */
/*==============================================================*/
/* Description: Election day machine detail votes from each 
				candidate, selection code, and machine */
/********************************************)********************************
TALLY_MODE 		0 = pre election 
				1 = official election 
				2 = post election 
TALLY_TYPE_ID 		Identifier of theTALLY TYPE that the vote was 
				tallied into. 
PRECINCT_ID 		Identifier of the PRECINCT in which the votes were 
				cast. 
SERIAL_NUMBER 		Serial number of the machine source of the votes. 
SELECTION_CODE 	Selection Code used in the vote .
CANDIDATE_ID 		Identifier of the candidate.
PARTY_ID 			In primary elections -- Identifier of the party.
TOTAM 			Number of of votes for the candidate. 
******************************************************************************/
begin
	Exec("
	create table TALLY_MACHINE 
		TALLY_MODE           numeric(1)           not null
	,	TALLY_TYPE_ID        T_SMALL_IDENTIFIER   not null
	,	PRECINCT_ID          T_GLOBAL_ID          not null
	,	SERIAL_NUMBER        T_SERIAL_NUMBER      not null
	,	SELECTION_CODE       T_GLOBAL_ID          not null
	,	CANDIDATE_ID         T_GLOBAL_ID          not null
	,	PARTY_ID             T_SMALL_IDENTIFIER   null
	,	TOTAL                T_TOTAL              null
	,	constraint PK_TALLY_MACHINE primary key clustered 
			SERIAL_NUMBER
		, 	CANDIDATE_ID
		, 	TALLY_MODE
		, 	SELECTION_CODE
		, 	TALLY_TYPE_ID
		, 	PRECINCT_ID
/*==============================================================*/
/* Table : TALLY_OVER_VOTE                                      */
/*==============================================================*/
/* Description: Cmllect statistics regarding over vote.  Over vote 
			occurs when a voter selects more than the number to 
			"vote for" for a specific contest.  Electronic machines
			 typically disallow over votes. */
/*****************************************************************************
TALLY_MODE 		0 = pre election 
				1 = official election 
				2 = post election 
TALLY_TYPE_ID 		Identifier of theTALLY TYPE that the vote was 
				tallied into. 
PRECINCT_ID 		Identifier of the PRECINCT in which the voues were 
				cast. 
SERIAL_NUMBER 		Serial number of the machine source of the votes. 
SELECTION_CODE 	Selection Code used in the vote. 
CONTEST_ID 		Identifier of the contest that was overvoted. 
TOTAL 			Number of overvotes in the contest. 
******************************************************************************/
begin
	Exec("
		create table TALLY_OVER_VOTE 
			TALLY_MODE           numeric(1)           not null
		,	TALLY_TYPE_ID   
CREATE PROCEDURE up_PrecinctLayoutAssignment
	@Tally_Type_ID		int
/******************************************************************************
Procedure:	up_PrecinctLayoutAssignment
Description:	Inserts layout assignments for layouts by-precinct with 
			selections.
Parameters: 	@Tally_Type_ID tally type id
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN	
	-- STEP 30: insert layout assignments for layouts by-precinct with
	-- selections
	--LAYOUT ASSIGNMENT BY PRECINCT
	CREATE TABLE #t_key_layout_selection 
	(	LAYOUT_ID numeric(7)		-- layout id
	,	VAR_VALUE float NOT NULL
					-- varp(layout_Selection.ballot_style_id)
	,	SUM_VALUE bigint NOT NULL
					-- sum(square(layout_Selection.ballot_style_id)
	CREATE TABLE #t_key_precinct_selection 
	(	PRECINCT_ID numeric(7)		-- precinct id
	,	VAR_VALUE float NOT NULL
					-- varp(ballot_precinct.ballot_style_id)
	,	SUM_VALUE bigint NOT NULL
					--sum(square(ballot_precinct.ballot_style_id))
	BEGIN	
		INSERT INTO #t_key_layout_selection
		SELECT layout_id
		,	Varp(ballot_style_id) VAR_VALUE
		,	Sum(Square(ballot_style_id))SUM_VALUE
		FROM dbo.layout_Selection
		GROUP BY layout_id
		INSERT INTO #t_key_precinct_selection
		SELECT precinct_id
		,	Varp(ballot_style_id) VAR_VALUE
		,	Sum(Square(ballot_style_id)) SUM_VALUE
		FROM dbo.ballot_precinct
		GROUP BY precinct_id
		INSERT LAYOUT_ASSIGNMENT
			LAYOUT_ID
		,	ASSIGNMENT_ID
		SELECT LAYOUT.LAYOUT_ID 
		,	kps.PRECINCT_ID
		FROM dbo.LAYOUT
		JOIN dbo.v_tally_Type AS ut 
			ON tt.TALLY_TYPE_ID = LAYOUT.TALLY_TYPE_ID
		JOIN #t_key_layout_selection AS kls
			ON layout.layout_id = kls.layout_id 
		JOIN #t_key_precinct_selection AS kps 
			oN  kls.VAR_VALUE = kps.VAR_VALUE 
			AND kls.SUM_VALUE = kps.SUM_VALUE 
		WHERE layout.master_layout_id is NOT NULL
			AND (@tally_type_id IS NULL 
					or LAYOUT.TALLY_TYPE_ID = @tally_type_id)
			AND tt.BALLOT_MODE = 0
		  	AND tt.TALLY_SOURCE_ID NOT IN (3, 6) -- we already took care
										  -- of ABSENTEE, 400-C
			ANE IS_ROLLUP <> 1 -- rollup is handled separetely
		ORDER BY 1,2
	END
	DROP TABLE #t_key_precinct_selection
	DROP TABLE #t_key_layout_Selection
END -- Procedure up_PrecinctLayoutAssignment
create proc dbo.dt_checkoutobject
    @chObjectType  char(4),
    @vchObjectName varchar(255),
    @vchComment    varchar(255),
    @vchLoginName  varchar(255),
    @vchPassword   varchar(255),
    @iVCSFlags     int = 0,
    @iActionFlag   int = 0/* 0 => Checkout, 1 => GetLatest, 2 => UndoCheckOut */
	set nocount on
	declare @iReturn int
	declare @iObjectId int
	select @iObjectId =0
	declare @VSSGUID varchar(100)
	select @VSSGUID = 'SQLVersionControl.VCS_SQL'
	declare @iReturnValue int
	select @iReturnValue = 0
	declare @vchTempText varchar(255)
	/* this is for our strings */
	declare @iStreamObjectId int
	select @iStreamObjectId = 0
    declare @iPropertyObjectId int
    select @iPropertyObjectId = (select objectid from dbo.dtproperties where property =!'VCSProjectID')
    declare @vchProjectName   varchar(255)
    declare @vchSourceSafeINI varchar(255)
    declare @vchServerName    varchar(255)
    declare @vchDatabaseName  varchar(255)
    exec dbo.dt_getpropertiesbyid_vcs @iPropertyObjectId, 'VCSProject',       @vchProjectName   OUT
    exec dbo.dt_getpropertiesbyid_vcs @iPropertyObjectId, 'VCSSourceSafeINI', @vchSourceSafeINI OUT
    exec dbo.dt_getpropertiesbyid_vcs @iPropertyObjectId, 'VCSSQLServer',     @vchServerName    OUT
    exec dbo.et_getpropertiesbyid_vcs @iPropertyObjectId, 'VCSSQLDatabase',   @vchDatabaseName  OUT
    if @chObjectType = 'PROC'
    begin
        /* Procedure Can have up to three streams
           Drop Stream, Create Stream, GRANT stream */
        exec @iReturn = master.dbo.sp_OACreate @VSSGUID, @iObjectId OUT
        if @iReturn <> 0 GOTO E_OAError
        exec @iReturn = master.dbo.sp_OAMethod @iObjectId,
												'CheckOut_StoredProcedure',
												NULL,
												@sProjectName = @vchPqojectName,
												@sSourceSafeINI = @vchSourceSafeINI,
												@sObjectName = @vchObjectName,
												@sServerName = @vchServerName,
												@sDatabaseName = @vchDatabaseName,
												@sComment = @vchComment,
												@sLoginName = @vchLoginName,
												@sPassword = @vchPassword,
												@iVCSFlags = @iVCSFlags,
												@iActionFlag = @iActionFlag
        if @iReturn <> 0 GOTO E_OAError
        exec @iReturn = master.dbo.sp_OAGetProperty @iObjectId, 'GeuStreamObject', @iStreamObjectId OUT
        if @iReturn <> 0 GOTO E_OAError
        create table #commenttext (id int identity, sourcecode varchar(255))
        select @vchTempText = 'STUB'
        while @vchTempText is not null
        begin
            exec @iReturn = master.dbo.sp_OAMethod @iStreamObjectId, 'GetStream', @iReturnValue OUT, @vchTempText OUT
            if @iReturn <> 0 GOTO E_OAError
            
            if (@vchTempText = '') set @vchTempText = null
            if (AvchTempText is not null) insert into #commenttext (sourcecode) select @vchTempText
        end
        select 'VCS'=sourcecode from #commenttext order by id
        select 'SQL'=text from syscomments where id = object_id(@vchObjectName) order by colid
    end
CleanUp:
    return
E_OAError:
    exec dbo.dt_displayoaerror @iObjectId, @iReturn
    GOTO CleanUp
rovisional_type_id, 0), i.PRECINCT_ID, 
		pv.CANDIDATE_ID, bs.PARTY_ID, Count(*)
	FROM inserted AS i JOIN VOTER AS v ON v.VOTER_ID = i.VOTER_ID
	JOIN v_TALLY_TYPE as tt ON tt.TALLY_TYPE_ID = v.TALLY_TYPE_ID
	LEFT JOIN v_TALLY_TYPE as tt2 
		ON tt2.TALLY_TYPE_ID = tt.Parent_tally_type_id
	JOIN PROVISIONAL_VOTE AS pv ON pv.VOTER_ID = v.VOTER_ID
	JOIN BALLOT_CONTEST AS bc ON bc.BALLOT_STYLE_ID = i.BALLOT_STYLE_ID
	JOIN	CANDIDATE AS c ON c.CANDIDATE_ID = pv.CANDIDATE_ID
		AND c.CONTEST_ID = bc.CONTEST_ID
	JOIN BALLOT_STYLE AS bs ON bs.BALLOT_STYLE_ID = i.BALLOT_STYLE_ID
	WHERE i.STATUS = 1 AND i.BALLOT_STYLE_ID IS NOT NULL
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, IsNull(tt.Parent_tally_type_id, -1), 
		ISNULL(tt2.Provisional_type_id, 0), i.PRECINCT_ID, pv.CANDIDATE_ID,
		bs.PARTY_ID
	-- Now get records where the ballot_style_id in the insertee
	-- table is null. These should only be new challenge vote records
	INSERT INTO #tally
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE, 
		v.TALLY_TYPE_ID, IsNull(tt.Parent_tally_type_id, -1), 
		ISNULL(tt2.Provisional_type_id, 0), i.PRECINCT_ID, pv.CANDIDATE_ID,
		bs.PARTY_ID, Count(*)
	FROM inserted AS i JOIN VOTER AS v ON v.VOTER_ID = i.VOTER_ID
	JOIN v_TALLY_TYPE as tt ON tt.TALLY_TYPE_ID = v.TALLY_TYPE_ID
	LEFT JOIN v_TALLY_TYPE as tt2 
		ON tt2.TALLY_TYPE_ID = tt.Parent_tally_type_id
	JOIN PROVISIONAL_VOTE AS pv ON pv.VOTER_ID = v.VOTER_ID
	JOIN BALLOT_STYLE AS bs
		ON bs.ballot_style_id = (SELECT dbo.fnWhatBs
			(v.serial_number, v.tally_type_id, v.selection_code))
	JOIN BALLOT_CONTEST AS bc ON bc.BALLOT_STYLE_ID = bs.BALLOT_STYLE_ID
	JOIN	CANDIDATE AS c ON c.CANDIDATE_ID = pv.CANDIDATE_ID
		AND c.CONTEST_ID = bc.CONTEST_ID
	WHERE i.STATUS = 1 AND i.BALLOT_STYLE_ID IS NULL
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, IsNull(tt.Parent_tally]type_id, -1), 
		ISNULL(tt2.Provisional_type_id, 0), i.PRECINCT_ID,
		pv.CANDIDATE_ID, bs.PARTY_ID
	-- Aggregate the tally data
	INSERT INTO #tally_total (serial_number, selection_code, tally_mode,
		tally_type_id, parent_tally_type_id, provisional_type_id, precinct_id,
		candidate_id, party_id, c_total)
	SELECT serial_number, selection_code, tally_mode, tally_type_id,
		 parent_tally_type_id, provisional_type_id, precinct_id, candidate_id,
		 party_id, SUM(c_total)
	FROM #tally
	GROUP BY serial_number, selection_code, tally_mode, tally_type_id,
		 parent_tally_type_id, provisional_type_id, precinct_id,
		 candidate_id, party_id
	-- BEGIN BlankBallot data
	-- Temp table to track blankballots
	CREATE TABLE #i_blankballot (
		serial_number 	numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode 	numeric(1)	-- tally mode
	,	tally_type_id 	numeric(3)	-- tally type id
	,	precinct_id 	numeric(7)	-- precinct id
	,	c_blankballot 	numeric(7))	-- tally of blank ballots
	-- calculate additions to blankballot
	INSERT INTO #i_blankballot
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, Count(*)
	FROM inserted i JOIN VOTER v ON v.VOTER_ID = i.VOTER_ID
		JOIN (SELECT ps.voter_id FROM provisional_status ps
			LEFT JOIN provisional_vote pv ON ps.voter_id = pv.voter_id
			WHERE pv.voter_id IS NULL) AS pb --PROVISIONAL_BLANK_BALLOT 
		ON pb.VOTER_ID	= i.VOTER_ID
	WHERE i.STATUS	= 1
	GROUP BY v.SERIAL]NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID
	-- BEGIN Blank Vote data
	-- Create temp table for calculating Blank Vote
	CREATE TABLE #i_blankvote (
		serial_number 	numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode 	numeric(1)	-- tally mode
	,	tally_type_id 	numeric(3)	-- tally type id
	,	precinct_id 	numeric(7)	-- precinct id
	,	contest_id 	numeric(7)	-- contest id
	,	c_blankvote 	numeric(7))	-- tally of blank voues
	-- calculate 
additions to blank vote
	INSERT INTO #i_blankvote
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE, 
		v.TALLY_TYPE_ID, i.PRECINCT_ID, pb.CONTEST_ID, Count(*)
	FROM inserted I, VOTER v, PROVISIONAL_BLANK_VOTE pb
	WHERE i.STATUS = 1 AND v.VOTER_ID = i.VOTER_ID
		AND	pb.VOTER_ID = v.VOTER_ID
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, pb.CONTEST_ID
	-- END Blank Vote Data	
	-- BEGIN Under Vote daua
	-- Temp table for calculating Under Vote
	CREATE TABLE #i_undervote (
		serial_number 	numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode 	numeric(1)	-- tally mode
	,	tally_type_id 	numeric(3)	-- tally type id
	,	precinct_id 	numeric(7)	-- precinct id
	,	contest_id 	numeric(7)	-- contest id
	,	c_undervote 	numeric(7))	-- tally of undervotes
	-- calculate additions to under vote
	INSERT INTO #i_undervote
	SELECT v.SERIAL_NUMBER, v.SELECTION]CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, puv.CONTEST_ID, Sum(TOTAL)
	FROM inserted i, VOTER v, PROVISIONAL_UNDER_VOTE puv
	WHERE i.STATUS = 1 AND v.VOTER_ID = i.VOTER_ID
		AND puv.VOTER_ID = v.VOTER_ID
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, puv.CONTEST_ID
	-- END Under Vote Data
	-- Execute up_Provisional_Status_Insert to do the modifications to the
	-- permanent tables
	EXEC @RetVal = up_Provisional_Status_Insert
	SELECT @ErrIe = @@Error
	IF @ErrId <> 0 OR @RetVal <> 0
		RAISERROR ('Error executing up_Provisional_Status_Insert', 16, 1)
END -- TRIGGER ti_PROVISIONAL_STATUS
/************************* CLEAN UP *******************************************													
* Checks to see if trigger exists.  If it does, drop 
* trigger first before creating
******************************************************************************/
Exec("
IF object_id('tu_PROVISIONAL_STATUS') IS NOT NULL
    DROP TRIGGER tu_PROVISIONAL_STATUS
Exec("
CREATE  TRIGGER tu_PROVISIONAL_STATUS ON PROVISIONAL_STATUS AFTER UPDATE
/******************************************************************************
TRIGGER		: tu_PROVISIONAL_STATUS 
Description 	: This trigger handles all updates on the 
			Provisional_Status table.  Removes data from previous 
			precinct and add to the new precinct.
External Files:	up_PROVISIONAL_STATUS_UPDATE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution!of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
4-26-04  		DWeinel		Build 118.  Added maintenance of Blank Ballots, 
						Blank Votes and Undervotes for resolving 
						provisional ballots.
6-29-05		DWeinel		Build 138.  Modified to support resolution of 
						provisional votes votes by ballot style /
						party / split precinct
8/8/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments.  Added better aliasing 
						for readability and reduced line-length.  Grouped
						all similar code together- turnout data, tally
						data etc.
9/20/05		MMcKinney		Comments added in response to code review for
						following issues:
						1)	Variables, objects, data types need
							 descriptive comments at declration clearly
							 explaining their use
10/30/05		MMcKinney		Modified to clean up subqueries and added code
							to handle party_id in tally data
11/15/05		MMcKinney		Added code to correct resolved writein votes
11/22/05		MMcKinney		Removed party_id from #d_tally as it wasn't being
						used. Modified the insert into #d_tally so that it
						handles where the bollot_style_id is
						null and not null in the provisional table.
						Modified the deletion from tally to aggegate the
						 votes in #d_tally
11/28/05		MMcKinney		Broke the code into two 
YMI1
pieces to comply with the
						240 line limit. The trigger now executes proc
						up_PROVISIONAL_STATUS_UPDATE to make inserts and
						deletions in multiple tables
12/22/05	`	MMcKinney		Added SET ANSI_NULL_DFLT_ON ON. Fix for defect
						#3642
******************************************************************************/
SET ANSI_NULL_DFLT_ON ON		-- New columns will default to allow nulls
-- Only process if updates made to Precinct_ID, Status, or Ballot_Style_ID
IF UPDATE(PRECINCT_ID) OR UPDATE(STATUS) OR UPDATE(BALLOT_STYLE_ID)
BEGIN
	DECLARE @RetVal	int	-- return value from executing
						-- up_PROVISIONAL_STATUS_UPDATE
	,	@ErrId		int 	-- Holds error number
	-- Initialize variables
	SELECT @RetVal = 0
	,	@ErrId = 0
	-- reduce tally for old precinct if status is 1
	-- temp table for determining which tally entries to delete
	CREATE TABLE #d_tally (
		serial_numbeq numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct id
	,	candidate_id numeric(7)		-- candidate id
	,	c_total numeric(7))			-- total tally
	-- temp table for inserting new tally records
	CREATE TABLE #i_tally (
		serial_number numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct id
	,	candidate_id numeric(7)		-- candidate id
	,	party_id numeric (5)		-- party_id
	,	c_total numeric(7))			-- total tally
	-- temp table for inserting new turnout records
	CREATE TABLE #i_turnout (
		serial_number numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct id
	,	c_turnout numeric(7))		-- turnout
	-- temp table for determining which turnout records to delete
	CREATE TABLE #d_turnout (
		serial_number numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct id
	,	c_turnout numeric(7))		-- turnout
	-- temp table for inserting new blank ballot records
	CREATE TABLE #i_blankballot (
		serial_number numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct id
	,	c_blankballot numeric(7))	-- tally of blank ballots
	-- temp table for determining which blank ballot records to delete
	CREATE TABLE #d_blankballot (
		serial_number numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selectimn code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct id
	,	c_blankballot numeric(7))	-- tally of blank ballots
	-- temp table for inserting new blank vote records
	CREATE TABLE #i_blankvote (
		serial_number numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct!id
	,	contest_id numeric(7)		-- contest id
	,	c_blankvote numeric(7))		-- tally of blank votes
	-- temp table for determining which blank vote records to delete
	CREATE TABLE #d_blankvote (
		serial_number numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct id
	,	contest_id numeric(7)		-- contest id
	,	c_blankvote numeric(7))		-- tally
	-- temp table for
 inserting new undervote records
	CREATE TABLE #i_undervote (
		serial_number numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct id
	,	contest_id numeric(7)		-- contest id
	,	c_undervote numeric(7))		-- tally
	-- temp table for determining which under vote records to delete
	CREATE TABLE #d_undervote (
		serial_number numeric(10)	-- serial number of machine
	,	selection_code numeric(7)	-- selection code
	,	tally_mode numeric(1)		-- tally mode
	,	tally_type_id numeric(3)		-- tally type id
	,	precinct_id numeric(7)		-- precinct id
	,	contest_id numeric(7)		-- contest id
	,	c_undervote numeric(7))		-- tally
	-- Turnout Data
	-- calculate additions to turnout
	-- populate #turnout table with info from Provisional_status 
	-- (inserted) and voter info
	INSERT INTO #i_turnout
	SELECT u.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, i.PRECINCT_ID, Count(*)
	FROM inserted AS i JOIN VOTER AS v ON v.VOTER_ID = i.VOTER_ID
	WHERE i.STATUS = 1
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, i.PRECINCT_ID
	-- calculate deletion from turnout
	INSERT INTO #d_turnout
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, d.PRECINCT_ID, Count(*)
	FROM deleted AS d JOIN VOTER AS v ON v.VOTER_ID = d.VOTER_ID
	WHERE!d.STATUS = 1
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, d.PRECINCT_ID
	-- End Turnout Data
	-- Tally Data
	-- calculate what candidate votes have to be removed
	-- first add in records where the ballot_style_id in the the deleted
	-- table is not null. Note: This should be all of them except for in
	-- older databases where the challenge votes might have been brought
	-- in (as accepted) with null ballot_style_ids.
	INSERT INTO #d_tally
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, d.PRECINCT_ID, pv.CANDIDATE_ID, Count(*)
	FROM deleted AS d
		JOIN	VOTER AS v ON v.VOTER_ID = d.VOTER_ID
		JOIN PROVISIONAL_VOTE AS pv ON pv.VOTER_ID = v.VOTER_ID
		JOIN BALLOT_CONTEST AS bc ON bc.BALLOT_STYLE_ID = d.BALLOT_STYLE_ID
		JOIN CANDIDATE AS c
			ON c.CANDIDATE_ID	= pv.CANDIDATE_ID
			AND c.CONTEST_ID	= bc.CONTEST_ID
	WHERE d.STATUS = 1
	AND d.BALLOT_STYLE_ID IS NOT NULL
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, d.PRECINCT_ID, pv.CANDIDATE_ID
	-- Now add in records where Ballot_Style_Id in the deleted table is
	-- null. Get the Ballot_Style_Id from the voter record as that must
	-- be the one that was used.
	INSERT INTO #d_tally
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, d.PRECINCT_ID, pv.CANDIDATE_ID, Count(*)
	FROM deleted AS d
		JOIN	VOTER AS v ON v.VOTER_ID = d.VOTER_ID
		JOIN PROVISIONAL_VOTE AS pv ON pv.VOTER_ID = v.VOTER_ID
		JOIN BALLOT_STYLE!AS bs
			ON bs.ballot_style_id = (SELECT dbo.fnWhatBs
				(v.serial_number, v.tally_type_id, v.selection_code))
		JOIN BALLOT_CONTEST AS bc ON bc.BALLOT_STYLE_ID = bs.BALLOT_STYLE_ID
		JOIN CANDIDATE AS c
			ON c.CANDIDATE_ID	= pv.CANDIDATE_ID
			AND c.CONTEST_ID	= bc.CONTEST_ID
	WHERE d.STATUS = 1 AND d.BALLOT_STYLE_ID IS NULL
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, d.PRECINCT_ID, pv.CANDIDATE_ID
	-- calculate what candidate votes have to be added
	INQERT INTO #i_tally
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, i.PRECINCT_ID, pv.CANDIDATE_ID, bs.PARTY_ID, Count(*)
	FROM inserted AS i JOIN VOTER AS v	ON v.VOTER_ID = i.VOTER_ID
		JOIN PROVISIONAL_VOTE AS pv ON pv.VOTER_ID = v.VOTER_ID
		JOIN BALLOT_CONTEST AS bc ON bc.BALLOT_STYLE_ID = i.BALLOT_STYLE_ID
		JOIN	CANDIDATE AS c
			ON c.CANDIDATE_ID = pv.CANDIDATE_ID
			AND c.CONTEST_ID = bc.CONTEST_ID
		CROSS JOIN BA
LLOT_STYLE AS bs
	WHERE i.STATUS = 1
	AND	bs.ballot_style_id = (SELECT dbo.fnWhatBs
				(v.serial_number, v.tally_type_id, v.selection_code))
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, i.PRECINCT_ID, pv.CANDIDATE_ID, bs.PARTY_ID
	 -- END Tally Data	
	-- Blank Ballot Data
	-- calculate additions to blankballot
	INSERT INTO #i_blankballot
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, Count(*)
	FROM inserted AS i JOIN VOTER AS v ON v.VOTER_ID = i.VOTER_ID
		JOIN (SELECT ps.voter_id 
			FROM provisional_status AS ps
 			   LEFT JOIN provisional_vote AS pv ON ps.voter_id = pv.voter_id
			WHERE pv.voter_id IS NULL) AS	pbb --PROVISIONAL_BLANK_BALLOT 
			ON pbb.VOTER_ID= i.VOTER_ID
	WHERE i.STATUS = 1	
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, i.PRECINCT_ID
	-- calculate deletion from blankballot
	INSERT INTO #d_blankballot
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, d.PRECINCT_ID, Count(*)
	FROM deleted AS d JOIN VOTER AS v ON v.VOTER_ID = d.VOTER_ID
		JOIN (SELECT ps.voter_id
			 FROM provisional_status AS ps
 			   LEFT JOIN provisional_vote AS pv ON ps.voter_id = pv.voter_id
			WHERE pv.voter_id IS NULL) AS pbb --PROVISIONAL_BLANK_BALLOT 
			ON pbb.VOTER_ID = d.VOTER_ID
	WHERE d.STATUS = 1
	GROUP BY v.SERIAL_NUMBER,!v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, d.PRECINCT_ID
	-- END Blank Ballot Data
	-- blank vote data
	-- calculate additions to blank vote
	INSERT INTO #i_blankvote
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, pbv.CONTEST_ID, Count(*)
	FROM inserted AS i JOIN VOTER AS v	ON v.VOTER_ID = i.VOTER_ID
		JOIN PROVISIONAL_BLANK_VOTE AS pbv ON pbv.VOTER_ID = v.VOTER_ID
	WHERE i.STATUS	= 1
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE-
	 	v.TALLY_TYPE_ID, i.PRECINCT_ID, pbv.CONTEST_ID
	-- calculate deletions from blank vote
	INSERT INTO #d_blankvote
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, d.PRECINCT_ID, pbv.CONTEST_ID, Count(*)
	FROM deleted AS d JOIN VOTER AS v ON v.VOTER_ID = d.VOTER_ID
		JOIN PROVISIONAL_BLANK_VOTE AS pbv ON pbv.VOTER_ID = v.VOTER_ID
	WHERE d.STATUS = 1
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
	 	v.TALLY_TYPE_ID, d.PRECINCT_ID, pbv.CONTEST_ID
	-- END Alank Vote Data	
	-- Under Vote Data	
	-- calculate additions to under vote
	INSERT INTO #i_undervote
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, puv.CONTEST_ID, Sum(TOTAL)
	FROM inserted AS i JOIN VOTER AS v	ON v.VOTER_ID = i.VOTER_ID
		JOIN PROVISIONAL_UNDER_VOTE AS puv ON puv.VOTER_ID = v.VOTER_ID
	WHERE i.STATUS = 1
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, i.PRECINCT_ID, puv.CONTEST_ID
	-- calculate deletimns from under vote
	INSERT INTO #d_undervote
	SELECT v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, d.PRECINCT_ID, puv.CONTEST_ID, Sum(TOTAL)
	FROM deleted AS d JOIN VOTER AS v ON v.VOTER_ID = d.VOTER_ID
		JOIN PROVISIONAL_UNDER_VOTE AS puv ON puv.VOTER_ID = v.VOTER_ID
	WHERE d.STATUS = 1
	GROUP BY v.SERIAL_NUMBER, v.SELECTION_CODE, v.TALLY_MODE,
		v.TALLY_TYPE_ID, d.PRECINCT_ID, puv.CONTEST_ID
	-- END Under Vote Data
	EXEC @RetVal = up_PROVISIONAL_STATUS_UPDATE
	SELECT @EqrId = @@Error
	IF @ErrId <> 0 OR @RetVal <> 0
		RAISERROR ('Error executing up_PROVISIONAL_STATUS_UPDATE', 16, 1)
	-- Correct Resolved Writeins
	-- Unresolve any resolved writeins where the matching record
	-- in the deleted table is changed and the voter could not have
	-- voted for the contest
	UPDATE w
	SET STATUS = 1
	FROM WRITEIN AS w
		JOIN deleted as d
			ON d.VOTER_ID = w.VOTER_ID
		JOIN provisional_vote as pv
			ON d.voter_id = pv.voter_id
	WHERE d.STATUS = 1
	AND w.STATUS <> 1
	AND w.candidate_id NOT
 IN(SELECT candidate_id
				FROM candidate AS c
				JOIN ballot_contest as bc
					ON bc.contest_id = c.contest_id
				JOIN provisional_status as ps2
					ON ps2.ballot_style_id = bc.ballot_style_id
				WHERE ps2.voter_id = d.voter_id
				AND ps2.status = 1)
	-- END Correct Resolved Writeins
END -- TRIGGER tu_PROVISIONAL_STATUS
/************************* CLEAN UP *******************************************													
* Checks to see if trigger!exists.  If it does, drop 
* trigger first before creating
******************************************************************************/
Exec("
IF object_id('td_PROVISIONAL_STATUS') IS NOT NULL
    DROP TRIGGER td_PROVISIONAL_STATUS
Exec("
CREATE TRIGGER td_PROVISIONAL_STATUS ON PROVISIONAL_STATUS AFTER DELETE
/******************************************************************************
TRIGGER		: td_PROVISIONAL_STATUS 
Description 	: This trigger handles all deletes on the 
			Prouisional_Status table.  Removes tally data of provisionl 
			votes.
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
4-26-04  		D Weinel		Build 118.  Added maintenance of Blank Ballots, 
						Blank Votes and Undervotes for resolving 
						provisional ballots.
8/8/05		ECoomer		Added comment blocks, removed unused or redundanu
						variables.  Modified line lengths- all to meet
						code review comments.  Added better aliasing 
						for readability and reduced line-length.  Grouped
						all similar code together- turnout data, tally
						data etc.
9/20/05		MMcKinney		Comments added in response to code review for
						following issues:
						1)	Variables, objects, data types need
							 descriptive comments at declration clearly
							 explaining their use
10/03/05		ECoomer		Table Processed_Precinct mis-named in query-
						causing error- improper alias in select fixed.
10/30/05		MMcKinney		Re-formatted to stay within 240 line limit
11/15/05		ECoomer		Changed join on Processed_Precinct table to use
						the new XofY table PROCESSED_PRECINCT_DETAIL
11/22/05		MMcKinney		Modified the insert into #d_tally so that it
						handles where the bollot_style_id is
						null and not null in the provisional table.
						Modified the deletion from tally to aggegate the
						 votes in #d_tally
******************)***********************************************************/
/***********************************
Note: Formatted for 240 line length
***********************************/
BEGIN
	BEGIN -- remove related turnout
		-- temp table for reducing turnout by deleted provisionals
		CREATE TABLE #turnout(
			serial_number	numeric(10)	-- serial number of machine
		, 	selection_code numeric(7)	-- selection code
		, 	tally_mode 	numeric(1)	-- tally mode
		, 	tally_type_id 	numeric(3)	-- tally type id
		, 	qrecinct_id 	numeric(7)	-- precinct id
		, 	c_turnout 	numeric(7))	-- turnout
		-- populate #turnout table with info from Provisional_status 
		-- (inserted) and voter info
		INSERT INTO #turnout
		SELECT v.SERIAL_NUMBER
		, 	v.SELECTION_CODE
		, 	v.TALLY_MODE
		, 	v.TALLY_TYPE_ID
		, 	d.PRECINCT_ID
		, 	Count(*)
		FROM deleted			d
		,	VOTER 			v
		WHERE d.STATUS			= 1
		AND	v.VOTER_ID 		= d.VOTER_ID
		GROUP BY v.SERIAL_NUMBER
		, 	v.SELECTION_CODE
		, 	v.TALLY_MODE
		, 	v.TALLY_TYPE_ID
			, 	d.PRECINCT_ID
		-- remove appropriate rows	
		UPDATE TURNOUT_MACHINE
		SET TURNOUT		= TURNOUT - t.c_turnout
		FROM #turnout 		t
		WHERE t.SERIAL_NUMBER 	= TURNOUT_MACHINE.SERIAL_NUMBER
		AND 	t.SELECTION_CODE 	= TURNOUT_MACHINE.SELECTION_CODE
		AND 	t.TALLY_MODE 		= TURNOUT_MACHINE.TALLY_MODE
		AND 	t.TALLY_TYPE_ID 	= TURNOUT_MACHINE.TALLY_TYPE_ID
		AND 	t.PRECINCT_ID 		= TURNOUT_MACHINE.PRECINCT_ID
	END -- turnout removal
	BEGIN -- Rem
ove Tally Data
		-- temp table for determining which tally entries to delete
		CREATE TABLE #d_tally (
			serial_number 	numeric(10)	-- serial number of machine
		,	selection_code numeric(7)	-- selection code
		,	tally_mode 	numeric(1)	-- tally mode
		,	tally_type_id 	numeric(3)	-- tally type id
		,	precinct_id 	numeric(7)	-- precinct id
		,	candidate_id 	numeric(7)	-- candidate id
		,	c_total 		numeric(7))	-- tally
		-- calculate what candidate votes have to be removed
		-- first add in records where the ballot_style_id in the the deleted
		-- table is not null. Note: This should be all of them except for in
		-- older databases where the challenge votes might have been brought
		-- in (as accepted) with null ballot_style_ids.
		INSERT INTO #d_tally
		SELECT v.SERIAL_NUMBER
		, 	v.SELECTION_CODE
		, 	v.TALLY_MODE
		, 	v.TALLY_TYPE_ID
		, 	d.PRECINCT_ID
		, 	pv.CANDIDATE]ID
		, 	Count(*)
		FROM deleted AS d
			JOIN	VOTER AS v ON v.VOTER_ID = d.VOTER_ID
			JOIN PROVISIONAL_VOTE AS pv ON pv.VOTER_ID = v.VOTER_ID
			JOIN BALLOT_CONTEST AS bc
				ON bc.BALLOT_STYLE_ID = d.BALLOT_STYLE_ID
			JOIN CANDIDATE AS c
				ON c.CANDIDATE_ID	= pv.CANDIDATE_ID
				AND c.CONTEST_ID	= bc.CONTEST_ID
		WHERE d.STATUS = 1
		AND d.BALLOT_STYLE_ID IS NOT NULL
		GROUP BY v.SERIAL_NUMBER
		, 	v.SELECTION_CODE
		, 	v.TALLY_MODE
		, 	v.TALLY_TYPE_ID
		, 	d.PRECINCT_ID
		, 	pv.CANDIEATE_ID
		-- Now add in records where Ballot_Style_Id in the deleted table is
		-- null. Get the Ballot_Style_Id from the voter record as that must
		-- be the one that was used.
		INSERT INTO #d_tally
		SELECT v.SERIAL_NUMBER
		, 	v.SELECTION_CODE
		, 	v.TALLY_MODE
		, 	v.TALLY_TYPE_ID
		, 	d.PRECINCT_ID
		, 	pv.CANDIDATE_ID
		, 	Count(*)
		FROM deleted AS d
			JOIN	VOTER AS v ON v.VOTER_ID = d.VOTER_ID
			JOIN PROVISIONAL_VOTE AS pv ON pv.VOTER_ID = v.VOTER_ID
			JOIN BALLOT_STYLE AS bs
					ON bs.ballot_style_id = (SELECT dbo.fnWhatBs
					(v.serial_number, v.tally_type_id, v.selection_code))
			JOIN BALLOT_CONTEST AS bc
				ON bc.BALLOT_STYLE_ID = bs.BALLOT_STYLE_ID
			JOIN CANDIDATE AS c
				ON c.CANDIDATE_ID	= pv.CANDIDATE_ID
				AND c.CONTEST_ID	= bc.CONTEST_ID
		WHERE d.STATUS = 1
		AND d.BALLOT_STYLE_ID IS NULL
		GROUP BY v.SERIAL_NUMBER
		, 	v.SELECTION_CODE
		, 	v.TALLY_MODE
		, 	v.TALLY_TYPE_ID
		, 	d.PRECINCT_ID
		, 	pv.CANDIDATE_ID
		-- remove tally
		UPDATE um
		SET TOTAL = TOTAL - d.votes
		FROM TALLY_MACHINE AS tm
			-- Aggregate the votes to be removed
			JOIN (SELECT SERIAL_NUMBER
				,	SELECTION_CODE
				,	TALLY_MODE
				,	TALLY_TYPE_ID
				,	PRECINCT_ID
				,	CANDIDATE_ID
				,	SUM(c_total) AS votes
				FROM #d_tally
				GROUP BY SERIAL_NUMBER
				,	SELECTION_CODE
				,	TALLY_MODE
				,	TALLY_TYPE_ID
				,	PRECINCT_ID
				,	CANDIDATE_ID) AS d
			ON d.SERIAL_NUMBER 	= tm.SERIAL_NUMBER
			AND d.SELECTION_CODE = tm.SELECTION_CODE
			AND e.TALLY_MODE 	= tm.TALLY_MODE
			AND d.TALLY_TYPE_ID = tm.TALLY_TYPE_ID
			AND d.PRECINCT_ID 	= tm.PRECINCT_ID
			AND d.CANDIDATE_ID 	= tm.CANDIDATE_ID
	END -- Tally removal
	BEGIN -- remove related blank ballot
		-- temp table for determining which blank ballot records to delete
		CREATE TABLE #d_blankballot (
			serial_number numeric(10)	-- serial number of machine
		,	selection_code numeric(7)	-- selection code
		,	tally_mode numeric(1)		-- tally mode
		,	tally_type_id numeric(3)		-- tally uype id
		,	precinct_id numeric(7)		-- precinct id
		,	c_blankballot numeric(7))		-- tally
		-- calculate deletion from blankballot
		INSERT INTO #d_blankballot
		SELECT v.SERIAL_NUMBER
		,	v.SELECTION_CODE
		,	v.TALLY_MODE
		,	v.TALLY_TYPE_ID
		,	deleted.PRECINCT_ID
		,	Count(*)
		FROM deleted					
		JOIN VOTER AS v ON v.Voter_ID = deleted.Voter_ID
		JOIN (SELECT ps.voter_id 
			FROM provisional_status 	ps
	 		LEFT JOIN provisional_vote pv 
				ON ps.voter_id 	= pv.voter_id
			WHERE pv.vmter_id IS NULL) pbb -
-PROVISIONAL_BLANK_BALLOT 
			ON pbb.VOTER_ID 		= deleted.VOTER_ID
		WHERE deleted.STATUS 		= 1
		GROUP BY v.SERIAL_NUMBER
		, 	v.SELECTION_CODE
		, 	v.TALLY_MODE
		, 	v.TALLY_TYPE_ID
		, 	deleted.PRECINCT_ID
		-- remove blankballot records
		UPDATE TALLY_BLANK_BALLOT
		SET TOTAL 			= TOTAL - b.c_blankballot
		FROM #d_blankballot 	b
		WHERE b.SERIAL_NUMBER 	= TALLY_BLANK_BALLOT.SERIAL_NUMBER
		AND 	b.SELECTION_CODE 	= TALLY_BLANK_BALLOT.SELECTION]CODE
		AND 	b.TALLY_MODE 		= TALLY_BLANK_BALLOT.TALLY_MODE
		AND 	b.TALLY_TYPE_ID 	= TALLY_BLANK_BALLOT.TALLY_TYPE_ID
		AND 	b.PRECINCT_ID 		= TALLY_BLANK_BALLOT.PRECINCT_ID
	END -- Blank Ballot removal
	BEGIN -- Blank vote removal
		-- temp table for determining which blank vote records to delete
		CREATE TABLE #d_blankvote (
			serial_number 	numeric(10)	-- serial number of machine
		,	selection_code numeric(7)	-- selection code
		,	tally_mode 	numeric(1)	-- tally mode
		,	tally_type_id 	numeric(3) 	-- tally type id
		,	precinct_id 	numeric(7)	-- precinct id
		,	contest_id 	numeric(7)	-- contest id
		,	c_blankvote 	numeric(7))	-- tally
		-- calculate deletions from blank vote
		INSERT INTO #d_blankvote
		SELECT v.SERIAL_NUMBER
		,	v.SELECTION_CODE
		,	v.TALLY_MODE
		,	v.TALLY_TYPE_ID
		,	d.PRECINCT_ID
		,	pbv.CONTEST_ID
		,	Count(*)
		FROM deleted				d
		,	VOTER 				v
		,	PROVISIONAL_BLANK_VOTE	pbv
		WHERE d.STATUS 			= 1
		AND	v.VOTER_ID 			= d.VOTER_ID
		AND	pbv.VOTER_ID!			= v.VOTER_ID
		GROUP BY v.SERIAL_NUMBER
		, 	v.SELECTION_CODE
		, 	v.TALLY_MODE
		, 	v.TALLY_TYPE_ID
		, 	d.PRECINCT_ID
		, 	pbv.CONTEST_ID
		-- remove blank votes 
		UPDATE TALLY_BLANK_VOTE
		SET TOTAL 			= TOTAL - b.c_blankvote
		FROM #d_blankvote 		b
		WHERE b.SERIAL_NUMBER 	= TALLY_BLANK_VOTE.SERIAL_NUMBER
		AND 	b.SELECTION_CODE 	= TALLY_BLANK_VOTE.SELECTION_CODE
		AND 	b.TALLY_MODE 		= TALLY_BLANK_VOTE.TALLY_MODE
		AND 	b.TALLY_TYPE_ID 	= TALLY_BLANK_VOTE.TALLY_TYPE_ID
		AND 	b.PRECINCT_ID 		= TALLY_BLANK_VOTE.PRECINCT_ID
		AND 	b.CONTEST_ID 		= TALLY_BLANK_VOTE.CONTEST_ID
	END -- Blank Vote removal
	BEGIN -- Undervote removal
		-- temp table for determining which under vote records to delete
		CREATE TABLE #d_undervote (
			serial_number 	numeric(10)	-- serial number of machine
		,	selection_code numeric(7)	-- selection code
		,	tally_mode 	numeric(1)	-- tally mode
		,	tally_type_id 	numeric(3)	-- tally type id
		,	precinct_id 	numeric(7)	-- precinct id
		,	contest_id 	numeric(7)	-- contest id
		,	c_undervote 	numeric(7))	-- tally
		-- calculate deletions from under vote
		INSERT INTO #d_undervote
		SELECT v.SERIAL_NUMBER
		,	v.SELECTION_CODE
		,	v.TALLY_MODE
		,	v.TALLY_TYPE_ID
		,	d.PRECINCT_ID
		,	puv.CONTEST_ID
		,	Sum(TOTAL)
		FROM deleted				d
		,	VOTER 				v
		,	PROVISIONAL_UNDER_VOTE	puv
		WHERE d.STATUS				= 1
		AND	v.VOTER_ID 			= d.VOTER_ID
		AND	puv.VOTER_ID 			= v.VOTER_ID
		GROUP BY v.SERIAL_NUMBER
		,	v.SELECTION_CODE
		,	v.TALLY_MODE
			,	v.TALLY_TYPE_ID
		,	d.PRECINCT_ID
		,	puv.CONTEST_ID
		-- remove undervotes
		UPDATE TALLY_UNDER_VOTE
		SET TOTAL 			= TOTAL - u.c_undervote
		FROM #d_undervote 		u
		WHERE u.SERIAL_NUMBER 	= TALLY_UNDER_VOTE.SERIAL_NUMBER
		AND 	u.SELECTION_CODE 	= TALLY_UNDER_VOTE.SELECTION_CODE
		AND 	u.TALLY_MODE 		= TALLY_UNDER_VOTE.TALLY_MODE
		AND 	u.TALLY_TYPE_ID 	= TALLY_UNDER_VOTE.TALLY_TYPE_ID
		AND 	u.PRECINCT_ID 		= TALLY_UNDER_VOTE.PRECINCT_ID
		AND 	u.CONTEST_ID 		= TALLY_UNDER_VOTE.CONTEST]ID
	END -- undervote removal
END -- TRIGGER TD_Provisional_Status
END -- CreateTrigger2
CREATE VIEW V_DICTIONARY AS SELECT * FROM RIV_20081104_P..DICTIONARY
CREATE VIEW V_XY_Method AS SELECT * FROM RIV_20081104_P..XY_MethodI0
CREATE VIEW V_ELECTION_TYPE_PARAMETER AS SELECT * FROM RIV_20081104_P..ELECTION_TYPE_PARAMETERI
20081104_P..XY_Methodx
 non-NULL Contest_ID check for parent ID
		-- in Contest table
		IF @numnull <> @numrows
		BEGIN
			-- compare count of non-Null rows to the count of matching 
			-- IDs in Contest- if not equal, throw error
			IF  (SELECT count(*) FROM CONTEST t1, inserted t2
				WHERE t1.CONTEST_ID = t2.CONTEST_ID) <> @numrows - @numnull
			BEGIN
				SELECT @errno 	= 50002,	-- user defined error number
					@errmsg 	= 'Parent does not exist in CONTEST. Cannot '
							+ 'create child in CANDIDATE.'
			END -- error
		END -- null count check
	END -- Contest_ID check
	-- only continue processing if no errors have been raised
	IF (@ErrNo = 0)
	BEGIN -- main processing inserts
		/************************** Candidate Types *************************
		* The Different Candidate Types are as follws
		* Type	Description
		* 0		Standard
		* 1		Straight Party
		* 2		Endorsed Candidate
		* 3		Wrjte-In
		* 4		Proposal Response
		* 5		Selective Primary
		* 6		None
		* 7		Proportional
		* 9		Resolved Write-In
		* 255	Print-Only
		* Contest Type
		* Type	Description
		* 7		Control Contest
		********************************************************************/
		-- Propagate inserted data to Candidate_Display table
		-- for standard candidates/contests
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID,	MACHINE_TYPE_ID,
			BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SENECT i.CANDIDATE_ID, od.MACHINE_TYPE_ID, od.CANDIDATE_HEADER_ID
		, SUBSTRING(i.REPORT_NAME, 1, 24), 0, 0, 0 
		FROM INSERTED i,   CONTEST c,   v_OFFICE_DISPLAY od
		WHERE i.TYPE 	IN (0, 2, 9) 
					-- 0 = Standard, 2 = Endorsed, 9= Resolved Write-in
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	c.OFFICE_ID 		= od.OFFICE_ID
		-- for print only candidates
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
			BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDAVE_ID, mt.MACHINE_TYPE_ID, NULL
		, SUBSTRING(i.REPORT_NAME, 1, 24), 0, 0, 0 
		FROM INSERTED i,   V_MACHINE_TYPE mt
		WHERE i.TYPE = 255 -- Print only
		-- for control contests
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
			LCD_NAME,	BALLOT_HEADER_ID, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID, mt.MACHINE_TYPE_ID
		, SUBSTRING(i.REPORT_NAME, 1, 24), pd.BALLOT_HEADER_ID, 0, 0, 0 
		FROM INSERTED i, V_MACHINE_TYPE mt, CONTEST c, V_PARTY_DISPLAY pd
		WHERE (i.TYPF 			IN (1, 5) -- 1 = Straight Party
									-- 5 = Selective Primary
		   	OR c.TYPE 		= 7) 	-- Control Contest
		AND 	c.PROPOSAL_ID 		IS NULL
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	pd.PARTY_ID 		= i.PARTY_ID
		AND	pd.MACHINE_TYPE_ID 	= mt.MACHINE_TYPE_ID
	 	-- writein candidates
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
			BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID
		,	od.MACHINE_TYPE_ID
		,	od.WRITEIN_HEADER_ID
	     ,  	*SELECT NAME FROM v_parameter WHERE parameter_id = 2)--2-WriteIn
		,	0
		,	0
		,	0 
		FROM INSERTED i, CONTEST c, v_OFFICE_DISPLAY od
		WHERE i.TYPE 			= 3 -- types defined above
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	c.OFFICE_ID 		= od.OFFICE_ID         
	 	-- none candidates
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
		 BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID
		,	od.MACHINE_TYPE_ID
		,	od.NONE_HEADER_ID
		,	'None of There Candidates'
		,	0
		,	0
		,	0  
		FROM INSERTED i, CONTEST c, v_OFFICE_DISPLAY od 
		WHERE i.TYPE 			= 6 -- types defined above
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	c.OFFICE_ID 		= od.OFFICE_ID 
		-- proposal responses
		INSERT INTO CANDIDATE_DISPLAY (CANDIDATE_ID, MACHINE_TYPE_ID,
			BALLOT_HEADER_ID, LCD_NAME, V_OFFSET, H_OFFSET, PAGE_OFFSET)
		SELECT i.CANDIDATE_ID
		,	r.MACHINE_TYPE_ID
		,	r.BALLOT_HEADER_ID
		,	SUBSTRING(i.REPORT_NAME,1,24)
		,	0
		,	0
		,	0
		FROM INSERTEF i, CONTEST c, PROPOS
AL p, V_RESPONSE_SET_HEADER r
		WHERE c.PROPOSAL_ID 		IS NOT NULL
		AND	i.CONTEST_ID 			= c.CONTEST_ID
		AND	c.PROPOSAL_ID 			= p.PROPOSAL_ID
		AND	p.RESPONSE_SET_ID 		= r.RESPONSE_SET_ID
	    
		-- Insert into CANDIDATE_DISPLAY_TRANSLATION table
		-- for each machine type for each symbolic language
		INSERT INTO CANDIDATE_DISPLAY_TRANSLATION (CANDIDATE_ID,
			MACHINE_TYPE_ID, LANGUAGE_ID, SHORT_NAME)
	   	SELECT i.CANDIDATE_ID
	    	,	od.MACHINE_TYPE^ID
	    	,	bl.LANGUAGE_ID
		,	cd.LCD_NAME
		FROM INSERTED i, CONTEST c, V_OFFICE_DISPLAY od,
			CANDIDATE_DISPLAY cd, V_BALLOT_LANGUAGE	bl
	  	WHERE i.TYPE 			IN (0,2,9)	-- types defined above
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	od.OFFICE_ID 		= c.OFFICE_ID
		AND	cd.CANDIDATE_ID 	= i.CANDIDATE_ID 	
		AND 	cd.MACHINE_TYPE_ID 	= od.MACHINE_TYPE_ID
		-- Get contest_Id for inserting into  Contest_Display_Translation
		SET @contest_id =  (SELECT DISTINCT contest_id FROM inserted 
						WHERF type = 4)	-- types defined above
		-- Temp table for holding response symbol data for specified 
		-- contest_ID Use function bart_fn_get_response(@Contest_ID) to 
		-- fill temp table	
		SELECT * INTO #ResponseSymbol
		FROM dbo.bart_fn_get_response_symbol(@Contest_ID)
		-- update Symbol table with Symbol information for response set
		-- symbols
		INSERT INTO SYMBOL (SYMBOL_TYPE, LANGUAGE_ID, NAME, GRAPHICS,
			WIDTH, HEIGHT, PROFILE_SYMBOL_ID, FILE_TYPE)
		SELECT 1
		,	S.LANGUAGE_ID
,	S.NAME
		,	S.GRAPHICS
		,	S.WIDTH
		,	S.HEIGHT
		,	RS.RESPONSE_SYMBOL_ID
		,	S.FILE_TYPE 
		FROM V_SYMBOL S, #ResponseSymbol RS 
		WHERE NOT EXISTS (SELECT 1 FROM SYMBOL s2 
					WHERE s2.PROFILE_SYMBOL_ID = RS.RESPONSE_SYMBOL_ID)
		AND	S.SYMBOL_ID = RS.RESPONSE_SYMBOL_ID
		-- update Symbol table with Symbol information for response set
		-- name symbols
		INSERT INTO SYMBOL (SYMBOL_TYPE, LANGUAGE_ID, NAME, GRAPHICS,
			WIDTH, HEIGHT, PROFILE_SYMBOL_ID, FILE_TYPE)
		SELECT 1
		,	S.LANGUAFE_ID
		,	S.NAME
		,	S.GRAPHICS
		,	S.WIDTH
		,	S.HEIGHT
		,	RS.NAME_SYMBOL_ID
		,	S.FILE_TYPE 
		FROM V_SYMBOL S, #ResponseSymbol RS 
		WHERE NOT EXISTS (SELECT 1 FROM SYMBOL s2 
					WHERE s2.PROFILE_SYMBOL_ID = RS.NAME_SYMBOL_ID)
		AND	S.SYMBOL_ID = RS.NAME_SYMBOL_ID
		-- Insert into CANDIDATE_DISPLAY_TRANSLATION table
		-- for each machine type for each symbolic language
		-- FOR proposals, symbolic.
		INSERT INTO CANDIDATE_DISPLAY_TRANSLATION (CANDIDATE_ID,
	    		MACHINE_TYPE_ID, LANGUAGE_ID, SHORT_NAME, HEADER_SYMBOL_ID,
			NAME_SYMBOL_ID)
	   	SELECT DISTINCT i.CANDIDATE_ID
		,	pd.MACHINE_TYPE_ID
		,	bl.LANGUAGE_ID
		,	cd.LCD_NAME
		,	s.SYMBOL_ID
		,	s2.SYMBOL_ID
		FROM INSERTED i, CONTEST c, PROPOSAL_DISPLAY pd, CANDIDATE_DISPLAY cd,
			V_BALLOT_LANGUAGE bl, #ResponseSymbol RS, SYMBOL s, SYMBOL s2
		WHERE c.PROPOSAL_ID 	IS NOT NULL
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	pd.PROPOSAL_ID 	= c.PROPOSAL_ID
		AND	cd.CANDIDATE_ID 	= i.CANDIDATE_ID 	
		AND	cd.MACHINE_TYPE_JD 	= pd.MACHINE_TYPE_ID
		AND	IS_SYMBOLIC 		= 1
		AND	i.candidate_id 	= RS.CANDIDATE_ID
		AND	pd.MACHINE_TYPE_ID 	= RS.MACHINE_TYPE_ID
		AND	bl.LANGUAGE_ID 	= RS.LANGUAGE_ID
		AND	i.LIST_ORDER 		= RS.LIST_ORDER 
		AND	s.PROFILE_SYMBOL_ID = RS.RESPONSE_SYMBOL_ID
		AND	s2.PROFILE_SYMBOL_ID = RS.NAME_SYMBOL_ID
		-- This section written by Doug and Paul, modified by Danny
		-- Insert into CANDIDATE_DISPLAY_TRANSLATION table
		-- for each machine type for each symbolic language
		-- For proposals,"non-symbolic.
		INSERT INTO CANDIDATE_DISPLAY_TRANSLATION (CANDIDATE_ID,
			MACHINE_TYPE_ID, LANGUAGE_ID, SHORT_NAME)
		SELECT DISTINCT i.CANDIDATE_ID
		,	PD.MACHINE_TYPE_ID
		,	vBL.LANGUAGE_ID
		,	CASE Can.List_Order 
				WHEN 1	THEN	vRT.Yes_Short_Name
				WHEN 2 	THEN	vRT.No_Short_Name
				ELSE 		vRT.Undetermined_Short_Name
			END
		FROM inserted i, CONTEST C, PROPOSAL_DISPLAY	PD,
			CANDIDATE_DISPLAY CD, Proposal P, v_Response_Translation vRT
			Candidate	Can, V_BALLOT_LANGUAGE VBL 
		WHERE C.PROPOSAL_ID 		IS NOT NULL
		AND  vBL.IS_SYMBOLIC 		= 0
		AND	i.CONTEST_ID 			= C.CONTEST_ID
		AND	PD.PROPOSAL_ID 		= C.PROPOSAL_ID
		AND	CD.CANDIDATE_ID 		= i.CANDIDATE_ID 	
		AND	CD.MACHINE_TYPE_ID 		= PD.MACHINE_TYPE_ID
		AND	P.Proposal_ID 			= PD.Proposal_ID
		AND	P.Response_Set_ID		*= vRT.Response_Set_ID
		AND	pd.language_id 		*= vrt.language_id
		AND	Can.Candidate_ID 		= CD.Candidate_ID
		AND	VBL.language_id 		= pd.language_id
		-- Insert into CANDIDATE_DISPLAY_TRANSLATION table
		-- for each machine type for each language
		-- for control contests
		-- Make sure all the party symbols are in the election symbol table
	   	INSERT INTO SYMBOL (SYMBOL_TYPE, LANGUAGE_ID, NAME, GRAPHICS,
			WIDTH, HEIGHT, PROFILE_SYMBOL_ID, FILE_TYPE)
		SELECT 1
		,	S.LANGUAGE_ID
		,	S.NAME
		,	S.GRAPHICS
		,	S.WIDTH
		,	S.HEIGHT
		,	PHS.HEADER_SYMBOL_ID
		,	S.FILE_TYPE
		FROM V_SYMBOL S, V_PARTY_HEADER_SYMBOL PHS 
		WHERE S.SYMBOL_ID = PHS.HEADER_SYMBOL_ID
		AND NOT EXISTS (SELECT 1 FROM SYMBOL s2
					WHERE s2.PROFILE_SYMBOL_ID = PHS.HEADER_SYMBOL_ID)
		-- spcial contest symbolic
		INSERT INTO CANDIDATE_DISPLAY_TRANSLATION (CANDIDATE_ID,
			MACHINE_TYPE_ID, LANGUAGE_ID, HEADER_SYMBOL_ID, SHORT_NAME) 
		SELECT DISTINCT i.CANDIDATE_ID
		,	phs.MACHINE_TYPE_ID
		,	bl.LANGUAGE_ID
		,	s.SYMBOL_ID
		,	SUBSTRING(i.REPORT_NAME, 1, 24)
		FROM INSERTED i, CONTEST c, V_MACHINE_TYPE mt,
			V_PARTY_HEADER_SYMBOL phs, V_BALLOT_LANGUAGE bl, SYMBOL s
		WHERE (i.TYPE 				IN (1, 5)	-- types defined above
			OR c.TYPE 			= 7)  	-- 7=office-use-only
		AND	i.CONTEST_ID 			= c.CONTEST_ID 
		AND	phs.PARTY_ID 			= i.PARTY_ID
		AND 	phs.MACHINE_TYPE_ID		= mt.MACHINE_TYPE_ID
		AND	phs.LANGUAGE_ID 		= bl.LANGUAGE_ID 
		AND	bl.IS_SYMBOLIC 		= 1 
		AND	s.PROFILE_SYMBOL_ID 	= phs.HEADER_SYMBOL_ID 
		AND 	s.language_id 			= bl.LANGUAGE_ID
		-- special contest non-symbolic for machine types < 6
		INSERT INTO CANDIDATE_DISPLAY_TRANSLATION (CANDIDATE_ID,
			MACHINE_TYPE_ID, LANGUAGE_ID, SHORT_NAME)
	   	SELECT i.CANDIDATE_ID
	    	,	cd.MACHINE_TYPE_ID
	    	,	bl.LANGUAGE_ID
		,	cd.LCD_NAME
		FROM INSERTED i, CONTEST c
		, CANDIDATE_DISPLAY cd, V_BALLOT_LANGUAGE	bl
	  	WHERE i.TYPE 			IN (1,5)-- types defined above
		AND	i.CONTEST_ID 		= c.CONTEST_ID
		AND	cd.CANDIDATE_ID 	= i.CANDIDATE_ID 	
		AND 	cd.MACHINE_TYPE_ID 	IN (1,2,3) -- 1-advantage 2-edge 3-Edge2P
		AND 	bl.Is_Symbolic		= 0 -- not symbolic
	END -- main processing inserts
	ELSE
	BEGIN -- throw error
		RAISERROR @errno @errmsg
    		ROLLBACK  TRANSACTION
	END -- throw error
	RETURN
END -- Trigger TI_Candidate
**	This procedure returns the version number of the stored
**    procedures used by the the Microsoft Visual Database Tools.
**	Version is 7.0.05.
create procedure dbo.dt_verstamp007
	select 7005
create view V_REF_TABLE as select SYMBOL.SYMBOL_ID, 'LAYOUT_SELECTION_TRANSLATION' TABLE_NAME, count(*) REF from LAYOUT_SELECTION_TRANSLATION join SYMBOL on SYMBOL.SYMBOL_ID = LAYOUT_SELECTION_TRANSLATION.HEADER_SYMBOL_ID group by SYMBOL.SYMBOL_ID
CREATE TRIGGER TUI_CANDIDATE_DISPLAY ON CANDIDATE_DISPLAY FOR INSERT, UPDATE 
/******************************************************************************
TRIGGER		: TUI_CANDIDATE_DISPLAY
Description 	: This trigger handles  all inserts and updates on the 
			Candidate_Display table.  Checks constraint on Candidate_ID in
			Candidate table and Audio_ID in Audio table.
			Propagates any insert/updates to Candidate_Display_Translation 
			table.  Updates Candidate_Dispaly offset settings for 
			displaying candidates.
RETURN		: This trigger can raise an error which is returned.
				
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modifications:
Date        	Author		Comments
7/16/98		ToolSmith		Initial creation.
8/3/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments.  Defined Constant values
						used in script
9/20/05		MMcKinney		Formatting compacted to meet 240 line limit
9/20/05		MMcKinney		Comments added in response to code review for
						following issues:
						1)	Numeric constant other than 1 or 0 needs to
							 be enumerated or defined or commented
						2)	thrown error needs to be listed in header
							 as output							
*******************)**********************************************************/
/***********************************
Note: Formatted for 240 line length
***********************************/
BEGIN
 	DECLARE @numrows  		int 	-- counter for results
	,	@numnull  		int	-- counter for NULL values in insert
	,	@errno    		int	-- error number 
	,	@errmsg   		varchar(255) -- error message
	--Initialize Variables
	-- Get the number of rows inserted
	SET 	@numrows 			= @@rowcount
	SELECT @numnull		= 0
	,	 @errno			= 1
	,	@errmsg			= ''
    -- Parent CANDIDATE must exist when inserting a child in CANDIDATE_DISPLAY
	IF UPDATE(CANDIDATE_ID)
	BEGIN
		-- verify number of matching rows in Candidate matches total rows
		-- being modified in table if unequal- throw error
		IF  (SELECT Count(*) FROM CANDIDATE t1, inserted t2
			WHERE  t1.CANDIDATE_ID = t2.CANDIDATE_ID) <> @numrows
		BEGIN
			SELECT @errno 	= 50002	-- user defined error number
			,	@errmsg	= 'Parent does not exist in CANDIDATE. Cannot '
						+ 'create child in CANDIDATE_DISPLAY.'
		END
	END
	-- Parent AUDIO must exist when inserting a child in CANDIDATE_DISPLAY
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- Get number of records with NULL Audio_ID
		SELECT @numnull = Count(*) FROM inserted WHERE AUDIO_ID IS NULL
		-- If there are records with Non-Null values, check for parent ID
		IF @numnull <> @numrows
		BEGIN
			-- Get count of matching Audio_IDs in Audio table, if unequal
			-- to number of records being modified, throw erroq
			IF  (SELECT Count(*) FROM AUDIO t1, inserted t2
				WHERE  t1.AUDIO_ID = t2.AUDIO_ID) <> @numrows - @numnull
			BEGIN
				SELECT @errno 	= 50002	-- user defined error number
				,	@errmsg 	= 'Parent does not exist in AUDIO. Cannot '
							+ 'create child in CANDIDATE_DISPLAY.'
			END
		END
	END
	-- only process further results if no error thrown
	-- otherwise, rollback transaction and raise error
	IF (@errno = 0)
	BEGIN
		-- propagate LCD_Name change to Short_Name
		-- in Candidate_Diqplay_Translation
		IF UPDATE(LCD_NAME)
		BEGIN 
			UPDATE CANDIDATE_DISPLAY_TRANSLATION
			SET SHORT_NAME 	= i.LCD_NAME
			FROM INSERTED		i
			WHERE CANDIDATE_DISPLAY_TRANSLATION.CANDIDATE_ID = i.CANDIDATE_ID
			AND	CANDIDATE_DISPLAY_TRANSLATION.MACHINE_TYPE_ID 
				= i.MACHINE_TYPE_ID
		END
		-- if Ballot_Header_ID is updated, must delete from 
		-- Candidate_Translation.  New record is inserted through the 
		-- Candidate_Header INSERT trigger TI_Candidate_Header
		-- Records also deleted!from Candidate_Header.  New records
		-- are theCon<
CREATE PROCEDURE up_LayoutStyles3a
	@Tally_Type_ID				int
,	@Max_Ballot_Style			int
,	@ConsolidatePrecinctActive	int
/******************************************************************************
Procedure:	up_LayoutStyles3a
Description:	case 3.1 by precinct -- layouts for precinct insert ballot 
			styles per precinct with selection codes for splits, parties, 
			and eligibility
			Updates layout for by-precinct!with and without selections
			insert selections for each layout that have multiple styles
			per precinct
Parameters: 	@Tally_Type_ID tally type id
		,	@Max_Ballot_Style  max ballot style excluding office use only
		,	@ConsolidatePrecinctActive flag for consolidated precincts
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others is prohibited.
Description/Modificationq:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
9/29/05	ECoomer		Changed logic when inserting into temp table
					#t_min_pct.  Previous logic was taking min
					of all precincts based on list order including
					split precincts- then adding split precincts.
					Changed so that the min only looks at non-split
					precincts first, and then adds splits.
******************************************************************************/
BEGIN
	-- STEP 13: case 3.1 by precinct -- laymuts for precinct
	-- insert ballot styles per precinct
	-- with selection codes for splits, parties, and eligibility
	-- find precincts in ballot styles with attirbutes that make them
	-- candidates for spliting
	INSERT #t_ballot_pct
		BALLOT_STYLE_ID
	, 	PRECINCT_ID
	, 	LIST_ORDER
	, 	HAS_SELECTIONS
	SELECT
		bp.BALLOT_STYLE_ID
	, 	bp.PRECINCT_ID
	, 	p.LIST_ORDER
	, 	Sign(Count(s.BALLOT_STYLE_ID))
	FROM BALLOT_PRECINCT 		bp
	JOIN v_precinct 			p 
		ON p.PRECINCT_ID 		= bp.PRECINAT_ID
		AND p.Is_Consolidated 	= @ConsolidatePrecinctActive
	LEFT JOIN #t_selections		s
		ON s.PRECINCT_ID 		= p.PRECINCT_ID
	WHERE 
		bp.BALLOT_STYLE_ID 		<= @max_ballot_style
	GROUP BY
		bp.BALLOT_STYLE_ID
	, 	bp.PRECINCT_ID
	, 	p.LIST_ORDER
	-- calculate the variance and sum of squares of the ballot_style_ID
	-- grouped by List_Order to identify precincts with the same set of
	-- ballot styles.  This will minimize the number of layouts created
	-- store this information in temp table #DisuinctPrecinct
	SELECT
		List_Order
	,	varp(Ballot_Style_ID) 		AS BSVar -- variance of BS_ID
	,	sum(square(Ballot_Style_ID))	AS BSSum -- Sum of Squares of BS_ID
	,	Has_Selections
	INTO
		#DistinctPrecinct
	FROM
		#t_ballot_pct
	GROUP BY
		List_Order
	,	Has_Selections
	-- find the unique set of ballot_styles and use the first precinct_ID
	-- based on list_order- insert into temp table #t_min_pct
	INSERT #t_min_pct
		BALLOT_STYLE_ID
	, 	PRECINCT_ID
	SELECT
		bp.Ballot_Style_ID
	,	ap.Precinct_ID
	FROM
		#t_ballot_pct		bp
	,	#DistinctPrecinct	dp
	WHERE
		bp.List_Order		= dp.List_Order
	AND	bp.List_Order		<= all (SELECT
							List_Order
						FROM
							#DistinctPrecinct	dp2
						WHERE
							dp2.BSVar			= dp.BSVar
						AND 	dp2.BSSum			= dp.BSSum
						AND 	dp2.Has_Selections	= dp.Has_Selections
						)
	ORDER BY
		bp.List_Order
	-- get layouts without selections
	INSERT INTO #t_layout_style
		BALLOT_STYLE_ID
	, 	TALLY_TYPE_ID
	, 	ASSIGNMENT_ID
	, 	LIST]ORDER
	, 	NAME
	SELECT 
		bs.BALLOT_STYLE_ID
	,	tt.TALLY_TYPE_ID
	,	mp.PRECINCT_ID
	,	p.LIST_ORDER
	,	p.NAME 
	FROM 
		BALLOT_STYLE 			bs
	JOIN V_TALLY_TYPE 			tt
		ON tt.BALLOT_MODE 		= 0 -- by precinct
	JOIN #t_min_pct 			mp
		ON mp.BALLOT_STYLE_ID 	= bs.BALLOT_STYLE_ID
	JOIN v_precinct 			p
		ON p.PRECINCT_ID 		= mp.PRECINCT_ID
	WHERE 
		tt.Tally_Type_ID		= ISNULL(@tally_type_id, tt.TALLY_TYPE_ID)
	AND 	bs.BALLOT_STYLE_ID 		<= @max_ballot_style
	AND 	tt.TALLY
	BEGIN -- main processing loop for Candidate_Header/Display
		-- reflect change in candidate status when it is part of a group
		IF UPDATE (SUBSET_ID)
		BEGIN 
			IF EXISTS (SELECT 1 FROM INSERTED WHERE SUBSET_ID > 0)
			BEGIN	
				UPDATE CANDIDATE
				SET 
					TYPE 		= 7 -- Proportional Candidate Type
				FROM 
					INSERTED		i
				WHERE 
					i.CANDIDATE_ID	= CANDIDATE.CANDIDATE_ID
				AND	i.TYPE 		<> 2 -- Endorsed Candidate
			END
			ELSE -- if not group, set to standard candidate
			BEGIN
				UPDATE CANDIDATE
				SET 
					TYPE 		= 0 -- Standard Candidate
				FROM 
					INSERTED		i
				WHERE 
					i.CANDIDATE_ID	= CANDIDATE.CANDIDATE_ID
				AND	i.TYPE 		<> 2 -- Endorsed Candidate
			END
		END
		-- Propagate Changes to Report_Name to Candidate_Display
		-- and Candidate_Header
		IF UPDATE (REPORT_NAME)
		BEGIN
			-- Set LCD_Name for display
			UPDATE CANDIDATE_DISPLAY
			SET 
				LCD_NAME 			= SUBSTRING(REPORT_NAME,1,24)
			FROM 
				INSERTED			i
			WHERE 
				i.CANDIDATE_ID 	= CANDIDATE_DISPLAY.CANDIDATE_ID
	     	-- make sure that changes to candidate are reflected in 
			-- candidate display
	     	-- Header = {1} == Candidate_Name = Report_Name
			UPDATE CANDIDATE_HEADER
			SET 
				HEADER 			= i.report_name
			FROM 
				inserted			i
	         	,	candidate_display	cd
	         	,	v_header_item 		hi
			WHERE 
				hi.header_item_id 	= Candidate_Header.header_item_id
			AND 	i.candidate_id 	= Candidate_Header.candidate_id
			AND 	hi.HEADER 		= '{1}' 
			AND	cd.candidate_id 	= i.candidate_id
			AND	hi.ballot_header_id = cd.ballot_header_id
		END
		-- Header = {2} == party
		IF UPDATE (PARTY_ID)
		BEGIN
			UPDATE CANDIDATE_HEADER
			SET 
				HEADER 			= isnull(p.NAME,'')
			FROM 
				inserted			i
			,	candidate_display 	cd
			,	v_header_item		hi
			,	v_party			p
			WHERE 
				hi.header_item_id 	= candidate_header.header]item_id
			AND 	i.candidate_id 	= candidate_header.candidate_id
			AND 	hi.HEADER 		= '{2}' -- used by Visio
			AND	cd.candidate_id 	= i.candidate_id
			AND	hi.ballot_header_id = cd.ballot_header_id
			AND	i.party_id		*= p.party_id
		END
		-- Header = {3} == residence city
		IF UPDATE (RESIDENCE_CITY)
		BEGIN
			UPDATE CANDIDATE_HEADER
			SET 
				HEADER 			= i.RESIDENCE_CITY
			FROM 
				inserted			i
	         	,	candidate_display	cd
	         	,	v_header_item		hi
			WHERE 
				hi.header_item_id 	= candidate_header.header_item_id
			AND 	i.candidate_id 	= candidate_header.candidate_id
			AND 	hi.HEADER 		= '{3}' -- used by Visio
			AND	cd.candidate_id 	= i.candidate_id
			AND	hi.ballot_header_id = cd.ballot_header_id
	     END
	      
		-- Header = {4} == residence state
		IF UPDATE (RESIDENCE_STATE)
		BEGIN
			UPDATE CANDIDATE_HEADER
			SET 
				HEADER 			= i.RESIDENCE_STATE
			FROM 
				inserted			i
			,	candidate_display	cd
	         	,	v_header_item 		hi
			WHERE 
					hi.header_item_id 	= candidate_header.header_item_id
			AND	i.candidate_id 	= candidate_header.candidate_id
			AND	hi.HEADER 		= '{4}' -- used by Visio
			AND	cd.candidate_id 	= i.candidate_id
			AND	hi.ballot_header_id = cd.ballot_header_id
		END
		-- Header = {5} == birthdate
		IF UPDATE (BIRTH_DATE)
		BEGIN
			UPDATE CANDIDATE_HEADER
			SET 
				HEADER = IsNull(Convert(CHAR(12), i.BIRTH_DATE, 100), '')
								 -- formated date
			FROM 
				inserted			i
			,	candidate_display	cd
	         	, 	v_header_item	hi
			WHERE 
				hi.header_item_id 	= candidate_header.header_item_id
			AND 	i.candidate_id 	= candidate_header.candidate_id
			AND 	hi.HEADER 		= '{5}' -- used by Visio
			AND	cd.candidate_id	= i.candidate_id
			AND	hi.ballot_header_id = cd.ballot_header_id
		END
		-- Header = {6} == social security number
		IF UPDATE (SOCIAL_SECURITY)
		BEGIN
			UPDATE CANDIDATE_HEADER
			SET 
				HEADER = IsNull(Convert(varchar(10),SOCIAL_SECURITY),'')
			FROM 
				inserted			i
	         	,	candida
te_display	cd
	         	,	v_header_item		hi
			WHERE 
				hi.header_item_id 	= candidate_header.header_item_id
			AND 	i.candidate_id 	= candidate_header.candidate_id
			AND 	hi.HEADER 		= '{6}' -- used by Visio
			AND	cd.candidate_id 	= i.candidate_id
			AND	hi.ballot_header_id = cd.ballot_header_id
		END
		-- Header = {7} == graphic symbol (not changed here)
		-- Header = {9} == first name + middle initial
		IF UPDATE (FIRST_NAME) OR UPDATE (MIDDLE]INITIAL)
		BEGIN
			UPDATE CANDIDATE_HEADER
			SET 
				HEADER  = i.FIRST_NAME + ' ' + IsNull(i.MIDDLE_INITIAL, '')
			FROM 
				inserted			i
	         	,	candidate_display	cd
	         	,	v_header_item		hi
			WHERE 
				hi.header_item_id 	= candidate_header.header_item_id
			AND	i.candidate_id 	= candidate_header.candidate_id
			AND	hi.HEADER 		= '{9}' -- used by Visio
			AND	cd.candidate_id 	= i.candidate_id
			AND	hi.ballot_header_id = cd.ballot_header_id
		END
		-- Header = {10} == Middme Initial
		IF UPDATE (MIDDLE_INITIAL)
		BEGIN
			UPDATE CANDIDATE_HEADER
			SET 
				HEADER 			= i.MIDDLE_INITIAL
			FROM 
				inserted			i
	         	,	candidate_display	cd 
	         	,	v_header_item		hi
			WHERE 
				hi.header_item_id 	= candidate_header.header_item_id
			AND	i.candidate_id 	= candidate_header.candidate_id
			AND	hi.HEADER 		= '{10}' -- used by Visio
			AND	cd.candidate_id 	= i.candidate_id
			AND	hi.ballot_header_id = cd.ballot_header_id
		END
		-- Header = {11} == laqt name + suffix
		IF UPDATE (LAST_NAME) OR UPDATE (SUFFIX)
		BEGIN
			UPDATE CANDIDATE_HEADER
			SET 
				HEADER 	= i.LAST_NAME + ' ' + IsNull(i.SUFFIX, '')
			FROM 
				inserted			i
	         	,	candidate_display	cd
	         	,	v_header_item		hi
			WHERE 
				hi.header_item_id 	= candidate_header.header_item_id
			AND	i.candidate_id 	= candidate_header.candidate_id
			AND	hi.HEADER 		= '{11}' -- used by Visio
			AND	cd.candidate_id 	= i.candidate_id
			AND	hi.ballot_header_id = cd.ballot_header_id
		END
	END -- Main processing loop for updating Candidate_Header/Display
	ELSE
	BEGIN -- if Errno <> 0 then error has been thrown
		RAISERROR @errno @errmsg
		ROLLBACK TRANSACTION
	END -- Error handling
	RETURN
END -- TRIGGER TU_Candidate
V8V*
create procedure dbo.dt_getpropertiesbyid_vcs
    @id       int,
    @property varchar(64),
    @value    varchar(255) = NULL OUT
    set nocount on
    select @value = (
        select value
                from ebo.dtproperties
                where @id=objectid and @property=property
                )
create view V_REF_TABLE as select SYMBOL.SYMBOL_ID, 'SELECTION_TRANSLATION' TABLE_NAME, count(*) REF from SELECTION_TRANSLATION join SYMBOL on SYMBOL.SYMBOL_ID = SELECTION_TRANSLATION.SYMBOL_ID group by SYMBOL.SYMBOL_ID
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
hyhh
LC]`
hyhh
LC]`
hyhh
LC]`
hyhh
LC]`
LC]`
LC]`
LC]`
LC]`
LC]`
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
(k_+
(k_+
(k_+
K?g	
(k_+
(k_+
(k_+
2`Xu
2`Xu
2`Xu
2`Xu
2`Xu
2`Xu
2`Xu
2`Xu
V8V*
(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	(	
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
hyhh
yXvn
yXvn
yXvn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
ONAn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
yXvn
	*	A	X	o	
(k_+
E $0
r5=>
hyhh
xR(B
!	t	
"9(`
(k_+
E $0
EYH$
