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
			, 	Candidate_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 unusee 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
	-- Seu 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 LAYOUT_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   	
		COMTEST_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
CREATE PROCEDURE up_ClosedPrimary
	@Closed_Primary	int OUTPUT
,	@dts_primary		int OUTPUT
/*****************************)************************************************
Procedure:	up_ClosedPrimary
Description:	Sends back data for whether election is 1) closed primary
			2) dts (decline-to-state) primary
Parameters: 	none
Return: 	@ClosedPrimary OUTPUT variable
	,	@dts_Primary OUTPUT variable
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      Autior		Comments
9/21/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN
	-- find if current election is a closed primary election
	SELECT 
		@closed_primary 		= VALUE
 	FROM 
		v_ELECTION_PARAMETER	ep
	JOIN v_ELECTION 			e
		ON e.ELECTION_ID 		= ep.ELECTION_ID
	WHERE 
		e.REMOTE_LINK 			= DB_NAME()
	AND 	ep.PARAMETER_ID 		= 1
	IF @closed_primary IS NULL 
		SELECT @closed_primary 	= 0
	-- account for DTS primary
	IF @closee_primary = 3 
	BEGIN
		SELECT @closed_primary 	= 1
		SELECT @dts_primary 	= 1
	END
	ELSE
		SELECT @dts_primary = 0
END -- PROCEDURE up_ClosedPrimary
**	Drop an object from the dbo.dtproperties table
create procedure dbo.dt_dropuserobjectbyid
	@id int
	set nocount on
	delete from dbo.dtproperties where objectid=@id
create view V_REF_TABLE as select SYMBOL.SYMBOL_ID, 'CONTEST_DISPLAY_TRANSLATION' TABLE_NAME, count(*) REF from CONTESU_DISPLAY_TRANSLATION join SYMBOL on SYMBOL.SYMBOL_ID = CONTEST_DISPLAY_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			= 0
	,	@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_DISPMAY.'
		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 error
			IF  (SELECT Count(*) FQOM 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_Display_Translation
		IF UPDAUE(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 the
_SOURCE_ID 		NOT IN (3, 6) 	-- we already took care
										-- of ABSENTEE, 400-C
	AND 	IS_ROLLUP 			<> 1 -- rollup is handled separetely
	AND 	NOT EXISTS 
		(SELECT 
			1
		FROM 
			#t_selections 		SEL
		WHERE 
			bs.BALLOT_STYLE_ID 	= SEL.BALLOT_STYLE_ID
		AND 	p.PRECINCT_ID 		= SEL.PRECINCT_ID
		) -- no selections
	UNION ALL
	-- layouts with selections 
	-- add one layout for each set of selections with the same precincts
	SELECT  
		s.BALLOU_STYLE_ID BALLOT_STYLE_ID 
	,	tt.TALLY_TYPE_ID
	,	s.PRECINCT_ID PRECINCT_ID
	,	p.LIST_ORDER
	,	p.NAME 
	FROM 
		#t_min_pct 			mp 
	JOIN #t_selections 			s
		ON s.BALLOT_STYLE_ID 	= mp.BALLOT_STYLE_ID
		AND s.PRECINCT_ID 		= mp.PRECINCT_ID
	JOIN BALLOT_STYLE			bs
		ON bs.BALLOT_STYLE_ID 	= s.BALLOT_STYLE_ID
	JOIN v_precinct 			p
		ON p.PRECINCT_ID 		= s.PRECINCT_ID
	JOIN V_TALLY_TYPE 			tt
		ON tt.BALLOT_MODE 		= 0 -- by precinct
	WHERE 
		tt.Tally_Type_ID		= ISNULL(@tally_type_id, tt.TALLY]TYPE_ID)
	AND 	tt.TALLY_SOURCE_ID 		NOT IN (3, 6) 	-- we already took care
										-- of ABSENTEE, 400-C
	AND 	IS_ROLLUP 			<> 1 -- rollup is handled separetely
	AND 	bs.LIST_ORDER 			<= all (SELECT BS2.LIST_ORDER
							FROM 
								BALLOT_STYLE	BS2
							JOIN #t_min_pct 	mp2
							ON mp2.BALLOT_STYLE_ID = BS2.BALLOT_STYLE_ID
							WHERE 
								mp2.PRECINCT_ID = s.PRECINCT_ID
							)
	-- STEP 15: insert created layouts for by-precinct with and without
	-- selections
	INSERT INTO LAYOUT
		LAYOUT_ID
	, 	NAME
	, 	TALLY_TYPE_ID
	, 	REVISION
	, 	IS_VALID
	, 	BALLOT_STYLE_ID
	SELECT 
		LAYOUT_ID 
	,	NAME
	,	TALLY_TYPE_ID
	,	'0'
	,	1
	,	BALLOT_STYLE_ID
	FROM 
		#t_layout_style
	-- STEP 16: insert selections for each layout that have multiple styles
	-- per precinct
	INSERT INTO LAYOUT_SELECTION
	(	LAYOUT_ID
	, 	SELECTION_CODE
	, 	SELECTION_NAME
	, 	BALLOT_STYLE_ID
	SELECT DISTINCT
		l.LAYOUT_ID 
	,	bs.LIST_ORDER 
	,	s.NAME
	,	s.BALLOT_STYLE_ID
	FRMM 
		#t_selections 			s
	JOIN #t_layout_style 		l
		ON s.PRECINCT_ID 		= l.ASSIGNMENT_ID
	JOIN BALLOT_STYLE 			bs
		ON bs.BALLOT_STYLE_ID	= s.BALLOT_STYLE_ID
	ORDER BY 
		l.LAYOUT_ID
	,	bs.LIST_ORDER
END -- Procedure up_LayoutStyles3a
****(
 @@ED
Rota
.  T
ION 
neTy
 cla]
rom 
****
				
late
d = E
	ECo(
hallE
    
_id(F
****
****
he D]
****
 IT 
CREATE TRIGGER TI_CANDIDATE_DISPLAY_TRANSLATION 
ON CANDIDATE_DISPLAY_TRANSLATION FOR INSERT 
/******************************************************************************
TRIGGER		: TI_CANDIDATE_DISPLAY_TRANSLATION
Description 	: This trigger handles  all inserts on the 
			CANDIDATE_DISPLAY_TRANSLATION table.  Checks constraint on 
				Candidate_ID in Candidate_Display table
			,	Audio_ID in Audio table
			,	Symbol_ID (Header_Symbol_ID) in Symbol table
			If parent record(s) do not exist, trigger rolls back transaction
				
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.  
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
	,	@numnuln  		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 CANDIDATE_DISPLAY must exist when inserting a child 
	-- in CANDIDATE_DISPLAY_TRANSLATION
	IF (UPDATE(CANDIDATE_ID) OR UPDATE(MACHINE_TYPE_ID))
	BEGIN
		if  (SELECT Count(*)
			FROM
				CANDIDATE_DISPLAY
			, 	inserted 			i
			WHERE  
				cd.CANDIDATE_ID 	= i.CANDIDATE_ID
			AND	cd.MACHINE_TYPE_ID = i.MACHINE_TYPE_ID)	<> @numrows
		BEGIN
			SELECT
				@errno  	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not exist in CANDIDATE_DISPLAY. '
						+ 'Cannot create child in '
						+ 'CANDIDATE_DISPLAY_TRANSLATION.'
		END
	END -- Candidate_Display constraint check
	-- Parent AUDIO must exist when inserting a child in 
	-- CANDIDATE_DISPLAY_TRANSLATION.  Skip if error throvn
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- get number of records with NULL Audio_ID
		SET @numnull = (SELECT 
						Count(*)
                          FROM   
						inserted
                          WHERE  
						AUDIO_ID IS NULL)
		-- if there are rows with non-NULL Audio_ID, check for parent
		IF @numnull <> @numrows
		BEGIN
			-- if non-matching, 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_DISPLAY_TRANSLATION.'
			END
		END
	END -- Audio_ID Constraint check
	-- Parent SYMBOL must exist when inserting a child in 
	-- CANDIDATE_DISPLAY_TRANSLATION
	IF (UPDATE(HEADER_SYMBOL_ID) AND @errno = 0)
	BEGIN
		-- get number of records with NULL Header_Symbol_ID
		SET @numnull = (SELECT 
				
	Count(*)
					FROM   
						inserted
					WHERE  
						HEADER_SYMBOL_ID is null)
		-- if there are rows with non-NULL Header_Symbol_ID check for parent
		IF @numnull <> @numrows
		BEGIN
			-- if non-matching, throw error
			IF  (SELECT 
					Count(*)
				FROM   
					SYMBOL 		s
				, 	inserted		i
				WHERE  
					s.SYMBOL_ID 	= i.HEADER_SYMBOL_ID
				) 				<> @numrows - @numnull
			BEGIN
				SELECT 
					@errno  	= 50002	-- user defined error number
				,	@errmsg 	= 'Parent does not ezist in SYMBOL. '
CREATE TRIGGER TU_CANDIDATE_DISPLAY_TRANSLATION 
ON CANDIDATE_DISPLAY_TRANSLATION FOR UPDATE 
/******************************************************************************
TRIGGER		: TU_CANDIDATE_DISPLAY_TRANSLATION
Description 	: This trigger handles  all updates on the 
			CANDIDATE_DISPLAY_TRANSLATION table.  Checks constraint on 
				Candidate_ID in Candidate_Display table
			,	Audio_ID in Audio table
			,	Symbol_ID (Header_Symbol_ID) in Symbol table
			If parent record(s) do not exist, trigger rolls back transaction
				
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.  
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	
1/12/06		ECoomer		Removed code that was checking whether Audio_ID
						was changing- and raising error if it was.  This
						code was in error.  Audio_ID jn this table should
						be allowed to change.			
******************************************************************************/
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 CANFIDATE_DISPLAY must exist when updating a child in
	-- CANDIDATE_DISPLAY_TRANSLATION
	IF (UPDATE(CANDIDATE_ID) OR UPDATE(MACHINE_TYPE_ID))
	BEGIN
		IF  (SELECT 
				Count(*)
			FROM   
				CANDIDATE_DISPLAY	cd
			, 	inserted 			i
			WHERE  
				cd.CANDIDATE_ID 	= i.CANDIDATE_ID
			AND  cd.MACHINE_TYPE_ID 	= i.MACHINE_TYPE_ID) <> @numrows
		BEGIN
			SELECT 
				@errno 	= 50003	-- user defined error number
			,	@errmsg 	= 'CANDIDATE_DISPLAY does not exist. '
						+ 'Cannot modify child in '
					+ 'CANDIDATE_DISPLAY_TRANSLATION.'
		END
	END -- Candidate_ID constraint check
	-- Parent AUDIO must exist when updating a child in 
	-- CANDIDATE_DISPLAY_TRANSLATION 
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- get number of records with NULL Audio_ID
		SET @numnull = (SELECT 
						Count(*)
					FROM   
						inserted
					WHERE  
						AUDIO_ID IS NULL)
		-- if there are rows with non-NULL Audio_ID, check for parent
		IF @numnull <> @numrows
		BEGIN
			IF  (SELECT 
					Covnt(*)
				FROM   
					AUDIO		a
				, 	inserted 		i
				WHERE  
					a.AUDIO_ID	= i.AUDIO_ID
				) 				<> @numrows - @numnull
			BEGIN
				-- no parent, raise error
				SELECT 
					@errno 	= 50003	-- user defined error number
				,	@errmsg 	= 'AUDIO does not exist. Cannot modify '
							+ 'child in CANDIDATE_DISPLAY_TRANSLATION.'
			END
		END
	END -- Audio_ID constraint check
	-- Parent SYMBOL must exist when updating a child in 
	-- CANDIDATE_DISPLAY_TRANSLATION 
	IF (UPDATE(HEADER_RYMBOL_ID) AND @errno = 0)
	BEGIN
		-- get number of records with NULL Header_Symbol_ID
		SET @numnull = (SELECT 
						count(*)
					FROM   
						inserted
					WHERE  
						HEADER_SYMBOL_ID IS NULL)
		-- if there are rows with non-NULL Header_Symbol_ID, check for parent
		IF @numnull <> @numrows
		BEGIN
			IF  (SELECT 
					Count(*)
				FROM   
					SYMBOL 		s
				, 	inserted 		i
				WHERE  
					s.SYMBOL_ID 	= i.HEADER_SYMBOL_ID
				) 				<> @numrows - @numnull
			BEGIN
				-- no parent, raise error
	SELECT 
					@errno  	= 50003	-- user defined error number
				,	@errmsg 	= 'SYMBOL does not exist. Cannot modify '
							+ 'child in CANDIDATE_DISPLAY_TRANSLATION.'
			END
		END
	END -- Header_Symbol_ID constraint
	-- Raise error and rollback transaction if @errno > 0
	IF (@errno > 0)
	BEGIN -- if @errno <> 0
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END -- error handling
	RETURN
END -- TRIGGER TU_CANDIDATE_DISPLAY_TRANSLATION
CREATE TRIGGER TI_CANDIDATE_HEADER ON CANDIDATE_HEADER FOR INSERT 
/******************************************************************************
TRIGGER		: TI_CANDIDATE_HEADER
Description 	: This trigger handles  all inserts on the 
			Candidate_Header table.  Checks constraint on 
				Candidate_ID in Candidate
			,	Symbol_ID in Symbol table
			If parent record(s) do not exist, trigger rolls back transaction
			Also handles propagating Candidate_Header information to the 
			Candidate_Translation 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/4/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
						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 CANDIDATE must exist when inserting a child in CANDIDATE_HEADER
	IF UPDATE(CANDIDATE_ID)
	BEGIN
		IF  (SELECT 
				Count(*)
			FROM   
				CANDIDATE 	c
			, 	inserted 		i
			WHERE  
				c.CANDIDATE_ID	= i.CANDIDATE_ID
) 				<> @numrows
		BEGIN
			-- no parent, raise error
			SELECT 
				@errno	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not exist in CANDIDATE. '
						+ 'Cannot create child in CANDIDATE_HEADER.'
		END
	END
	-- Parent Symbol_ID must exist when inserting a child in Candidate_Header
	-- only process if no error thrown yet
	IF (UPDATE(SYMBOL_ID) AND @errno = 0)
	BEGIN
		-- get number of records with NULL Symbol_ID
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE" SYMBOL_ID IS NULL
						
		-- if there are rows with non-NULL Symbol_ID, check for parent
		IF @numnull <> @numrows
		BEGIN	
			IF  (SELECT 
					Count(*)
				FROM   
					SYMBOL 		s
				, 	inserted 		i
				WHERE  
					s.SYMBOL_ID 	= i.SYMBOL_ID
				) 				<> @numrows - @numnull
        		BEGIN
				-- No parent Symbol_ID raise error
				SELECT 
					@errno	= 50002	-- user defined error number
				,	@errmsg 	= 'Parent does not exist in SYMBOL. '
							+ 'Cannot create child in CANDIDATE_JEADER.'
			END
		END
	END
	IF (@errno = 0)
	BEGIN -- Candidate Translation Inserts/Updates
		-- insert translation strings for each header item
		INSERT INTO CANDIDATE_TRANSLATION
			CANDIDATE_ID
		,	HEADER_ITEM_ID
		,	LANGUAGE_ID
		,	HEADER
		SELECT 
			i.CANDIDATE_ID,
			i.HEADER_ITEM_ID,
			bl.LANGUAGE_ID,
			CASE hi.HEADER
				WHEN '{2}' THEN IsNull(VP.name --Party Name
							, dbo.bart_fn_get_translation(i.HEADER
							, bl.LANGUAGE_ID))
				ELSE -- use dictionary to nookup common translations
					dbo.bart_fn_get_translation(i.HEADER, bl.LANGUAGE_ID)
			END 
		FROM 
			INSERTED			i
		,	v_Ballot_Language	bl
		,	CANDIDATE 		c
		,	V_HEADER_ITEM 		hi
		,	V_PARTY_TRANSLATION vp
		WHERE
			c.PARTY_ID 		*= vp.PARTY_ID
		AND 	bl.LANGUAGE_ID 	*= vp.LANGUAGE_ID
		AND	bl.IS_SYMBOLIC 	= 0 -- only for text based languages
		AND	c.CANDIDATE_ID 	= i.CANDIDATE_ID
		AND	hi.HEADER_ITEM_ID 	= i.HEADER_ITEM_ID
		-- Update Proposal translations for 'NO'
		UPDATE 
CANDIDATE_TRANSLATION
		SET 
			HEADER	= (SELECT DISTINCT	
						rt.NO
					FROM  
						V_RESPONSE_TRANSLATION 	rt
					,	PROPOSAL				p
					,	CONTEST				co
					,	CANDIDATE				c2
					,	CANDIDATE_TRANSLATION 	ct  
					,	INSERTED				i
					WHERE 
						c2.LIST_ORDER 			= 2 -- 'NO'
					AND 	c2.TYPE 				= 4 -- Proposal Type
					AND 	ct.LANGUAGE_ID	
						= CANDIDATE_TRANSLATION.LANGUAGE_ID
					AND	p.RESPONSE_SET_ID 		= rt.RESPONSE_SET_ID 
					AND	p.PROPOSAL_ID 
		= co.PROPOSAL_ID
					AND	c2.CONTEST_ID 			= co.CONTEST_ID
					AND	rt.LANGUAGE_ID 		= ct.LANGUAGE_ID 
					AND	i.CANDIDATE_ID 		= c2.CANDIDATE_ID 
					AND 	ct.CANDIDATE_ID 		= c2.CANDIDATE_ID	
					AND 	i.HEADER_ITEM_ID 		= ct.HEADER_ITEM_ID)
		FROM 
			INSERTED			i
		,	V_HEADER_ITEM		hi
		,	CANDIDATE 		c
		WHERE 
			i.CANDIDATE_ID		= CANDIDATE_TRANSLATION.CANDIDATE_ID
		AND 	i.HEADER_ITEM_ID	= CANDIDATE_TRANSLATION.HEADER_ITEM_ID
		AND	hi.HEADER 		= '{1}'
		AND	c.LIST_ORDER 		= 2 -- list"order 2 == 'NO'
		AND	c.TYPE 			= 4 -- Proposal type
		AND	hi.HEADER_ITEM_ID 	= i.HEADER_ITEM_ID	
		AND	c.CANDIDATE_ID 	= i.CANDIDATE_ID
		-- Update Proposal translations for 'YES'		
		UPDATE 
			CANDIDATE_TRANSLATION 
		SET 
			HEADER 	= (SELECT DISTINCT 
						rt.YES
					FROM  
						V_RESPONSE_TRANSLATION 	rt
					,	PROPOSAL				p
					,	CONTEST				co
					,	CANDIDATE				c2
					,	CANDIDATE_TRANSLATION 	ct  
					,	INSERTED				i
					WHERE 
						c2.LIST_ORDER 			= 1 -- 'YES'
					AND 	c2.TYPE 				= 4 -- Proposal Type
					AND 	ct.LANGUAGE_ID	
						= CANDIDATE_TRANSLATION.LANGUAGE_ID
					AND	p.RESPONSE_SET_ID 		= rt.RESPONSE_SET_ID 
					AND	p.PROPOSAL_ID 			= co.PROPOSAL_ID
					AND	c2.CONTEST_ID 			= co.CONTEST_ID
					AND	rt.LANGUAGE_ID 		= ct.LANGUAGE_ID 
					AND	i.CANDIDATE_ID 		= c2.CANDIDATE_ID 
					AND 	ct.CANDIDATE_ID 		= c2.CANDIDATE_ID	
					AND 	i.HEADER_ITEM_ID 		= ct.HEADER_ITEM_ID)
		FROM 
			INSERTED			i
		,	V_HEADER_ITEM		hi
		,	CANDIDATE 		c
		WHERE"
			i.CANDIDATE_ID		= CANDIDATE_TRANSLATION.CANDIDATE_ID
		AND 	i.HEADER_ITEM_ID	= CANDIDATE_TRANSLATION.HEADER_ITEM_ID
		AND	hi.HEADER 		= '{1}'	-- used by Visio
		AND	c.LIST_ORDER 		= 1 -- list order 2 == 'YES'
		AND	c.TYPE 			= 4 -- Proposal type
		AND	hi.HEADER_ITEM_ID 	= i.HEADER_ITEM_ID	
		AND	c.CANDIDATE_ID 	= i.CANDIDATE_ID
		-- Update Proposal translations for 'Undetermined'	
		UPDATE 
			CANDIDATE_TRANSLATION 
		SET 
			HEADER 	= (SELECT DISTINCT 
						rt.UNDETERMINED
					FROM "
						V_RESPONSE_TRANSLATION 	rt
					,	PROPOSAL				p
					,	CONTEST				co
					,	CANDIDATE				c2
					,	CANDIDATE_TRANSLATION 	ct  
					,	INSERTED				i
					WHERE 
						c2.LIST_ORDER 			= 3 -- undetermined
					AND 	c2.TYPE 				= 4 -- Proposal Type
					AND 	ct.LANGUAGE_ID	
						= CANDIDATE_TRANSLATION.LANGUAGE_ID
					AND	p.RESPONSE_SET_ID 		= rt.RESPONSE_SET_ID 
					AND	p.PROPOSAL_ID 			= co.PROPOSAL_ID
					AND	c2.CONTEST_ID 			= co.CONTEST_ID
					AND	rt.LANGUAGE_ID 		= ct.LANGUAGE^ID 
					AND	i.CANDIDATE_ID 		= c2.CANDIDATE_ID 
					AND 	ct.CANDIDATE_ID 		= c2.CANDIDATE_ID	
					AND 	i.HEADER_ITEM_ID 		= ct.HEADER_ITEM_ID)
		FROM 
			INSERTED			i
		,	V_HEADER_ITEM		hi
		,	CANDIDATE 		c
		WHERE 
			i.CANDIDATE_ID		= CANDIDATE_TRANSLATION.CANDIDATE_ID
		AND 	i.HEADER_ITEM_ID	= CANDIDATE_TRANSLATION.HEADER_ITEM_ID
		AND	hi.HEADER 		= '{1}'	-- used by Visio
		AND	c.LIST_ORDER 		= 3 -- undetermined
		AND	c.TYPE 			= 4 -- Proposal type
		AND	hi.HEADER_ITEM_ID 	= i.HEADER_ITFM_ID	
		AND	c.CANDIDATE_ID 	= i.CANDIDATE_ID
	END -- Candidate_Translation updates
	ELSE
	BEGIN -- raise error
		RAISERROR @errno @errmsg
		ROLLBACK TRANSACTION
	END
	RETURN
END -- TRIGGER TI_Candidate_HEADER
CREATE PROCEDURE up_LayoutParty
	@Tally_Type_ID		int
,	@closed_primary	int
,	@dts_primary		int
,	@max_ballot_style	int
/******************************************************************************
Procedure:	up_LayoutParty
Description:	Creates layout party for all parties included in the election 
			for each layout.
			Inserts layout assignment for precincts without selections
Parameters: 	@Tally_Type_ID tally type id
		,	@Closed_Primary flag for closed primary
		,	@dts_Primary flag for dts primary
		,	@Max_Ballot_Style max ballot style excluding office use only
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 28: create layout party for all parties included in the 
	-- election for each layout
	INSERT INTO LAYOUT_PARTY
		LAYOUT_ID
	,	PARTY_ID
	,	LIST_ORDER
	SELECT DISTINCT
		lc.LAYOUT_ID
	,	IsNull(c.PARTY_ID, 0)
	,	IsNull(p.LIST_ORDER,0)
	FROM 
		LAYOUT_CONTEST			lc
	JOIN LAYOUT 				l
		ON l.LAYOUT_ID			= lc.LAYOUT_ID
	JOIN CONTEST 				c
		ON c.CONTEST_ID 		= lc.CONTEST_ID
	LEFU JOIN V_PARTY 			p
		ON c.PARTY_ID 			= p.PARTY_ID
	WHERE 
		Tally_Type_ID 			= ISNULL(@tally_type_id, TALLY_TYPE_ID)
	AND 	p.IS_ACTIVE 			= 1
	UNION
	-- Build 137 / DTS Parties 
	SELECT DISTINCT
		lc.LAYOUT_ID
	,	IsNull(dp.PARTY_ID, 0)
	,	IsNull(dp.LIST_ORDER,0)
	FROM 
		LAYOUT_CONTEST			lc
	JOIN LAYOUT 				l
		ON l.LAYOUT_ID 		= lc.LAYOUT_ID
	JOIN CONTEST 				c
		ON c.CONTEST_ID 		= lc.CONTEST_ID
	JOIN V_PARTY 				p
		ON c.PARTY_ID 			= p.PARTY_ID
	JOIN V_PARTY 				dp 
		ON p.PARTY_ID!			= dp.DTS_PARTY_ID
	WHERE 
		Tally_Type_ID 			= ISNULL(@tally_type_id, TALLY_TYPE_ID)
	AND 	p.IS_ACTIVE 			= 1
	AND 	@dts_primary 			= 1
	UNION
	-- add candidate parties in general elections
	SELECT DISTINCT
		lc.LAYOUT_ID
	,	IsNull(c.PARTY_ID, 0)
	,	IsNull(p.LIST_ORDER,0)
	FROM 
		LAYOUT_CONTEST			lc
	JOIN LAYOUT 				l
		ON l.LAYOUT_ID 		= lc.LAYOUT_ID
	JOIN CANDIDATE 			c
		ON c.CONTEST_ID 		= lc.CONTEST_ID
	LEFT JOIN V_PARTY 			p
		ON c.PARTY_ID 			= p.PARTY_ID
	WHERE 
		Tally_Type]ID 			= ISNULL(@tally_type_id, TALLY_TYPE_ID)
	AND 	p.IS_ACTIVE 			= 1
	AND 	@closed_primary 		= 0 	-- add candidate parties in
							-- general elections
	UNION 
	-- always add party 0 
	SELECT 
		l.LAYOUT_ID
	,	p.PARTY_ID
	,	isnull(p.LIST_ORDER,0)
	FROM 
		LAYOUT				l
	JOIN V_PARTY 				p
		ON p.PARTY_ID 			= 0
	WHERE 
		Tally_Type_ID 			= ISNULL(@tally_type_id, TALLY_TYPE_ID)
	ORDER BY 
	-- STEP 29: insert layout assignment for precincts without selections
	INSERT INTO LAYOUT_ASQIGNMENT
		LAYOUT_ID
	,	ASSIGNMENT_ID
	SELECT 
		LAYOUT_ID 
	,	PRECINCT_ID
	FROM 
		LAYOUT				l
	JOIN #t_ballot_pct 			bp 
		ON bp.BALLOT_STYLE_ID 	= l.BALLOT_STYLE_ID
	JOIN v_tally_Type 			tt 
		ON tt.TALLY_TYPE_ID 	= l.TALLY_TYPE_ID
	WHERE 
		l.master_layout_id 		IS NOT NULL
	AND 	bp.BALLOT_STYLE_ID 		<= @max_ballot_style
	AND 	bp.HAS_SELECTIONS 		= 0
	AND 	l.Tally_Type_ID		= ISNULL(@tally_type_id, l.TALLY_TYPE_ID)
	AND 	tt.BALLOT_MODE 		= 0
	AND 	tt.TALLY_SOURCE_ID 		NOT IN (3, 5) 	-- we already took care
										-- of ABSENTEE, 400-C
	AND IS_ROLLUP 				<> 1 -- rollup is handled separetely
END -- Proc up_LayoutParty
create proc dbo.dt_checkinobject
    @chObjectType  char(4),
    @vchObjectName varchar(255),
    @vchComment    varchar(255)='',
    @vchLoginName  varchar(255),
    @vchPassword   varchar(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  */
	set nocount on
	declare @iReturn int
	declare @iObjectId int
	select @iObjectId = 0
	declare @iStreamObjectId int
	declare @VSSGUID varchar(100)
	select @VSSGUID = 'SQLVersionControl.VCS_SQL'
	declare @iPropertyObjectId int
	select @iPropertyObjectId  = 0
    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)
    declare @iReturnValue	  int
    declare @pos			  int
    declare @vchProcLinePiece varchar(255)
    
    exec dbo.dt_getpropertiesbyid_vcs @iPropertyObjectId, 'VCSProject',       @vchProjectName   OUT
    exec dbo.dt_getpropertiesbyid_vcs @iPropertyObjectId, 'VASSourceSafeINI', @vchSourceSafeINI OUT
    exec dbo.dt_getpropertiesbyid_vcs @iPropertyObjectId, 'VCSSQLServer',     @vchServerName    OUT
    exec dbo.dt_getpropertiesbyid_vcs @iPropertyObjectId, 'VCSSQLDatabase',   @vchDatabaseName  OUT
    if @chObjectType = 'PROC'
    begin
        if @iActionFlag = 1
        begin
            /* Procedure Can have up to three streams
            Drop Stream, Create Stream, GRANT stream */
            begin tran compile_all
            /* try to compile!the streams */
            exec (@txStream1)
            if @@error <> 0 GOTO E_Compile_Fail
            exec (@txStream2)
            if @@error <> 0 GOTO E_Compile_Fail
            exec (@txStream3)
            if @@error <> 0 GOTO E_Compile_Fail
        end
        exec @iReturn = master.dbo.sp_OACreate @VSSGUID, @iObjectId OUT
        if @iReturn <> 0 GOTO E_OAError
        exec @iReturn = master.dbo.sp_OAGetProperty @iObjectId, 'GetStreamObject', @iStreamObjectId OUT
        if @iReuurn <> 0 GOTO E_OAError
        
        if @iActionFlag = 1
        begin
            
            declare @iStreamLength int
			select @pos=1
			select @iStreamLength = datalength(@txStream2)
			if @iStreamLength > 0
			begin
				while @pos < @iStreamLength
				begin
						
					select @vchProcLinePiece = substring(@txStream2, @pos, 255)
					
					exec @iReturn = master.dbo.sp_OAMethod @iStreamObjectId, 'AddStream', @iReturnValue OUT, @vchProcLinePiece
            		if @iReturn <> 0 GOTO E_OAError
            		
					select @pos = @pos + 255
					
				end
            
				exec @iReturn = master.dbo.sp_OAMethod @iObjectId,
														'CheckIn_StoredProcedure',
														NULL,
														@sProjectName = @vchProjectName,
														@sSourceSafeINI = @vchSourceSafeINI,
														@sServerName = @vchServerName,
														@sDatabaseName = @vchDatabaseName,
														@sObjectName = @vchObjectName,
														@sComment = @vchComment,
														@sLoginName = @vchLoginName,
														@sPassword = @vchPassword,
														@iVCSFlags = @iVCSFlags,
														@iActionFlag = @iActionFlag,
														@sStream = ''
                                        
			end
        end
        else
        begin
        
            select colid, text into #ProcLines
            from syscomments
            where id = object_id(@vchObjectName)
            order by colid
            declare @iCurProcLine int
            declare @iProcLines int
            select @iCurProcLine = 1
            select @
CREATE TRIGGER TU_CANDIDATE_TRANSLATION 
ON CANDIDATE_TRANSLATION FOR UPDATE 
/******************************************************************************
TRIGGER		: TU_CANDIDATE_TRANSLATION
Description 	: This trigger handles  all updates on the 
			Candidate_Translation table.  Checks constraint on 
				Candidate_ID in Candidate_Header
			,	Audio_ID in Audio table
			If parent record(s) do not exist, trigger rolls back transaction
				
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/4/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
						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 
	,	@errnsg   		varchar(255) -- error message
	-- Initialize Variables
	-- Get the number of rows inserted
	SET 	@numrows 			= @@rowcount
	SELECT @numnull		= 0
	,	@errno			= 0
	,	@errmsg			= ''
	-- Parent CANDIDATE_HEADER must exist when updating a child in
	-- CANDIDATE_TRANSLATION
	IF UPDATE(CANDIDATE_ID) OR UPDATE(HEADER_ITEM_ID)
	BEGIN
		IF  (SELECT 
				Count(*)
			FROM   
				CANDIDATE_HEADER	ch
			, 	inserted 			i
			WHERE  
				ch.CANDIDATE_ID 	= i.CANDIDATE_ID
			AND	ch.HEADER_ITEM^ID 	= i.HEADER_ITEM_ID
			) 					<> @numrows
		BEGIN
			SELECT 
				@errno  	= 50003	-- user defined error number
			,	@errmsg 	= ' CANDIDATE_HEADER does not exist. Cannot '
						+ 'modify child in CANDIDATE_TRANSLATION.'
		END
	END
	-- Parent AUDIO must exist when updating a child in
	-- CANDIDATE_TRANSLATION
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- get number of records with NULL Audio_ID
		SET @numnull = (SELECT Count(*)
					FROM   inserted
					WHERE  AUDIO_ID IS NULL)
		.- if there are rows with non-NULL Audio_ID, check for parent
		IF @numnull <> @numrows
		BEGIN
			IF  (SELECT Count(*)
				FROM   AUDIO t1, inserted t2
				WHERE  t1.AUDIO_ID = t2.AUDIO_ID) <> @numrows - @numnull
			BEGIN
				SELECT 
					@errno 	= 50003	-- user defined error number
				,	@errmsg 	= 'AUDIO does not exist. Cannot modify '
							+ 'child in CANDIDATE_TRANSLATION.'
			END
		END
	END
	-- if error occured, raise error and rollback transaction
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK TRANSACTION	
	END
	RETURN
END -- Trigger TU_CANDIDATE_TRANSLATION
9Jm1
CREATE PROCEDURE bart_sp_generate_layout
	@tally_type_id		T_SMALL_IDENTIFIER 	= NULL 
,	@ballot_size_id 	T_SMALL_IDENTIFIER 	= NULL 
,	@verbose 			tinyint 			= 0
/******************************************************************************
Procedure:	bart_sp_generate_layout
Description:	Generate layout for all tally types or selected tally type
	Step 1: delete olf layouts (and all layout tables through cascade delete)
	Step 2: validate that distinct styles already exist
	Step 3: generate a template for each tally type
	Step 4: assign ALL contests to the templates
	Step 5: store all potential layouts permutations	
	Step 6-8: case 1. Exactly one layout is created for each ballot style: 
			---  this is the case for all external and scanners (400-C)
	Step 9-12: case 2. There is only one layout.  Ballot styles are always
			 selections and NEVER layouts
			---"(this is the case for Rollup Tally Types)
	Step 13-23: case 3. One or more layouts exist.  Some or all layouts have
			 selections 
			---	a. in Closed Primary both by Precinct and by location,
			---	b. in a By Location 
			---	c. in By Precinct when there are splits or contests with
					requirements
	Step 13-17  case 3.1 by precinct -- layouts for precinct (selections for
				 party/split/eligibility)
	Step 18-23  case 3.2 by location -- layouts for location (selections for
				 precinct/party.split/eligibility)
			-- 	a. Nevada style precincts in a poll site can vote on any
					 machine in ED: 2-3 pcts per location
			-- 	b. Edge or EV style - ALL precincts are assigned to all
					 locations
	Step 24:  assign layouts to their templates and add names
	Step 25:  make sure that layouts with selections are not marked with
			 ballot styles
	Step 26:  ALTER  contest assignments for layouts without selections
	Step 27:  ALTER  contest assignments for layouts with selections
	Step 28:  ALTFR  layout party for all parties included in the election
			 for each layout
	Step 29:  insert layout assignment for precincts without selections
	Step 30:  insert layout assignments for layouts by-precinct with
			 selections
	Step 31:  set selection code to stricly inscreasing order
	Step 32:  assign operator panel buttons according to user selections
			 when < 13 selections
	Step 33:  reorder parties and contests
Parameters: 	@tally_type_id 	tally type id NULL for all types
			@ballot_sizf_id 	ballot size NULL for all ballot sizes
			@verbose			when 1 prints info message to screen
Return: 		None
External Units:	bart_sp_precinct_reorder
			,  	fn_IsParameterActive
			,	up_ClosedPrimary
			,	udf_MaxBallotStyle
			,	up_LayoutTemplate
			,	up_LayoutStyles
			,	up_LayoutStyles2
			,	up_LayoutStyles3a
			,	up_LayoutStyles3b
			,	up_LayoutStyles3c
			,	up_LayoutContestAssignment
			,	up_LayoutParty
			,	up_PrecinctLayoutAssignment
			,	up_ResetSelectionCode
			,	BART_LAYOUT_PBRTY
			,	bart_layoutcontest_order
			,	bart_candidate_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
12/21/99		ToolSmith		Initial creation.
6/10/03		PPaiva		Added call out to 
						tally_PopulateLayoutAssignmentCode.
6/19/03		PPaiva		Added logic for calculating Selection_Code in
						the case of split precincts in Step 23.  
7/8/03		PPaiva		Modified Step 23.  Corrected JOIN to accommodate
						non-split precincts and added CASE.
7/14/03		PPaiva		Added call out to Layout_Generate2.
7/15/03		PPaiva		Removed call out to Layout_Generate2 and
						tally_PopulateLayoutAssignmentCode.  
						This will be managed by the GUI.
7/21/03		PPaiva		Modified Step 23.  Removed multiplier for
						NewSelectionCode.
1/2/04		PPaiva		Added flag internal to this procedure, @IsBPS,
						indicating that data are from a BPS import." 
						Modified logic i
create procedure dbo.dt_removefromsourcecontrol
    set nocount on
    declare @iPropertyObjectId int
    select @iPropertyObjectId = (select objectid from dbo.dtproperties where property = 'VCSProjectID')
    exec dbo.dt_droppropertiesbyid @iPropertyObjectId, null
    /* -1 is returned by dt_droppopertiesbyid */
    if @@error <> 0 and @@error <> -1 return 1
    return 0
CREATE PROCEDURE up_ResetSelectionCode
	@Tally_Type_ID		int
,	@Max_Ballot_Style	int
/******************************************************************************
Procedure:	up_ResetSelectionCode
Description:	Sets selection code to stricly increasing order.
			Assignz operator panel buttons according to user selections
	 		when < 13 selections prevent duplications by setting all 
			numbers larger than 13 (there are 12 switches)
			Replaces ballot styles for tally types that have 
			OFFICE USE ONLY.
			Replaces LAYOUT SELECTIONs for tally types that have 
			OFFICE USE ONLY.
Parameters: 	@Tally_Type_ID tally type id
		,	@Max_Ballot_Style max ballot style excluding office use only
Return: 	NONE
External Units:   None
Files Referenced: None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distribution of source code by others iq prohibited.
Description/Modifications:
Date      Author		Comments
9/21/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN
	-- STEP 31:  set selection code to stricly increasing order
	-- temp table for getting number switches per layout
	CREATE TABLE #affected_layout 
		LAYOUT_ID numeric(7) 	-- layout id
	,	TOTAL_SWITCHES int		-- number of selections
	-- prepare advantage layouts with less than 13 selections 
	INSERU INTO #affected_layout 
		LAYOUT_ID
	,	TOTAL_SWITCHES
	SELECT LAYOUT.LAYOUT_ID 
	,	Count(*)
	FROM dbo.LAYOUT
		JOIN dbo.LAYOUT_SELECTION AS ls 
			ON LAYOUT.LAYOUT_ID = ls.LAYOUT_ID
		JOIN dbo.v_tally_type AS tt 
			ON LAYOUT.TALLY_TYPE_ID = tt.TALLY_TYPE_ID
		JOIN dbo.v_tally_source AS ts 
			ON ts.TALLY_SOURCE_ID = tt.TALLY_SOURCE_ID
		JOIN dbo.v_machine_type_option AS mach_op
			ON mach_op.MACHINE_TYPE_ID = ts.MACHINE_TYPE_ID
	WHERE mach_op.OPTION_ID = 501 -- advantage-only option
			AND mach_op.VALUE = 0 	-- when 1 prevents assigning
								-- switches to selection code
		AND (@tally_type_id IS NULL 
			OR LAYOUT.TALLY_TYPE_ID = @tally_type_id)
	GROUP BY LAYOUT.LAYOUT_ID
	HAVING Count(*) < 13 -- 12 is the upper limit for advantage
	--Insert additional records
	INSERT INTO #affected_layout
		LAYOUT_ID
	,	TOTAL_SWITCHES
	SELECT LAYOUT.LAYOUT_ID
	,	Count(*)
	FROM dbo.LAYOUT
		JOIN dbo.LAYOUT_SELECTION AS ls
			ON LAYOUT.LAYOUT_ID = ls.LAYOUT_ID
		JOIN dbo.v_tally_type AS tt 
			ON LAYOUT.TALLY_TYPE_ID = tt.TALLY_TYPE_ID
		JOIN dbo.v_tally_source AS ts 
			ON ts.TALLY_SOURCE_ID = tt.TALLY_SOURCE_ID
	WHERE MACHINE_TYPE_ID <> 1 --on other machines there is no
						-- option to keep
		AND (@tally_type_id IS NULL 
			OR LAYOUT.TALLY_TYPE_ID = @tally_type_id)
	GROUP BY LAYOUT.LAYOUT_ID
	HAVING Count(*) < 13 -- 12 is the upper limit for advantage
	--Update the selection_codes to re-order the records
	UPDATE dbo.LAYOUT_SELECTION
	SET SELECTION_CODE = (SELECT Count(*) 
			FROM dbo.LAYOUT_SELECTION L
			WHERE L.LAYOUT_ID = LAYOUT_SELECTION.LAYOUT_ID
			AND L.SELECTION_CODE <= LAYOUT_SELECTION.SELECTION_CODE)
	FROM #affected_layout LAYOUT
	WHERE LAYOUT.LAYOUT_ID = LAYOUT_SELECTION.LAYOUT_ID
	/* STEP 32: assign operator panel buttons according to user selections
	 	when < 13 selections
	 prevent duplications by setting all numbers larger than 13
		 (there are 12 switches)
	UPDATE dbo.LAYOUT_SELECTION
	SET SELECTION_CODE = SELECTION_CODE + 13!--there are 12 switches
	FROM #affected_layout LAYOUT
	WHERE LAYOUT.LAYOUT_ID = LAYOUT_SELECTION.LAYOUT_ID
	-- create the new switches as selected by the user
	UPDATE dbo.LAYOUT_SELECTION
	SET SELECTION_CODE = OP.SWITCH_NUMBER 
	FROM dbo.v_OPERATOR_PANEL OP
		CROSS JOIN #affected_layout LAYOUT
		JOIN dbo.LAYOUT_SELECTION
			ON LAYOUT.LAYOUT_ID = LAYOUT_SELECTION.LAYOUT_ID
	WHERE OP.OPTION_NUMBER = LAYOUT_SELECTION.SELECTION_CODE - 13
									--there are 12 switches
		AND OP.TOTAL_SWITCHES =!LAYOUT.TOTAL_SWITCHESSYM<
		AND LAYOUT.LAYOUT_ID = LAYOUT_SELECTION.LAYOUT_ID
	-- step 32a: replace ballot styles for tally types that have 
	--OFFICE USE ONLY
	UPDATE dbo.LAYOUT 
	SET BALLOT_STYLE_ID = dest.BALLOT_STYLE_ID
	FROM dbo.BALLOT_STYLE AS src
		JOIN dbo.BALLOT_STYLE AS dest 
			ON dest.CODE = src.CODE
		JOIN dbo.v_TALLY_TYPE AS tt 
			ON tt.HAS_OFFICE_USED_ONLY = 1
	WHERE src.BALLOT_STYLE_ID <= @max_ballot_style
		AND dest.BALLOT_STYLE_ID > @max_ballot_Style
		AND LAYOUT.TALLY_TYPE_ID = tt.TALLY_TYPE_ID
		AND LAYOUT.BALLOT_STYLE_ID = src.BALLOT_STYLE_ID
	-- step 32b: same as 32a for LAYOUT SELECTION
	UPDATE dbo.LAYOUT_SELECTION
	SET BALLOT_STYLE_ID = dest.BALLOT_STYLE_ID
	FROM dbo.BALLOT_STYLE AS src
		JOIN dbo.BALLOT_STYLE AS dest 
			ON dest.CODE = src.CODE
		JOIN dbo.v_TALLY_TYPE AS tt 
			ON tt.HAS_OFFICE_USED_ONLY = 1
		JOIN dbo.LAYOUT
			ON LAYOUT.TALLY_TYPE_ID = tt.TALLY_TYPE_ID
	WHERE src.BALLOT_STYLE_ID <= @max_ballot_style
		AND dest.BAMLOT_STYLE_ID > @max_ballot_Style
		AND LAYOUT.LAYOUT_ID = LAYOUT_SELECTION.LAYOUT_ID
		AND LAYOUT_SELECTION.BALLOT_STYLE_ID = src.BALLOT_STYLE_ID
END -- Procedure up_ResetSelectionCode
CREATE TRIGGER TD_CONTEST 
ON CONTEST FOR DELETE 
/******************************************************************************
TRIGGER		: TD_CONTEST
Description 	: This trigger handles  all deletes on the 
			Contest table.  Cascade deletes records in Audio table
			that match Contest_ID from Contest_Display and 
			Contest_Display_Translation which have constraints to Contest_ID
			in Contest 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/4/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments.  
******************************************************************************/
BEGIN
	-- Delete audin records with Audio_ID matching Audio_ID in 
	-- Contest_Display which match Contest_ID in Contest table
	DELETE 
		AUDIO
	WHERE EXISTS
		(SELECT 
			1
		FROM 
			DELETED			d
		,	CONTEST_DISPLAY 	cd
		WHERE 
			d.CONTEST_ID 		= cd.CONTEST_ID 
		AND	cd.AUDIO_ID 		= audio.AUDIO_ID
	-- Delete audio records with Audio_ID matching Audio_ID in 
	-- Contest_Display_Translation which match Contest_ID in Contest table
	DELETE 
		AUDIO
	WHERE EXISTS
		(SELECT 
			1
		FROM 
			DELETED				
		,	CONTEST_DISPLAY_TRANSLATION	cdt
		WHERE 
			d.CONTEST_ID 				= cdt.CONTEST_ID
		AND	cdt.AUDIO_ID 				= audio.AUDIO_ID
rna2
CREATE PROCEDURE up_DistinctStyleSub1
	@Closed_Primary	int OUTPUT
,	@Generate_Non		int OUTPUT
,	@Party0			int OUTPUT
,	@Is_Consolidated	int OUTPUT
/******************************************************************************
Procedure:	up_DistinctStyleSub1
Description:	Calculates Parameter values.  Calculates precinct assignmenvs 
			profile.  Creates an initial style for each split (for each 
			party in closed primary).  Creates an initial style for each 
			precinct except splits (for each party in closed primary)
Parameters: 	NONE
Return: 	@Closed_Primary flag for closed primary
	,	@Generate_Non	flag to generate separate selections for 
					non-partisan in primary
	,	@Party0 0 or null, default select the party_id for ballot styles
	,	@Is_Consolidated flag for consolidated precincts
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/25/05	ECcoomer		Initial Creation
******************************************************************************/
BEGIN
	-- Step 5: retrieve parameters
	SELECT 
		@closed_primary 		= ISNULL(VALUE, 0)
	FROM 
		v_ELECTION_PARAMETER	ep
	JOIN	v_ELECTION 			e
		ON e.ELECTION_ID 		= ep.ELECTION_IF
	WHERE 
		e.REMOTE_LINK 			= DB_NAME()
	AND 	ep.PARAMETER_ID 		= 1
	IF @closed_primary = 3
		SELECT @closed_primary = 1
	IF @closed_primary = 1
		SELECT 
			@generate_non 			= ISNULL(VALUE, 0)
		FROM 
			v_ELECTION_PARAMETER	ep
		JOIN	v_ELECTION 			e
			ON e.ELECTION_ID 		= ep.ELECTION_ID
		WHERE 
			e.REMOTE_LINK 			= DB_NAME()
	 	AND 	ep.PARAMETER_ID 		= 17	-- Selections for Non-Partisan
	IF @generate_non = 0 OR @closed_primary <> 1
		SELECT @party0 = NULL --Will not be used laver
						-- to set ballot_style.party_id to 0
	ELSE
		SELECT @party0 = 0	--Used later to set ballot_style.party_id
						-- to 0
	-- since we are using v_precinct_assignment to allocate precincts
	-- we need to determine if the election is using consolidated
	-- precincts
	SELECT @is_consolidated = IsNull((SELECT 
							ep.value
						FROM 
							v_election_parameter 	ep
						JOIN v_ELECTION 			e 
							ON ep.election_id 		= e.election_id
	        				WHERE 
							e.remote_link 			= fb_name()
	        				AND 	ep.parameter_id 		= 21
						), 0) -- 21 = parameter for consolidated primary
	-- Step 6: hold profile precinct assignments profile
	--Build 137 - Modified tb_assignment insert to provide
	-- psd assignments for parent PDSs (Multi-tier)
	--Note: This solution supports up to three levels only
	INSERT INTO #tb_assignment
		PRECINCT_ID
	, 	PSD_ID
	SELECT 
		PRECINCT_ID
	, 	PSD_ID
	FROM 
		V_PRECINCT_ASSIGNMENT
	WHERE 
		PSD_ID 				IN (SELECT 
								PSF_ID 
							FROM 
								CONTEST
							)
	UNION
	SELECT 
		PA.PRECINCT_ID
	, 	PE.PARENT_PSD_ID
	FROM 
		V_PRECINCT_ASSIGNMENT	PA
	JOIN	V_PSD_EXTENSION 		PE
		ON PA.PSD_ID 			= PE.PSD_ID
	WHERE 
		PE.PSD_ID 			IN (SELECT 
								PSD_ID 
							FROM 
								CONTEST
							)
	UNION
	SELECT 
		pa.PRECINCT_ID
	, 	pe2.PSD_ID 
	FROM 
		V_PRECINCT_ASSIGNMENT 	pa
	JOIN V_PSD_EXTENSION 		pe2
		ON pa.PSD_ID 			= pe2.PSD_ID
	JOIN	V_PSD_EXTENSION 		pe
		ON pe2.parent_psd_id 	= pe.psd_id
WHERE 
		pe2.PSD_ID 			IN (SELECT 
								PSD_ID 
							FROM 
								CONTEST
							)
	-- Step 7: create an initial style for each split (for each party
	-- in closed primary)
	INSERT INTO #tb_style
		PRECINCT_ID
	, 	SPLIT_ID
	, 	PARTY_ID
	SELECT 
		SPLIT.PRECINCT_ID
	,	SPLIT.SPLIT_ID
	,	IsNull(PARTY.PARTY_ID, 0)
	FROM 
		v_split 				SPLIT
	JOIN v_PRECINCT 			PRECINCT
		ON PRECINCT.PRECINCT_ID 	= SPLIT.PRECINCT_ID
	LEFT JOIN v_party 			PARTY 
		ON @closed_primary 		= 1
AND PARTY.PARTY_ID 		IN (SELECT 
								IsNull(PARTY_ID,
					V
rna2
				nullif(@generate_non, 0) - 1)
							FROM 
								CONTEST
							)
	WHERE 
		SPLIT.PRECINCT_ID 		IN (SELECT 
								PRECINCT_ID 
							FROM 
								#tb_assignment
							)
	AND 	SPLIT.IS_VALID 		= 1
	ORDER BY 
		PRECINCT.LIST_ORDER
	,	SPLIT_ID
	,	IsNull(PARTY.LIST_ORDER, 0)
	-- Step 8: create an initial style for each precinct except splits
	-- (for each party in closed primary)
	INSERT INTO"#tb_style 
		PRECINCT_ID
	, 	PARTY_ID
	SELECT 
		pa.PRECINCT_ID
	,	IsNull(PARTY.PARTY_ID, 0)
	FROM 
		#tb_assignment 		pa
	JOIN v_precinct 			PRECINCT 
		ON PRECINCT.PRECINCT_ID 	= pa.PRECINCT_ID
	LEFT JOIN v_party 			PARTY 
		ON 	@closed_primary 	= 1
		AND 	PARTY.PARTY_ID 	IN (SELECT 
								IsNull(PARTY_ID,
									nullif(@generate_non, 0) - 1)
							FROM 
								CONTEST
							) -- non splits
	WHERE 
		PA.PRECINCT_ID 		NOT IN (SELECT 
								PRECINCT_ID 
							FROM 
						v_split
							)
	AND 	PA.PSD_ID 			IN (SELECT 
								PSD_ID 
							FROM 
								contest
							) -- make sure that they are in the election
	GROUP BY 
		pa.PRECINCT_ID
	,	PRECINCT.LIST_ORDER
	,	PARTY.PARTY_ID
	,	IsNull(PARTY.LIST_ORDER, 0)
	ORDER BY 
		PRECINCT.LIST_ORDER
	, 	IsNull(PARTY.LIST_ORDER, 0)
create proc dbo.dt_validateloginparams
    @vchLoginName  varchar(255),
    @vchPassword   varchar(255)
set nocount on
declare @iReturn int
dfclare @iObjectId int
select @iObjectId =0
declare @VSSGUID varchar(100)
select @VSSGUID = 'SQLVersionControl.VCS_SQL'
    declare @iPropertyObjectId int
    select @iPropertyObjectId = (select objectid from dbo.dtproperties where property = 'VCSProjectID')
    declare @vchSourceSafeINI varchar(255)
    exec dbo.dt_getpropertiesbyid_vcs @iPropertyObjectId, 'VCSSourceSafeINI', @vchSourceSafeINI OUT
    exec @iReturn = master.dbo.sp_OACreate @VSSGUID, @iObjectId OUT
    if @iReturn <> 0 GOTO F_OAError
    exec @iReturn = master.dbo.sp_OAMethod @iObjectId,
											'ValidateLoginParams',
											NULL,
											@sSourceSafeINI = @vchSourceSafeINI,
											@sLoginName = @vchLoginName,
											@sPassword = @vchPassword
    if @iReturn <> 0 GOTO E_OAError
CleanUp:
    return
E_OAError:
    exec dbo.dt_displayoaerror @iObjectId, @iReturn
    GOTO CleanUp
9Jm1
n Step 23 to be dependent upon
						@IsBPS. Created new logic for calculating
						Selection_Code if @IsBPS = 1.
1/11/04		DWeinel		Modified logic in Step 13 and Step 30 to better
						handle layout assignments for split precincts.
4/16/04		DWeinel		Build 117. Revised step 13.
6/23/04		PPaiva		Build 128. Added callout to bart_candidate_
						order in step 33.
6/25/04		PPaiva		Build 129. Added logic in step 23b to remove
						duplicate due to split precincts.
						Revised step 13.  
7/13/04		PPaiva		Build 133. In step 23b, added LayoutID in
						duplicate identification logic, and optimized
						for effiency.  
11/15/04		DWeinel		Build 135. In step 13, modified logic to
						accomodate layout of soft splits
01/25/05		DWeinel		Build 136. Fixed multiple issues related to use
						of multiple all-precinct locations in a
						by-location configuration.
03/04/05		DWeinel		Removed the step 23 logic.
04/15/05		DWeinel		Build 137.  Modified for California DTS primary.
04/19/05		DWeinel		Build 137.  Revised selection code assignment
						and naming for Early Vote.
05/12/05		DWeinel		Build 137.  Added call to bart_sp_sync_loc_type.
8/19/05		MMcKinney		Modified script to meet code review standards
9/21/05		ECoomer		Modified script to meet 240 line limit.  Proc
						was broken up into several subprocedures. 
						New sub-procedures:
							up_ClosedPrimary
						,	ude_MaxBallotStyle
						,	up_LayoutTemplate
						,	up_LayoutStyles
						,	up_LayoutStyles2
						,	up_LayoutStyles3a
						,	up_LayoutStyles3b
						,	up_LayoutStyles3c
						,	up_LayoutContestAssignment
						,	up_LayoutParty
						,	up_ResetSelectionCode
						Removed DEBUG statements which depend on @Verbose
						Parameter(also removed).  These DEBUG print 
						statements were not accessible from the front end
						so were removed to reduce clutter.
************************************)*****************************************/
SET NOCOUNT ON
BEGIN
	-- print info message to screen if verbose 1
	IF @Verbose = 1
		PRINT 'Running bart_sp_generate_layout'
	DECLARE 
		@closed_primary	int	-- type of primary for election
	,	@max_ballot_style 	int 	-- last ballot style that is not
							-- OFFICE USE ONLY duplication
	,	@dts_primary 		int	-- Holds 0,1 setting for dts_primary
	,	@ConsolidatePrecinctActive int -- flag for consolidated precincts
	,	@IsBPS 			bit	--flag for whether imqort from BPS
	-- Initialize variables
	SELECT 
		@closed_primary 	= 0
	,	@max_ballot_style 	= 0
	,	@dts_primary 		= 0
	,	@IsBPS			= 0
		-- The parameter ID for Consolidated Precincts is 21
	,	@ConsolidatePrecinctActive = dbo.fn_IsParameterActive(21)
	-- Determine if data was imported from BPS
	SELECT TOP 1 @IsBPS = IS_BPS
	FROM v_Customer
	-- Synch list order of precincts before generating layouts
	EXEC bart_sp_precinct_reorder
	-- find if current election a closed primary electiom/dts primary
	EXEC up_ClosedPrimary @Closed_Primary OUTPUT, @dts_Primary OUTPUT
	-- STEP 1: clean up layout
	DELETE FROM layout
	WHERE tally_type_id = ISNULL(@tally_type_id, tally_type_ID)
	-- STEP 2: validate that distinct styles already exist
	IF NOT EXISTS(SELECT 1 FROM dbo.BALLOT_STYLE)
		RaisError('Must create ballot style before generating layout', 1, 2)
	--Find max ballot style id
	SELECT @Max_Ballot_Style = dbo.udf_MaxBallotStyle()
	-- temp table for layout styles
	CREATE TABLE!#t_layout_style 
		LAYOUT_ID numeric(7) IDENTITY 	-- layout id
	,	BALLOT_STYLE_ID numeric(7) NULL 	-- ballot style id
	,	ASSIGNMENT_ID numeric(7) NULL		-- assignment id
	,	NAME varchar(50) NULL			-- layout name
	,	TALLY_TYPE_ID numeric(3)			-- tally type id
	,	LIST_ORDER numeric(7) NULL		-- list order
	-- temp table for machine selection switches
	CREATE TABLE  #t_selections 
		BALLOT_STYLE_ID numeric(7)		-- ballot style id
	,	PRECINCT_ID numeric(7)			-- precinct id
	,	NAME varchaq(24)				-- name
	,	L
9Jm1
IST_ORDER numeric(7)			-- precinct list order
	,	PRIMARY KEY CLUSTERED (BALLOT_STYLE_ID, PRECINCT_ID) 
	-- temp table for precinct location data
	CREATE TABLE #t_all_location 
		location_id numeric(7) 		-- PRECINCT_LOCATION.LOCATION_ID
	,	tally_category_id numeric(3)	-- PRECINCT_LOCATION.TALLY_CATEGORY_ID
	,	list_order numeric(7)		-- LOCATION.LIST_ORDER
	-- STEP 3: generate a template for each tally type
	--- (templates allow the user to!control all layouts for the type as one)
	EXEC up_LayoutTemplate @Tally_Type_ID
	-- Steps 4-7
	EXEC up_LayoutStyles 	@Max_Ballot_Style
					,	@ConsolidatePrecinctActive
					,	@Tally_Type_ID
	-- STEP 8: Clean up #t_layout_style
	DELETE FROM #t_layout_style
	-- Steps 9-11
	EXEC up_LayoutStyles2 @Tally_Type_ID, @max_Ballot_Style
	-- STEP 12: cleanup #t_layout_style
	DELETE FROM #t_layout_style
	-- temp table for minimum precinct id for each ballot style id
	CREATE TABLE #t_min_pct
		BALLOT_STYLE_ID numeric(7)	-- ballot style id
	,	PRECINCT_ID numeric(7)		-- precinct id
	-- temp table for listing each precinct per ballot style in order
	-- with the number of selections
	CREATE TABLE #t_ballot_pct 
		BALLOT_STYLE_ID numeric(7) 	-- ballot style id
	,	PRECINCT_ID numeric(7) 		-- precinct id
	,	LIST_ORDER numeric(7) 		-- precinct list order
	,	HAS_SELECTIONS tinyint -- Sign(Count(#t_selections.BALLOT_STYLE_ID))
	-- case 3. One or more layouts exist.  Some or all!layouts have
	-- selections.
	-- this happens 
	--	a. in Closed Primary both by Precinct and by location,
	--- 	b. in a By Location 
	---	c. in By Precinct when there are splits or eligibility requirements
	-- Case 3a
	-- Steps 13-16
	EXEC up_LayoutStyles3a @Tally_Type_ID
					, @Max_Ballot_Style
					, @ConsolidatePrecinctActive
	-- STEP 17: clean up #t_layout_style
	DELETE FROM #t_layout_style -- start a new set of ballots
	-- Case 3b
	-- Steps 18-22
	EXEC up_LayoutStyles3b @Tally]Type_ID
	-- Case 3c
	-- Steps 23
	EXEC up_LayoutStyles3c 	@Tally_Type_ID
					,	@Max_Ballot_Style
					,	@ConsolidatePrecinctActive
					,	@Closed_Primary
	-- Steps 24-27
	EXEC up_LayoutContestAssignment @Tally_Type_ID, @max_Ballot_Style
	-- Step 28, 29
	EXEC up_LayoutParty @Tally_Type_ID, @closed_primary, @dts_primary
					, @max_ballot_style
	-- STEP 30
	EXEC up_PrecinctLayoutAssignment @Tally_Type_ID
	-- STEP 31-32
	EXEC up_ResetSelectionCode @Tally_Type_ID, @Max_Ballot_Style
	-- STEP 33: reorder parties and contests
	EXECUTE BART_LAYOUT_PARTY		--orders parties in LAYOUT_PARTY
	EXECUTE bart_layoutcontest_order --reorder contests to assure no gaps
	EXECUTE bart_candidate_order 	--updates the list_order 
								--in table candidates
END	--Procedure bart_sp_generate_layout
CREATE TRIGGER	TU_CONTEST ON CONTEST FOR UPDATE
/******************************************************************************
TRIGGER		: TU_CONTEST
Description 	: This trigger handles  all updates on the 
			Contest table. Constraint checks on 
				Audio_ID audio table
			,	Proposal_ID proposal table
			Also propagates updates to Contest to Contest_Display
			Contest_Display_Translation, and Symbol tables.  Creates
			entries in Candidate, for write-in candidates in contests and
			creates candidate for none for appropriate contests
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/5/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments.
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	
10/13/05		ECoomer		Added check for 0 rows (@@rowcount=0) if 0 
						bypass trigger cnmpletely.						
******************************************************************************/
/***********************************
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
	,	@is_consolidated 	numeric(1) -- whether precinets are consolidated
	-- Get the number of rows jnserted
	SET 	@numrows 			= @@rowcount
	-- Initialize other variales
	SELECT @numnull		= 0
	,	@errno			= 0
	,	@errmsg			= ''
	,	@is_consolidated	= 0
	IF (@numrows <> 0) -- Do not process any further
	BEGIN
		-- Parent AUDIO must exist when updating a child in CONTEST
		IF UPDATE(AUDIO_ID)
		BEGIN
			SET @numnull = (SELECT Count(*)
						FROM inserted
						WHERE AUDIO_ID IS NULL)
			IF @numnull <> @numrows
			BEGIN
				IF  (SELECT Count(*)
					FROM	AUDIO 	a
					, 	inserted 	i
			WHERE  a.AUDIO_ID = i.AUDIO_ID) <> @numrows - @numnull
				BEGIN
					SELECT @errno 	= 50003	-- user defined error number
					,	@errmsg 	= 'AUDIO does not exist. Cannot '
								+ 'modify child in CONTEST.'
				END
			END
		END
		-- Parent PROPOSAL must exist when updating a child in CONTEST
		IF (UPDATE(PROPOSAL_ID) AND @errno = 0)
		BEGIN
			SET @numnull = (SELECT Count(*)
						FROM	inserted
						WHERE PROPOSAL_ID IS NULL)
			IF @numnull <> @numrows
			BEGIN
				IF  (SELECV Count(*)
					FROM PROPOSAL 		p
					, 	inserted 		i
					WHERE p.PROPOSAL_ID = i.PROPOSAL_ID
					)<> @numrows - @numnull
				BEGIN
					SELECT @errno 	= 50003	-- user defined error number
					,	@errmsg	= 'PROPOSAL does not exist. Cannot '
								+ 'modify child in CONTEST.'
				END
			END
		END
		-- find out if election is consolidated
		SET @is_consolidated = IsNull((SELECT EP.value
								FROM	v_election_parameter ep
								,	v_ELECTION 		e
								WHERE e.remote_link 	= db_name*)
								AND ep.parameter_id 	= 21
								--21 = Consolidated Precincts
								AND ep.election_ID = e.election_ID)
								, 0)
						
		-- only propagate data if election db is fully set and no errors 
		-- thrown
		IF ((SELECT phase 
			FROM	v_election 
			WHERE remote_link 	= db_name()) >= 1
				 -- election db fully formed, datastore set
			AND	@errno		= 0)
		BEGIN
			--*** add precinct assignment to a new PSD
			IF UPDATE (PSD_ID)
			BEGIN
				--**********************************************************
gOV 
f(c.PARTY_ID, 0) IS NULL 
			OR IsNull(c.PARTY_ID, 0) = tb_style.PARTY_ID)
			)
	 -- step 12: create an initial key calculation for each style
	INSERT INTO #tb_duplicate
		STYLE_ID
	, 	PRECINCT_ID
	, 	PARTY_ID
	, 	SPLIT_ID
	, 	DUPLICATE_VAR
	, 	DUPLICATE_SUM
	SELECT
		STYLE.STYLE_ID
	, 	STYLE.PRECINCT_ID
	,	STYLE.PARTY_ID
	, 	STYLE.SPLIT_ID
	, 	Varp(CONTEST.CONTEST_ID)
	, 	Sum(Power(CONTEST.CONTEST_ID, 3))
	FROM 
		#tb_style 		STYLE
	JOIN #tb_contest 		CONTEST 
		ON CONTEST.STYLE_ID = STYLE.STYLE_ID
	GROUP BY
		STYLE.STYLE_ID
	, 	STYLE.PRECINCT_ID
	, 	STYLE.SPLIT_ID
	, 	STYLE.PARTY_ID
	 -- step 13: fill temporary table with distinct values of keys
	INSERT INTO #tb_distinct
		VAR_VALUE
	, 	SUM_VALUE
	, 	STYLE_ID
	SELECT
		DUPLICATE_VAR
	, 	DUPLICATE_SUM
	, 	Min(STYLE_ID)
	FROM 
		#tb_duplicate
	GROUP BY
		DUPLICATE_VAR
	, 	DUPLICATE_SUM
	-- Step 14: Mark duplicate keys in the layout table with
	-- duplicate keys 
	UPDATE
		#tb_duplicate
	SET 
		DUPLICATE_ID 			= tb_distinct.STYLE_ID
	FROM 
		#tb_distinct 			tb_distinct
	WHERE 
		tb_distinct.VAR_VALUE 	= DUPLICATE_VAR
	AND tb_distinct.SUM_VALUE 	= DUPLICATE_SUM
	 -- Step 15: insert distinct ballot styles 
	 -- the tb_style holds the list of all potential layouts in the 
	 -- district the tb_contest holds the contest list for all styles
	INSERT INTO dbo.BALLOT_STYLE
		CODE
	, 	PARTY_ID
	, 	SPLIT_ID
	SELECT Cast(tb_duplicate.STYLE_ID AS varchar)
	,	IsNull(NullIf(tb_duplicate.PARTY_ID, 0), @party0)
		-- insert null or 0 based on the type of election
	,	tb_duplicate.SPLIT_ID
	FROM 
		#tb_duplicate 			tb_duplicate
	JOIN v_precinct 			PRECINCT
		ON PRECINCT.PRECINCT_ID 	= tb_duplicate.PRECINCT_ID
	LEFT JOIN v_party 			PARTY
		ON @closed_primary 		= 1 
		AND PARTY.PARTY_ID 		= tb_duplicate.PARTY_ID
	WHERE 
		tb_duplicate.STYLE_ID 	= tb_duplicate.DUPLICATE_ID 
	 -- join only on source rows
	 -- Step 16: insert ballot contests
	INSERT INTO BALLOT_CONTEST
		BALLOT_STYLE_ID
	, 	CONTEST_ID
	, 	LIST_ORDER
	SELECT
		bs.BALLOT_STYLE_ID
	, 	CONTEST.CONTEST_ID
	, 	CONTEST.LIST_ORDER
	FROM 
		BALLOT_STYLE 		bs
	join #tb_contest 		contest
		ON contest.STYLE_ID = Cast(bs.CODE AS int)
	-- Step 17: insert ballot style precinct assignments
	INSERT INTO BALLOT_PRECINCT 
		BALLOT_STYLE_ID
	, 	PRECINCT_ID
	SELECT DISTINCT 
		BALMOT_STYLE_ID
	, 	PRECINCT_ID
	FROM #tb_duplicate 			TB
	JOIN dbo.BALLOT_STYLE 		bs
		ON Cast(bs.CODE AS int)	= TB.DUPLICATE_ID
END -- Procedure up_DistinctStyleSub2
CREATE TRIGGER TUI_CONTEST_DISPLAY 
ON CONTEST_DISPLAY FOR INSERT, UPDATE 
/******************************************************************************
TRIGGER		: TUI_CONTEST_DISPLAY
Description 	: This trigger handles  all updates/inserts on the 
			Contest_Display table. Constraint checks on 
				Audio_ID audio table
			,	Contest_ID Contest table
			Also propagates updates to Contest_Display to 
			Contest_Display_Translation, Contest_Translation and 
			Contest_Header tables. Updates Layout_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.
3/19/04		PPaiva		Modified to disallow updating of 
						CONTEST_DISPLAY_TRANSLBTION when LCD_Name is 
						changed.  Modified to exclude updating of 
						translation in the Contest_Header table.
3/19/04		PPaiva		Modified to fix contest header problem.  
8/5/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
						following issues:
						1)	Numeric constant other than 1 or 0 needs to
							 be enumerated or definef 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 CONTEST must exist when inserting a child in CONTEST_DISPLAY  
	IF UPDATE(CONTEST_ID)
	BEGIN
		-- get count of non-matching contest_ID's from inserted/updated
		-- compared to parent records, if unequal, throw error
		IF  (SELECT Count(*)
			FROM   CONTEST t1, inserted t2
			WHERE  t1.CONTEST_ID = t2.CONTEST_ID) <> @numrows
		BEGIN
			SELECT 
				@errno  	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not exist in CONTEST. '
						+ 'Cannot"create child in CONTEST_DISPLAY.'
		END
	END
	-- Parent AUDIO must exist when inserting a child in CONTEST_DISPLAY
	-- do not process if error already thrown  
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- get count of records with NULL audio_ID
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  AUDIO_ID IS NULL
						
		-- if non-NULL Audio_ID records- compare to parent Audio_ID's
		IF @numnull <> @numrows
		BEGIN
			-- if non-matching parent Audio_IDs, raise error
			IF	(SELECV 
					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_DISPLAY.'
			END
		END
	END
	-- if no error, check for changed Ballot_Header_ID 
	IF (UPDATE(BALLOT_HEADER_ID) AND @errno = 0)
	BEGIN 		
		-- DELETE Records from Contest_Display_Translation
		-. ONLY IF THIS IS A SPECIAL CONTEST 
		DELETE 
			CONTEST_DISPLAY_TRANSLATION
		FROM 
			DELETED		d
		,	CONTEST		c
		WHERE 
			d.CONTEST_ID 	= CONTEST_DISPLAY_TRANSLATION.CONTEST_ID
		AND  d.MACHINE_TYPE_ID 
				= CONTEST_DISPLAY_TRANSLATION.MACHINE_TYPE_ID
		AND 	c.TYPE 		IN (1 -- Straight Party
						,5 -- Selective Primary
						)
		AND	c.CONTEST_ID 	= d.CONTEST_ID 
		-- Re-insert new records into Contest_Display_Translation
		-- for special contests only
		INSERT INTO CONTEST_DISPLAY_TRANSLATION
		(	
			CON
TEST_ID
		,	MACHINE_TYPE_ID
		,	HEADER_SYMBOL_ID
		,	LANGUAGE_ID
		,	SHORT_NAME
		SELECT 
			i.CONTEST_ID
		,	i.MACHINE_TYPE_ID
		,	NULL
		,	bl.LANGUAGE_ID
		,	i.LCD_NAME
		FROM 
			INSERTED    		i
		,	CONTEST			c
		,	V_BALLOT_LANGUAGE	bl -- cross join
		WHERE 
			c.TYPE 			IN (1 -- straight party
							, 5 -- selective primary
							)
		AND	c.CONTEST_ID 		= i.CONTEST_ID 
		-- Do the same for contest_translation records- delete
-- for special contests
		DELETE 
			CONTEST_TRANSLATION
		FROM 
			DELETED			d
		WHERE 
			CONTEST_TRANSLATION.CONTEST_ID = d.CONTEST_ID
		AND 	CONTEST_TRANSLATION.HEADER_ITEM_ID 
			IN (SELECT 
				hi.HEADER_ITEM_ID
			FROM 
				V_HEADER_ITEM		hi
			,	V_BALLOT_HEADER	bh
			WHERE 
				bh.MACHINE_TYPE_ID 	= d.MACHINE_TYPE_ID
			AND	hi.BALLOT_HEADER_ID = bh.BALLOT_HEADER_ID
			)
		OR 	CONTEST_TRANSLATION.HEADER_ITEM_ID 
			IN (SELECT 
				hi.HEADER_ITEM_ID
			FROM 
				V_HEADER_ITEM		hi
			WHERE 
				hi.IS_ACTIVE = 0
			)
		OR 	CONTEST_TRANSLATION.HEADER_ITEM_ID 
			NOT IN (SELECT 
				hi.HEADER_ITEM_ID
			FROM 
				V_HEADER_ITEM		hi
			)
		-- Delete records from Contest_Header
		DELETE 
			CONTEST_HEADER
		FROM 
			DELETED				d
		WHERE 
			CONTEST_HEADER.CONTEST_ID = d.CONTEST_ID
		AND 	CONTEST_HEADER.HEADER_ITEM_ID 
			in (SELECT 
				hi.HEADER_ITEM_ID
			FROM 
				V_HEADER_ITEM 		hi
			,	V_BALLOT_HEADER 	bh
			WHERE 
				bh.MACHINE_TYPE_ID = d.MACHINE_TYPE_ID 
			AND	hi.BALLOT_HEADER_ID = bh.BALLOT_HEADER_ID
			)
		OR 	CONTEST_HEADER.HEADER_ITEM_ID 
			in (SELECT 
				hi.HEADER_ITEM_ID
			FROM 
				V_HEADER_ITEM		hi
			WHERE 
				hi.IS_ACTIVE 		= 0 
			)
		OR 	CONTEST_HEADER.HEADER_ITEM_ID 
			NOT IN (SELECT 
				hi.HEADER_ITEM_ID
			FROM 
				V_HEADER_ITEM		hi
			)
		-- recreate data in Contest_Header table
		INSERT INTO CONTEST_HEADER
			CONTEST_ID
		,	HEADER_ITEM_ID
		,	HEADER
		) 
		SELECT DISTINCT 
			i.CONTEST_ID,
			hi.HEBDER_ITEM_ID,
			CASE hi.HEADER
				WHEN '{1}' THEN isnull(c.NAME, '') -- Contest Name 
		          WHEN '{2}' THEN (SELECT 
								isnull(NAME, '') -- Party Name 
		                          FROM 
								v_PARTY		p 
		                          WHERE 
								c.PARTY_ID 	*= p.PARTY_ID)
		          WHEN '{3}' THEN (SELECT 
								isnull(BALLOT_NAME, '') --office Name
		                           FROM 
								v_OFFICE_DISPLAY 	od
		                           WHERE 
								od.OFFICE_ID 		=* b.OFFICE_ID
							  AND i.MACHINE_TYPE_ID 
									*= od.MACHINE_TYPE_ID)
		          WHEN '{4}' THEN (SELECT 
								isnull(NAME, '') -- Precinct Name
		                           FROM 
								v_PRECINCT 	p
		                           WHERE 
								c.PRECINCT_ID *= p.PRECINCT_ID)
		          WHEN '{5}' THEN (SELECT 
								isnull(NAME,'') --PSD name
		                           FROM 
								v_PSD 		p
		                           WHERE 
								c.PSD_ID 		= p.PSD_ID)
		          WHEN &{6}' THEN isnull(VOTE_FOR_HEADER, '') --Vote4Header
		       	WHEN '{15}' THEN '' -- free text
			  	WHEN '{20}' THEN '&&Separator'  -- seperate line
			  	WHEN '{25}' THEN '&&Proposal' -- proposal text
		          ELSE ''
			END
		FROM 
			INSERTED			i
		, 	v_HEADER_ITEM 		hi
		,	CONTEST 			c
		WHERE 
			i.BALLOT_HEADER_ID 	= hi.BALLOT_HEADER_ID
		AND 	i.CONTEST_ID 		= c.CONTEST_ID
		AND 	hi.IS_ACTIVE 		= 1
		-- propagate changes to Layout_Contest
		UPDATE 
			LAYOUT_CONTEST
		SET 
			BRROW_X			= bh.ARROW_X
		, 	ARROW_Y 			= bh.ARROW_Y
		FROM 
			V_BALLOT_HEADER 	bh
		, 	INSERTED			i
		WHERE 
			i.BALLOT_HEADER_ID	= bh.BALLOT_HEADER_ID
		AND 	i.CONTEST_ID 		= LAYOUT_CONTEST.CONTEST_ID
		AND 	LAYOUT_CONTEST.X 	> 0
	END
	-- raise error if error thrown	
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
END -- TRIGGER TUI_Contest_Display
CREATE TRIGGER TI_CONTEST_DISPLAY_TRANSLATION 
ON CONTEST_DISPLAY_TRANSLATION FOR INSERT 
/******************************************************************************
TRIGGER		: TI_CONTEST_DISPLAY_TRANSLATION
Description 	: This trigger handles  all inserts on the 
			Contest_Display_Translation table. Constraint checks on 
				Audio_ID audio table
			,	Contest_ID And Machine_Type_ID Contest table
			,	Header_Symbol_ID (Symbol_ID) in 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/5/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
						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 CONTEST_DISPLAY must exist when inserting a child in 
	-- CONTEST_DISPLAY_TRANSLATION
	IF UPDATE(CONTEST_ID) OR UPDATE(MACHINE_TYPE_ID)
	BEGIN
		-- if count of matching parent ids unequal to changed IDs error
		IF  (SELECT Count(*)
			FROM
				CONTEST_DISPLAY t1, inserted t2
			WHERE  
				t1.CONTEST_ID = t2.CONTEST_ID
			AND	t1.MACHINE_TYPE_ID = t2.MACHINE_TYPE_ID) <> @numrows
		BEGIN
			SELECT 
				@errno 	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not exist in CONTEST_DISPLAY. '
						+ 'Cannot create child in '
						+ 'CONTEST_DISPLAY_TRANSLATION.'
		END
	END
	-- Parent AUDIO must exist when inserting a child in 
	-- CONTEST_DISPLAY_TRANSLATION
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- Get count of NULL Audio_ID records- if > 0 cheak for parents
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  AUDIO_ID IS NULL
						
		IF @numnull <> @numrows
		BEGIN
			-- compare count of valid parent Ids to changed ids if 
			-- unequal error
			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 '
							+ 'CMNTEST_DISPLAY_TRANSLATION.'
			END
		END
	END
	-- Parent SYMBOL must exist when inserting a child in
	-- CONTEST_DISPLAY_TRANSLATION  */
	IF UPDATE(HEADER_SYMBOL_ID)
	BEGIN
		-- Get count of NULL Header_Symbol_ID records- if > 0 check 
		-- for parents
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  HEADER_SYMBOL_ID IS NULL
						
		IF @numnull <> @numrows
		BEGIN
			-- compare count of valid parent Ids to changed ids if 
			-- unequal error
			IF  (SELECT count(*)
				FROM SYMBOL t1
				,	inserted t2
				WHERE t1.SYMBOL_ID	= t2.HEADER_SYMBOL_ID
				) 				<> @numrows - @numnull
			BEGIN
				SELECT 
					@errno  	= 50002	-- user defined error number
				,	@errmsg 	= 'Parent does not exist in SYMBOL. '
							+ 'Cannot create child in '
							+ 'CONTEST_DISPLAY_TRANSLATION.'
			END
		END
	END
	-- if error thrown, raiserror and rollback transaction
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
CREATE PROCEDURE dbo.dt_displayoaerror_u
    @iObject int,
    @iresult int
	-- This procedure should no longer be called;  dt_displayoaerror should be called instead.
	-- Calls are forwarded to dt_displayoaerror to maintain backward compatibility.
	set nocount on
	exec dbo.dt_displayoaerror
		@iObject,
		@iresult
tion table.  
			Contains original code from ToolSmith.
Parameters: 	@a_contest_id 	-- contest_id for contest to rotate 
			@state		--!state that the contest is in
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/27/03		PPaiva		Initial creation.
8/18/05		MMcKinney		Modified script to meet code review standards
9/12/05		NFeldman		Added comments to temp table fields
11/09/05		ECoomer		Modified Check for state for standard rotatimn
						changed check for 'OH' and 'XX' to <> 'CA' as
						all states that use rotation use standard 
						rotation except CA
******************************************************************************/
BEGIN
	-- if @state is not null then the rotation is generated based on
	-- state specific algoritm
	DECLARE @contest_id	numeric(7)	-- current contest id
	,	@old_id 		numeric(7)	-- previous contest id
	,	@precinct_id 	numeric(7)	-- current precinct id
	,	@cnt 		numeric(7)	-- counter
	--Initialize variables
	SELECT @contest_id	= 0
	,	@old_id 		= 0
	,	@precinct_id 	= 0
	,	@cnt 		= 0
	-- prepare rotation table with initial precinct data
	DECLARE @rotation TABLE 
		PRECINCT_ID 	numeric(7)	-- identifier of precinct
	,	CONTEST_ID 	numeric(7)	-- identifier of contest
	,	LIST_ORDER 	numeric(7)	-- order in list
	,	PRIMARY KEY 	(
						PRECINCT_ID
					, 	CONTEST_ID
					)			-- creates primary key
	-- flush rotation table in order to start fresh
	DELETE dbo.ROTATION
	WHERE Aa_contest_id is null 
		OR CONTEST_ID = @a_contest_id
	-- allow user to select standard rotation by default 
	-- if the state is not recognized specifically
	IF @state IS NULL
		SELECT @state = state
		FROM dbo.v_customer
	-- initialize the rotation table
	-- create a list all contests and precincts that vote in each contest
	INSERT INTO @rotation
		CONTEST_ID
	, 	PRECINCT_ID
	, 	LIST_ORDER
	SELECT contest_id
	, 	p.precinct_id
	, 	p.list_order
	FROM dbo.contest AS c
		JOIN dao.precinct_assignment AS pa
			ON pa.psd_id = c.psd_id
		JOIN dbo.v_precinct AS p
			ON p.precinct_id = pa.precinct_id
	WHERE c.precinct_id IS NULL
	IF @state <> 'CA' 
	-- for all states other than CA that use standard automatic rotation, 
	-- contests rotate through all candidates (except writein).
	-- The rotation is precinct based: each precinct [that votes in the
	-- contest] gets a different rotation
	BEGIN
	    	-- use an explicit cursor to enumarate the precincts for each
		-- contest!from 1 to n
		DECLARE cr_order INSENSITIVE CURSOR FOR		
			SELECT contest_id
			, 	precinct_id 
			FROM @rotation
			ORDER BY contest_id
			, 	list_order
		-- open cursor
		OPEN cr_order
		-- fetch first row into cursor
		FETCH cr_order INTO 
			@contest_id
		, 	@precinct_id
		--while a row is returned from a cursor continue processing
		WHILE (@@fetch_status=0)
		BEGIN
			IF @old_id = @contest_id
				SELECT @cnt = @cnt + 1
			ELSE
				SELECT @cnt = 0
				
			-- update @rotation uith new list order
			UPDATE @rotation
			SET list_order = @cnt
			WHERE contest_id = @contest_id
			AND precinct_id= @precinct_id
			SELECT @old_id = @contest_id
			-- get next row from cursor
			FETCH cr_order INTO 
				@contest_id
			, 	@precinct_id
		END	-- end cursor
		--close cursor and free memory
		DEALLOCATE cr_order
		-- create rotation rows, where rotation ordered by precinct
		-- and bound by the nu
							    -- non-partisan in primary election
	, 	@party0 			int -- 0 or null, used to default select the 
						    -- party_id for ballot styles  
	,	@max_ballot_style 	int -- last known ballot style
	--Initialize variables
	SELECT 
	  	@is_consolidated  	= 0
	, 	@closed_primary 	= 0
	, 	@generate_non 		= 0
	, 	@party0 			= 0
	,	@max_ballot_style 	= 0
	-- print informational message to screen if @verbose is 1
	IF @Verbose = 1
		PRINT 'running bart_sp_distinct_styles'
	-- Step 1: delete existing layouts
	DELETE LAYOUT
	-- Step 2: delete existing ballot styles
	DELETE BALLOT_STYLE
	/* Step 3: Remove defunct location and precincts.  These will change
	 	the result set if allowed to exist. delete location type for 
		removed locations and unassigned precincts.
	DELETE FROM 
		LOCATION_TYPE
	WHERE NOT EXISTS 
		(SELECT 
			1 
		FROM 
			v_location_type!lt
		WHERE 
			lt.location_id 		= LOCATION_TYPE.LOCATION_ID
		AND 	lt.tally_category_id	= LOCATION_TYPE.TALLY_CATEGORY_ID
	-- delete precinct locations for deleted precincts.
	-- location type has a delete trigger on precinct-location
	DELETE FROM 
		PRECINCT_LOCATION
	WHERE NOT EXISTS 
		(SELECT 
			1
		FROM 
			v_PRECINCT_LOCATION AS pl
		WHERE 
			pl.PRECINCT_ID 		= PRECINCT_LOCATION.PRECINCT_ID
		AND 	pl.tally_category_id 	= PRECINCT_LOCATION.TALLY_CATEGORY_ID
		AND 	pl.LOCATION]ID 		= PRECINCT_LOCATION.LOCATION_ID
	-- Step 4: declare the main temp table
	-- tb_style is used to collect precinct/psd assignment and
	--   generate potential style IDs
	CREATE TABLE #tb_style
		STYLE_ID 		INTEGER IDENTITY -- identifier of style
	,	PRECINCT_ID	NUMERIC(7) null -- identifier of precinct
	,	SPLIT_ID 		numeric(7) null -- identifier of split
	,	PARTY_ID 		numeric(3) null -- identifier of political party
	,	PRIMARY KEY CLUSTERED (STYLE_ID) -- creates primary key on Style_ID
	-- tb_duplicate copies the styles from tb_style and calculates a key
	-- for each row according to contest assignments
	CREATE TABLE #tb_duplicate
		STYLE_ID 		INTEGER-- identifier of style	
	,	PRECINCT_ID 	NUMERIC(7) -- identifier of precinct
	,	PARTY_ID 		numeric(3) -- indentifier of political party
	,	SPLIT_ID 		numeric(7) null -- identifier of split
	,	DUPLICATE_ID 	INTEGER  null -- original style identifier
	,	DUPLICATE_VAR 	float  null -- holds population variance of contest_id
							 -- for the duplicated record
	,	DUPLICATE_SUM 	bigint NULL -- duplicates the original sum
	,	PRIMARY KEY CLUSTERED (STYLE_ID) -- creates primary key 
	-- tb_contest is used to store contest assignment for each style
	CREATE TABLE #tb_contest
		STYLE_ID 	 INTEGER	-- identifier of style
	,	CONTEST_ID NUMERIC(7) -- identifier of contest
	,	PSD_ID 	 NUMERIC(7) -- identifier of political subdivision
	,	PARTY_ID 	 NUMERIC(3) NULL -- identfieir of political party
	,	LIST_ORDER NUMERIA(7) NULL -- order in list
	,	PRIMARY KEY CLUSTERED (STYLE_ID, CONTEST_ID)	-- creates primary key
	-- tb_distinct is used to store only distinct styles
	CREATE TABLE #tb_distinct
		VAR_VALUE 	float		-- holds original value of key
	,	SUM_VALUE 	bigint		-- holds sum of value
	,	STYLE_ID 		numeric(7)	-- identifier of style
	,	PRIMARY KEY CLUSTERED (VAR_VALUE, SUM_VALUE) -- create primary key
	-- tb_assignment stored PSD/PRECINCT assignment from the current
	-- assingment set
	CREATE!TABLE #tb_assignment
		PRECINCT_ID 	NUMERIC(7) NOT NULL --identfier of precinct
	,	PSD_ID 		numeric(7) NOT NULL --identifier of political 
									-- subdivision
	,	PRIMARY KEY CLUSTERED(PRECINCT_ID, PSD_ID) -- creates primary key
	-- Steps 4-8
	EXEC up_DistinctStyleSub1	@Closed_Primary	OUTPUT
						,	@Generate_Non		OUTPUT
						,	@Party0			OUTPUT
						,	@Is_Consolidated	OUTPUT
	-- Steps 9-17
	EXEC up_DistinctStyleSub2 @Closed_Primary, @Party0
	-- step 18: generate and assign!special contests
EC dbo.bart_sp_special_contests -- execute bart_sp_special_contests 
							-- to generate special contests
	-- step 19-28
	EXEC up_DistinctStyleSub3	@name
						, 	@Max_Ballot_Style 	OUTPUT
	-- execute bart_sp_ballotcontest_order to reorder contests to 
	-- assure no gaps
	Exec bart_sp_ballotcontest_order 
	-- reorder all contests if there is a special contest type = 1
	IF EXISTS (SELECT
			1
		FROM
			Contest
		WHERE
			Type	= 1
	BEGIN
		EXEC up_Contest_Reorder
	END
	-- step 29: generate layouts
	-- generate dts layouts
	EXEC dbo.bart_sp_dts_styles @verbose, @name, @Closed_Primary
	EXEC dbo.bart_sp_generate_layout -- Generate layout for all tally types
END	-- Procedure bart_sp_distinct_styles
chec
ck t
on i
o > 8
IN -
AISE`
rno F
CREATE PROCEDURE dbo.bart_rotate1
	@a_contest_id int = Null -- contest_id for contest to rotate 
,	 @state char(2) = Null	-- state that the contest is in
/******************************************************************************
Procedure: 	bart_rotate1
Description: 	First of two procedures that populatet the rotation table.  
			Contains original code from ToolSmith.
Parameters: 	@a_contest_id 	-- contest_id for contest to rotate 
			@state		-- state that the contest is in
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/27/03		PPaiva		Initial creation.
8/18/05		MMcKinney		Modified script to meet code review standards
9/12/05		NFeldman		Added comments tm temp table fields
11/09/05		ECoomer		Modified Check for state for standard rotation
						changed check for 'OH' and 'XX' to <> 'CA' as
						all states that use rotation use standard 
						rotation except CA
******************************************************************************/
BEGIN
	-- if @state is not null then the rotation is generated based on
	-- state specific algoritm
	DECLARE @contest_id	numeric(7)	-- current contest id
	,	@old_id 		numeric(7)	-- previous contest id
	,	@precinct_id 	numeric(7)	-- current precinct id
	,	@cnt 		numeric(7)	-- counter
	--Initialize variables
	SELECT @contest_id	= 0
	,	@old_id 		= 0
	,	@precinct_id 	= 0
	,	@cnt 		= 0
	-- prepare rotation table with initial precinct data
	DECLARE @rotation TABLE 
		PRECINCT_ID 	numeric(7)	-- identifier of precinct
	,	CONTEST_ID 	numeric(7)	-- identifier of contest
	,	LIST_ORDER 	numeric(7)	-- order in list
	,	PRIMARY KEY 	(
						PRECINCT_ID
					, 	CONTEST_ID
					)			-- creates primary key
	-- flush rotation table in order to start fresh
	DELETE dbo.ROTATION
	WHERE @a_contest_id is null 
		OR CONTEST_ID = @a_contest_id
	-- allow user to select standard rotation by default 
	-- if the state is not recognized specifically
	IF @state IS NULL
		SELECT @state = state
		FROM dbo.v_customer
	-- initialize the rotation table
	-- create a list all contests and precincts that vote in each contest
	INSERT INTO @rotation
		CONTEST_ID
	, 	PRECINCT_ID
	, 	LIST_ORDER
	SELEAT contest_id
	, 	p.precinct_id
	, 	p.list_order
	FROM dbo.contest AS c
		JOIN dbo.precinct_assignment AS pa
			ON pa.psd_id = c.psd_id
		JOIN dbo.v_precinct AS p
			ON p.precinct_id = pa.precinct_id
	WHERE c.precinct_id IS NULL
	IF @state <> 'CA' 
	-- for all states other than CA that use standard automatic rotation, 
	-- contests rotate through all candidates (except writein).
	-- The rotation is precinct based: each precinct [that votes in the
	-- contest] gets a different rotation
	BEGIM
	    	-- use an explicit cursor to enumarate the precincts for each
		-- contest from 1 to n
		DECLARE cr_order INSENSITIVE CURSOR FOR		
			SELECT contest_id
			, 	precinct_id 
			FROM @rotation
			ORDER BY contest_id
			, 	list_order
		-- open cursor
		OPEN cr_order
		-- fetch first row into cursor
		FETCH cr_order INTO 
			@contest_id
		, 	@precinct_id
		--while a row is returned from a cursor continue processing
		WHILE (@@fetch_status=0)
		BEGIN
			IF @old_id = @contest_id
				SELECT @cnt = @cnt + 1
			ELSE
				SELECT @cnt = 0
				
			-- update @rotation with new list order
			UPDATE @rotation
			SET list_order = @cnt
			WHERE contest_id = @contest_id
			AND precinct_id= @precinct_id
			SELECT @old_id = @contest_id
			-- get next row from cursor
			FETCH cr_order INTO 
				@contest_id
			, 	@precinct_id
		END	-- end cursor
		--close cursor and free memory
		DEALLOCATE cr_order
		-- create rotation rows, where rotation ordered by precinct
		-- and bound by the nu
mber of candidates in each contest
		INSERT INTO dbo.ROTATION
			CONTEST_ID
		,	PRECINCT_ID
		,	ROTATION_ORDER
		SELECT c.contest_id
		,	r.precinct_id
		,	Convert(numeric(7)
		,	Convert(integer, r.list_order) % Count(cd.list_order)+1)
		FROM dbo.contest 			c
			JOIN dbo.v_office 		o 
				ON c.office_id 	= o.office_id
			JOIN @rotation 		r 
				ON c.contest_id	= r.contest_id
			JOIN dbo.candidate		cd
				ON c.contest_id 	= cd.contest_id
		WHERE 
			o.is_rotated = 1
		AND 	(@a_contest_id IS NULL 
			OR c.contest_id = @a_contest_id
			)
		AND 	cd.type IN (0,2,7)		-- 0: standard, 
								-- 2:unaffected by straight party 
								-- 7:proportional
		GROUP BY c.vote_for 
		,	c.contest_id 
		,	r.precinct_id 
		,	r.list_order 
		,	c.psd_id
		HAVING
			-- When state OH, count list order must be greater than vote_for
			-- for all other states, count of list order doesn't matter > -1
			count(cd.list_order)	> CASE @State
									WHEN 'OH' THEN c.vote_for
									ELSE -1 -- all values
								END
	END
	ELSE
	BEGIN
		-- in California the rotation algorithm is as follows:
		-- for statewide offices -- rotate for assembly district
		-- for countywide offices --
		--	if there are 5 or more Assembly Districts then rotate for
		--		each assebmly district
		--	otherwise rotated for each supervisorial district
		DECLARE @assembly_id numeric(7) -- assembly id
								-- rotation assignment = state
		,	@supervisorial_id numeria(7) -- supervisorial_id
								-- rotation assignment = county
		,	@assembly_count int	-- count of assemblies
		-- initialize variables
		SELECT @assembly_id = 0
		,	@supervisorial_id = 0
		,	@assembly_count = 0
		-- get the assembly district category ID
		SELECT @assembly_id 	= pc.PSD_CATEGORY_ID
		,	 @assembly_count 	= Count(*)
		FROM dbo.v_PSD_CATEGORY AS pc
			JOIN dbo.v_psd AS psd 
				ON psd.PSD_CATEGORY_ID = pc.PSD_CATEGORY_ID
		WHERE pc.ROTATION_ASSIGNMENT = 1 -- state
		GROUP BY pc.PSD_CATEGORY_ID
		SELECT @supervisorial_id = PSD_CATEGORY_ID
		FROM dbo.v_PSD_CATEGORY
		WHERE ROTATION_ASSIGNMENT = 2 -- county
		-- use a 1 based for manual rotation for all contests that are
		-- marked as rotated but did not rotate
		-- or when rotation is not defined
		INSERT INTO dbo.ROTATION
			CONTEST_ID
		,	PRECINCT_ID
		,	ROTATION_ORDER
		SELECT c.contest_id
		,	pa.precinct_id
		,	1
		FROM dbo.contest AS c
			JOIN dbo.v_office AS office 
				ON c.office_id = ofeice.office_id
			JOIN dbo.precinct_assignment AS pa
				ON c.psd_id = pa.psd_id
		WHERE c.precinct_id IS NULL -- no rotation for precinct
								-- level contests
		AND office.is_rotated = 1
		AND (@a_contest_id IS NULL 
			OR c.contest_id = @a_contest_id)
		AND NOT EXISTS (SELECT 1
					FROM dbo.ROTATION
					WHERE CONTEST_ID = c.CONTEST_ID
					AND PRECINCT_ID = pa.PRECINCT_ID)
	END
END	--procedure bart_rotate1
CREATE TRIGGER TI_CONTEST_HEADER 
ON CONTEST_HEADER FOR INSERT 
/******************************************************************************
TRIGGER		: TI_CONTEST_HEADER
Description 	: This trigger handles  all inserts on the 
			Contest_Header table. Constraint checks on 
				Audio_ID audio table
			,	Contest_ID And Machine_Type_ID Contest table
			,	Header_Symbol_ID (Symbol_ID) in Symbol table
			Also propagates updates to Contest_Header to 
			Contest_Translation and Proposal_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/6/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Mofified line lengths- all to meet
						code review comments. 
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 NVLL 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 CONTEST must exist when inserting a child in CONTEST_HEADER
	IF UPDATE(CONTEST_ID)
	BEGIN
		IF	(SELECT Count(*)
			FROM   CONTEST t1, inserted t2
			WHERE  t1.CONTEST_ID = t2.CONTEST_ID) <> @numrows
		BEGIN
			SELECT 
				@errnn  	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not exist in CONTEST. Cannot '
						+ 'create child in CONTEST_HEADER.'
		END
	END
	-- Parent SYMBOL must exist when inserting a child in CONTEST_HEADER
	-- only process if no errors
	IF (UPDATE(SYMBOL_ID) AND @errno = 0)
	BEGIN
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  SYMBOL_ID is null
						
		IF @numnull <> @numrows
		BEGIN
			IF 	(SELECT Count(*)
				FROM   SYMBOL t1, inserted t2
				WHERE  
					t2.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 CONTEST_HEADER.'
			END
		END
	END
	-- propagate data to Contest_Translation table
	INSERT INTO CONTEST_TRANSLATION
		CONTEST_ID
	,	HEADER_ITEM_ID
	,	LANGUAGE_ID
	,	HEADER
	SELECT 
		i.CONTEST_ID
	,	i.HEADER_ITEM_ID
	,	bl.LANGUAGE_ID
	,	CASE hi.HEADER
			WHEN '{1~' THEN ot.NAME -- office name
			WHEN '{2}' THEN IsNull(pt.NAME, '') -- party name
			WHEN '{3}' THEN IsNull(ot.NAME, '') -- contest name
			WHEN '{6}' THEN IsNull(ot.VOTE_FOR_HEADER, '') --vote 4 header
			WHEN '{7}'  THEN IsNull(i.header, '') -- symbol
			WHEN '{20}'  THEN IsNull(i.header, '') -- marker
			ELSE IsNull((SELECT DISTINCT 
					DT.TERM_TRANSLATION 
				FROM 
					INSERTED				i
				,	V_HEADER_ITEM 			hi2
				,	V_DICTIONARY 			D
				,	V_DICTIONARY_TRANSLATION DT
				WHERE 
					DV.LANGUAGE_ID 		= bl.LANGUAGE_ID
				AND	i.HEADER_ITEM_ID 		= hi2.HEADER_ITEM_ID 
				AND 	Upper(isnull(i.HEADER,''))= UPPER(D.DICTIONARY_TERM)
				AND	D.DICTIONARY_ID 		= DT.DICTIONARY_ID 
				), i.HEADER)
		END
	FROM 
		INSERTED				i
	,	V_BALLOT_LANGUAGE		bl -- cross join
	,	CONTEST				c
	,	V_HEADER_ITEM			hi
	,	V_PARTY_TRANSLATION 	pt
	,	V_OFFICE_TRANSLATION 	ot
	WHERE
		i.CONTEST_ID 			= c.CONTEST_ID
	AND	i.HEADER_ITEM_ID 		= hi.HEADER_ITEM_ID
	AND	c.PARTY_ID 			*= pt.PARTY_ID
	AND 	bl.NANGUAGE_ID 		*= pt.LAl|
dc?z?
@(<y
y districts
	SELECT @rot_CNT = COUNT(vpsd.psd_id)
	FROM dbo.v_psd AS vpsd
		JOIN dbo.v_psd_category AS vpsdc 
			ON vpsd.PSD_CATEGORY_ID = vpsdc.PSD_CATEGORY_ID
	WHERE vpsdc.rotation_assignment = 1
	-- Statewide Offices
	INSERT INTO @t_ca_rot_param 
		precinct_id 
	,	contest_id
	,	psd_id
	,	psd_rot_number
	,	cand_number
	,	rot_number
	SELECT rot.precinct_id
	,	rot.contest_id
	,	vpsdc.psd_id
	,	vp.district_rotation
	,	Count(c.candidate_id) as cand_number
	,	CAST((vp.district_rotation 
			+ Count(c.candidate_id))AS INT) %
				 CAST(Count(c.candidate_id)AS INT ) AS rot_number
	FROM dbo.rotation AS rot
		JOIN dbo.contest AS cont 
			ON rot.contest_id = cont.contest_ID
		JOIN dbo.candidate AS c 
			ON cont.contest_id = c.contest_id
		JOIN dbo.v_office AS vofc 
			ON cont.office_id = vofc.office_id
		JOIN dbo.v_precinct_assignment AS vpa 
			ON rot.precinct_id = vpa.precinct_id
		JOIN dbo.v_psd AS vpsd
			ON vpa.psd_id = vpsd.psd_id
		JOIN dbo.v_psd_category AS vpsdc 
			ON vpsd.PSD_CATEGORY_ID = vpsdc.PSD_CATEGORY_ID
		JOIN @vp AS vp
			ON vpsd.psd_id = vp.psd_id
	WHERE  vofc.locality = 1	--statewide office
		AND c.is_on_ballot = 1
		AND c.type = 0
		AND vofc.is_rotated = 1
		AND vpsdc.rotation_assignment = 1
	GROUP BY  rot.precinct_id
	,	vpsdc.psd_id,rot.contest_id
	,	vp.district_rotation
	-- Countywide Offices
	IF @rot_CNT > 4 
		--IF @aqsembly_count > 4 then use ASSEMBLY DISTRICT rotation
		-- TABLE FOR > 4 ASSEMBLY DISTRICTS
		--ELSE Use assembly & supervisorial district rotation for < 5
		-- assembly districts
	BEGIN	
		-- The assembly district rotation table for > 4 assembly districts
		INSERT INTO @t_ca_rot_param 
			precinct_id
		,	contest_id
		, 	psd_id
		,	psd_rot_number
		,	cand_number
		,	rot_number
		SELECT rot.precinct_id
		,	rot.contest_id
		,	vpsdc.psd_id
		,	vp.list_order
		,	Count(c.candidate_id) as cand_number
		,    CAST((vp.list_order 
			+ Count(c.candidate_id))AS INT) % 
				CAST(Count(c.candidate_id) AS INT) AS rot_number
		FROM dbo.rotation AS rot
			JOIN dbo.contest AS cont 
				ON rot.contest_id = cont.contest_ID
			JOIN dbo.candidate AS c 
				ON cont.contest_id = c.contest_id
			JOIN dbo.v_office AS vofc 
				ON cont.office_id = vofc.office_id
			JOIN dbo.v_precinct_assignment AS vpa 
				ON rot.precinct_id = vpa.precinct_id
			JOIN dbo.v_psd AS vpsd
				ON vpa.psd_id = vpsd-psd_id
			JOIN dbo.v_psd_category AS vpsdc 
				ON vpsd.PSD_CATEGORY_ID = vpsdc.PSD_CATEGORY_ID
			JOIN @vp AS vp
				ON vpsd.psd_id = vp.psd_id
		WHERE  vofc.locality = 2	--countywide office
			AND c.is_on_ballot = 1
			AND c.type = 0
			AND vofc.is_rotated = 1
			AND vpsdc.rotation_assignment = 1
		GROUP BY  rot.precinct_id
		,	vpsdc.psd_id,rot.contest_id
		,	vp.list_order
	END
	ELSE
	BEGIN
		--Assembly &  supervisorial district rotation for < 5 assembly
		-- districts
		--If there are mess than 5 assembly districts then the county
		-- offices are rotated by supervisorial district.
		--SUPERVISORIAL DISTRICT RORTATION PORTION
		INSERT INTO @t_ca_rot_param 
			precinct_id
		,	contest_id 
		,	psd_id
		,	psd_rot_number 
		,	cand_number
		,	rot_number
		SELECT  rot.precinct_id
		,	rot.contest_id
		,	vpsdc.psd_id
		,	vp.district_rotation
		,	Count(c.candidate_id)as cand_number
		,	CAST((vp.district_rotation 
				+ Count(c.candidate_id))AS INT) %
					 CAST(Count(c-candidate_id)AS INT ) AS rot_number 
		FROM dbo.rotation AS rot
			JOIN dbo.contest AS cont 
				ON rot.contest_id = cont.contest_ID
			JOIN dbo.candidate AS c 
				ON cont.contest_id = c.contest_id
			JOIN dbo.v_office AS vofc 
				ON cont.office_id = vofc.office_id
			JOIN dbo.v_precinct_assignment AS vpa 
				ON rot.precinct_id = vpa.precinct_id
			JOIN dbo.v_psd AS vpsd
				ON vpa.psd_id = vpsd.psd_id
			JOIN dbo.v_psd_category AS vpsdc 
				ON vpsd.PSD_CATEGORY_ID = vpsdc.PSD_CATEGORY_ID
				JOIN @vp AS vp
		ON vpsd.psd_id = vp.psd_id
		WHERE  vofc.locality = 2	--countywide office
			AND c.is_on_ballot = 1
			AND c.type = 0
			AND vofc.is_rotated = 1
			AND vpsdc.rotation_assignment = 2 -- 2nd in rotation
		GROUP BY  rot.precinct_id
		,	vpsdc.psd_id
		,	rot.contest_id
		,	vp.district_rotation
	END
	-- State Offices
	INSERT INTO @t_ca_rot_param 
		precinct_id
	,	contest_id 
	,	psd_id
	,	psd_rot_number
	,	cand_number
	,	rot_number
	SELECT  rot.precinct_id
	,	rot.contest_id
	,	vpsdc.psd_id
	,	vp.district_order
	,	Count(c.candidate_id) as cand_number
	,     CAST((vp.district_order 
			+ Count(c.candidate_id)) AS INT) %
				 CAST(Count(c.candidate_id)AS INT ) AS rot_number
	FROM dbo.rotation AS rot
		JOIN dbo.contest AS cont 
		ON rot.contest_id = cont.contest_ID
		JOIN dbo.candidate AS c 
			ON cont.contest_id = c.contest_id
		JOIN dbo.v_office AS vofc 
			ON cont.office_id = vofc.office_id
		JOIN dbo.v_precinct_assignment AQ vpa 
			ON rot.precinct_id = vpa.precinct_id
		JOIN dbo.v_psd AS vpsd
			ON vpa.psd_id = vpsd.psd_id
		JOIN dbo.v_psd_category AS vpsdc 
			ON vpsd.PSD_CATEGORY_ID = vpsdc.PSD_CATEGORY_ID
		JOIN @vp AS vp
			ON vpsd.psd_id = vp.psd_id
	WHERE  vofc.locality = 3		--state offices
		AND c.is_on_ballot = 1
		AND c.type = 0
		AND vofc.is_rotated = 1
		AND vpsdc.rotation_assignment = 1
	GROUP BY  rot.precinct_id
	, 	vpsdc.psd_id
	,	rot.contest_id
	, 	vp.district_order
	--This update solves prmblem of no remainder (max candidate division)
	-- and of 1 candidate in contest
	UPDATE @t_ca_rot_param
	SET rot_number = cand_number
	WHERE rot_number = 0
	--UPDATE rotation TABLE
	UPDATE dbo.rotation
	SET rotation_order = tcap.rot_number
	FROM rotation 			rot
		JOIN @t_ca_rot_param 	tcap 
			ON  rot.precinct_id = tcap.precinct_id
			AND rot.contest_id = tcap.contest_ID
END -- procedure bart_rotate2	
CREATE TRIGGER TU_CONTEST_HEADER 
ON CONTEST_HEADER FOR UPDATE 
/******************************************************************************
TRIGGER		: TU_CONTEST_HEADER
Description 	: This trigger handles  all updates on the 
			Contest_Header table. Constraint checks on 
				Audio_ID audio table
			,	Contest_ID And Machine_Type_ID Contest table
			,	Header_Symbol_ID (Symbol_ID) in Symbol table
			Also propagates updates to Contest_Header and
			Contest_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/6/05		ECoomer		Added comment blocks, removed unused or redundant
						variables.  Modified line lengths- all vo meet
						code review comments. 
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
	,	Berrno    		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 CONTEST must exist when updating a child in CONTEST_HEADER
	IF UPDATE(CONTEST_ID)
	BEGIN
		-- if non-matching parent IDs throw error
		IF 	(SELECT count(*)
			FROM   CONTEST t1, inserted t2
			WHERE  t1.CONTEST_ID = t2.CONTEST_ID) <> @numrows
		BEGIN
	SELECT 
				@errno  	= 50003	-- user defined error number
			,	@errmsg 	= 'CONTEST does not exist. Cannot modify '
						+ 'child in CONTEST_HEADER.'
		END
	END
	-- Parent SYMBOL must exist when updating a child in CONTEST_HEADER
	IF (UPDATE(SYMBOL_ID) AND @errno = 0)
	BEGIN
		-- check for non-null Symbol_Ids, if so, check for parent ids
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  SYMBOL_ID IS NULL
						
		IF @numnull <> @numrows
		BEGIN
			-- if non-matching parent ids, throw error
			IF	(SELECT Count(*)
				FROM   SYMBOL t1, inserted t2
				WHERE  t1.SYMBOL_ID = t2.SYMBOL_ID) <> @numrows - @numnull
			BEGIN
				SELECT @errno	= 50003	-- user defined error number
				,	@errmsg 	= 'SYMBOL does not exist. Cannot modify '
							+ 'child in CONTEST_HEADER.'
			END
		END
	END
	-- check for no errors and whether symbol_ID is updated
	IF (UPDATE (SYMBOL_ID) AND @errno = 0)
	BEGIN
		-- Set header value for symbol header item
		UPDATE 
			contest_header 
		SET 
	contest_header.header	= '&' 
							 	+ CONVERT(VARCHAR, i.SYMBOL_ID) 
								+ '.bmp' --* symbol file
		FROM 
			v_header_item			hi
		,	inserted				i
		WHERE 
			contest_header.contest_id 	= i.contest_id 
		AND 	contest_header.header_item_id	= i.header_item_id 
		AND 	hi.header 		= '{7}' -- symbol
		AND	i.header_item_id 			= hi.header_item_id
		-- Set header value for symbol header item in contest translation 
		UPDATE 
			contest_translation 
		SET 
			contest_translation.header 	= '&' 
								+ CONVERT(VARCHAR, i.SYMBOL_ID) 
								+ '.bmp'    -- symbol file
		FROM 
			v_header_item			hi
		,	inserted				i
		WHERE 
			contest_translation.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 proc dbo.dt_checkoutobject_u
    @chObjectType  char(4),
    @vchObjectName nvarchar(255),
    @vchComment    nvarchar(255),
    @vchLoginName  nvarchar(255),
    @vchPassword   nvarchar(255),
    @iVCSFlags     int = 0,
    @iActionFlag   int = 0/* 0 => Checkout, 1 => GetLatest, 2 => UndoCheckOut */
	-- This procedure should no longer be called;  dt_checkoutobject should be called instead.
	-- Calls are forwarded to dt_checkoutobject to maintain"backward compatibility.
	set nocount on
	exec dbo.dt_checkoutobject
		@chObjectType,  
		@vchObjectName, 
		@vchComment,    
		@vchLoginName,  
		@vchPassword,  
		@iVCSFlags,    
		@iActionFlag 
fications:
Date        	Author		Comments
12/21/99		ToolSmith		Initial creation.
8/19/05		MMcKinney		Modified script to meet code review standards
9/12/2005		NFeldman		Added script comments to temp table field names
******************************************************************************/
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
	,	@key_name 	varchar(40) --u sed in cursor - holds column name in
							  -- joined table from syscolumns
	,	@key_table 	varchar(40) -- used in cursor - holds table name
	,	@name_col 	varchar(40) -- used in cursor - holds column name
	--Initialize Variabled
	SELECT 
		@table_name 	= ''
	,	@column_name 	= ''
	,	@cmd 		= ''
	,	@key_name 	= ''
	,	@key_table 	= ''
	,	@name_col 	= ''
	declare @ref_table TABLE 
		SYMBOL_TABLE 	varchar(40) -- name of symbol table
	,	KEY_TABLE 	varchar(40) -- name of source table
	,	NAME 		varchar(50) -- name of table in sysobjects
	,	ID 			numeric(7)  -- identifier of table in sysobjects
	-- declare cursor
	declare cr_ref cursor for
		select 
			sysobjects.name
		,	syscolumns.nane
		,	pkey.name 
		,	case pkey.name
				when 'contest_id' 		then 'CONTEST'
				when 'candidate_id' 	then 'CANDIDATE'
				when 'field_id' 		then 'FIELD'
				when 'selection_code'	then 'LAYOUT_SELECTION'
				when 'proposal_id' 		then 'PROPOSAL'
				when 'layout_id' 		then 'LAYOUT'
				else ''	
			end key_table	
		,	case pkey.name
				when 'candidate_id' 	then 'REPORT_NAME'
				when 'field_id' 		then 'SOURCE_TABLE'
				when 'selection_code' 	then 'SELECTION_NAME'
				else 'NAME'
			end name_con	
		from 
			syscolumns
		join
			sysobjects 
			on sysobjects.id = syscolumns.id
		left join syscolumns 	pkey 
			on syscolumns.id = pkey.id
		and	lower(pkey.name) in (	
								'candidate_id'
							, 	'contest_id'
							,	'proposal_id'
							, 	'selection_code'
							,	'field_id'
							,	'layout_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 record into curs
	fetch cr_ref 
	into @table_name
	,	@column_name
	,	@key_name
	,	@key_table
	,	@name_col
	--while a row is returned from a cursor continue processing
	while @@fetch_status = 0 
	begin
		-- dynamically create view counting references to current table
		-- first, drop the view if it exists
		select 
			@cmd = 'if exists (select 1 from sysobjects where id '
				+ '= object_id(''V_REF_TABLE'')) drop view V_REF_TABLE'
		exec (@cmd)
		--Now recreate the view
	select 
			@cmd = 'create view V_REF_TABLE as ' + char(13)
		select
			@cmd = @cmd + 'select ''' + @table_name 
				+ ''' TABLE_NAME, ''' + @key_table + ''' KEYTABLE, ' 
				+ 'source.' + @name_col + ', ' + 'source.' + @key_name 
				+ char(13) + ' from ' + @table_name + ' dest' 
				+ char(13) + ' join ' + @key_table + ' source on source.'
				+ @key_name + ' = dest.' + @key_name + char(13) 
				+ ' where dest.' + @column_name + ' = ' 
			+ cast(@a_symbol_id as varchar)
		exec(@cmd)
		--save off the data that is in the view
		insert into 
			@ref_table
		select 
			*
		from 
			V_REF_TABLE
		-- get next row from curs
		fetch cr_ref 
		into @table_name 
		,	@column_name
		,	@key_name
		,	@key_table
		,	@name_col
	End	-- end of cursor
	-- close cursor and free memory
	deallocate cr_ref
	--select the rowset to return to the calling ap.
	select 
	from 
		@ref_table
	-- drop the view that was created earlier if one exists 
	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_usage
ABLE            TABLE       VIEW       4
SYMBOL_ID
?|4r
CREATE TRIGGER TU_CONTEST_TRANSLATION 
ON CONTEST_TRANSLATION FOR UPDATE 
/******************************************************************************
TRIGGER		: TU_CONTEST_TRANSLATION 
Description 	: This trigger handles  all updates 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 updating 
	-- a child in CONTEST_TRANSLATION
	IF UPDATE(CONTEST_ID) OR UPDATE(HEADER_ITEM_ID)
	BEGIN
		-- if non-matching parent ids, 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
			SELECT 
				@errnn  	= 50003	-- user defined error number
			,	@errmsg 	= ' CONTEST_HEADER does not exist. Cannot '
						+ 'modify child in CONTEST_TRANSLATION.'
		END
	END
	-- Parent AUDIO must exist when updating a child in CONTEST_TRANSLATION  */
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- get non-null audio ids
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  AUDIO_ID IS NULL
		IF @numnull <> @numrows
		BEGIN
			-- if non-matching parent ids, error
			IF 	(SELECT Count(*)
				FROM   BUDIO t1, inserted t2
				WHERE  
					t1.AUDIO_ID	= t2.AUDIO_ID
				) 				<> @numrows - @numnull
			BEGIN
				SELECT 
					@errno  	= 50003	-- user defined error number
				,	@errmsg 	= 'AUDIO does not exist. Cannot modify '
							+ 'child in CONTEST_TRANSLATION.'
			END
		END
	END
	-- if error, rollback transaction
	IF @errno > 0
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
END -- TRIGGER TU_Contest_Translation
F@ =
CREATE TRIGGER TD_LAYOUT 
ON LAYOUT FOR DELETE 
/******************************************************************************
TRIGGER		: TD_LAYOUT
Description 	: This trigger handles  all deletes on the 
			Layout table. Sets Layout_ID = NULL in Machine Assignment
			table when Layout_ID deleted
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
	/*  Set parent code of LAYOUT to NULL in child MACHINE_ASSIGNMENT  */
	UPDATE 
		MACHINF_ASSIGNMENT
	SET   
		LAYOUT_ID 		= NULL
	FROM   
		MACHINE_ASSIGNMENT	ma
	, 	deleted 			d
	WHERE  
		d.LAYOUT_ID 		= ma.LAYOUT_ID
    RETURN
END -- TD_Layout
CREATE PROCEDURE dbo.sp_archive_election
	@ArchiveElection varchar(1)
/******************************************************************************
Procedure:	sp_archive_election
Description:	Archives election data to profile tables, or vice versa
Parameters: 	@ArchiveElection - If = 'T' the rrocedure sp_archive_copy_data
							is called to archive the profile data, if
							not the process is reversed
Return: 		None
External Units:   	sp_archive_copy_data,
				CreateViews
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 stbndards
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 
		@db_name 	varchar(40)	-- The current database name
	,	@profile	varchar(40)	-- The profile database name
							-- from wineds_version
	--Initialize Variables
	SELECT 
		@db_name = ''
	,	@profile	= ''
	--Get the PROFILE database name for this Election
	SELECT 
		@profile = profile 
	FROM 
		wineds_version
	--Check whether we are Archiving or REVERSING the process..
	IF @ArchiveElection = 'T'	-- T: true
	   SELECT 
		@db_name = db_name()
	ELSE
	   SELECT 
		@db_name = @profile
	--Execute the stored procedure to copy the data from the PROFILE
	-- database to  the archived profile tables within the ELECTION
	exec sp_archive_copy_data @profile
	, 	@ArchiveElection
	--Execute the stnred procedure to recreate the views to point only to
	-- the ELECTION/PROFILE tables
	IF @ArchiveElection = 'T'	-- T: true
		exec CreateViews @db_name, 1
		, 	1	-- Refreshes the views from the snapshot
	ELSE
		exec CreateViews @db_name
		, 	1		-- Refreshes the views
END	--drop procedure sp_archive_election
create proc dbo.dt_whocheckedout_u
        @chObjectType  char(4),
        @vchObjectName nvarchar(255),
        @vchLoginName  nvarchar(255),
        @vchPassworf   nvarchar(255)
	-- This procedure should no longer be called;  dt_whocheckedout should be called instead.
	-- Calls are forwarded to dt_whocheckedout to maintain backward compatibility.
	set nocount on
	exec dbo.dt_whocheckedout
		@chObjectType, 
		@vchObjectName,
		@vchLoginName, 
		@vchPassword  
CREATE PROCEDURE dbo.sp_split 
	@master_layout_id	NUMERIC(7)
,	@psd_category_id 	NUMERIC(7) = null
,	@split_type 		NUMERIC(7)
/******************************************************************************
Procedure:	sp_split
Description: 	Deletes existing layout splits and also spits layouts
			by PSD Category of Party	
Parameters: 	@master_layout_id	-- master layout id that will be split
			@psd_category_id	-- V_PSD.PSD_CATEGORY_ID that will
							-- be split when splitting by
							-- PSD Category
			@split_type		-- Determines what is done in this proc
							-- 0 = delete existing splits only
							-- 1 = split  by PSD Category
							-- 2 = split by Party
Return: 		None 
External Units: bart_layoutcontest_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
12/21/99		ToolSmith		Initial creation.
8/25/05		MMcKinney		Modified script to meet code review standards
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
BEGIN
	DECLARE 
		@layout_id	 numeric(7)	-- holds current layout id
	,	@old_layout_id  NUMERIC(7)	-- holds previous layout id
	,	@selection_code NUMERIC(7)	-- holds selection code
	,	@old_code 	 NUMERIC(7)	-- holds old selection code
	,	@max_layout_id  NUMERIC(7)	-- maximum existing layout id
	--Initialize Variables
	SELECT 
		@layout_id		= 	0
	,	@old_layout_id		= 	0
	,	@selection_code 	= 	0
	,	@old_code 		= 	0
	,	@max_layout_id 	= 	0
	-- create temp table #t_layout
	/********************************************************
	LAYOUT_ID            -- identifier of layout
	NEW_LAYOUT_ID        -- new identifier of layout
	TALLY_TYPE_ID       !-- identifier of tally type
	NAME                 -- name of new layout
	REVISION             -- revision number
	MASTER_LAYOUT_ID     -- identifier of master layout
	BALLOT_STYLE_ID      -- identifier of ballot style
	IS_VALID             -- 0: not valid, 1: valid
	CONTEST_COUNT        -- count of contest, defaults to 0
	BALLOT_SIZE_ID  	 -- identifier of ballot size
	*********************************************************/
	CREATE TABLE #t_layout 
		LAYOUT_ID            T_GLOBAL_ID       !  IDENTITY
	,	NEW_LAYOUT_ID        T_GLOBAL_ID          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
	-- get the max layout_ie before removing any rows.
	-- Otherwise a duplicate could occur
	SELECT 
		@max_layout_id = (	SELECT 
							max(layout_id)
						FROM 
							LAYOUT 
						WHERE 
							layout_id < 90000)
					-- real layout_ids are always less than 90000
					-- those above 90000 are temporary numbers
	-- wipe out previous splits
	DELETE 
		LAYOUT
	WHERE 
		MASTER_LAYOUT_ID = @master_layout_id
	-- delete all machines assignments of layouts that are split
	DELETE 
		MACHINE_ASSIGNMENT
	FROM 
		LAYOUT_ASSIGNMENT
	, 	LAYOUT
	WHERE 
		LAYOUT_ASSIGNMENT.ASSIGNMENT_ID = 	MACHINE_ASSIGNMENT.ASSIGNMENT_ID 
	AND 	LAYOUT.TALLY_TYPE_ID 		  = 	MACHINE_ASSIGNMENT.TALLY_TYPE_ID
	AND 	LAYOUT.LAYOUT_ID 			  =  LAYOUT_ASSIGNMENT.LAYOUT_ID 
	AND 	LAYOUT.LAYOUT_ID			  = 	@master_layout_id
	IF @split_type = 1
	BEGIN
		--*******  split by PSD Category
		-- insert into temp table the layout data that will be split
		INSERT INTO 
			#t_LAYOUT
			NAME
		,	TALLY_TYPE_ID
		,	REVISION
		,	MASTER_LAYOUU_ID
		SELECT 
iew<
			V_PSD.NAME
		,	LAYOUT.TALLY_TYPE_ID
		,	CONVERT(varchar(7),V_PSD.PSD_ID)
		,	@master_layout_id
		FROM 
			v_PSD
		, 	LAYOUT
		WHERE 
			LAYOUT.LAYOUT_ID 		= 	@master_layout_id
		AND 	V_PSD.PSD_CATEGORY_ID	= 	@psd_category_id
		AND 	V_PSD.IS_ACTIVE = 1
		ORDER BY 
			V_PSD.LIST_ORDER
		--generate new layout ids
		UPDATE 
			#t_LAYOUT
		SET 
			new_layout_id 			= 	layout_id + @max_layout_id
		-- Insert new layout records
		INSERT INTO 	
			LAYOUT
			LAYOUT_ID
		,	NAME
		,	TALLY_TYPE_ID
		,	REVISION
		,	MASTER_LAYOUT_ID
		SELECT 
			NEW_LAYOUT_ID
		,	NAME
		,	TALLY_TYPE_ID
		,	REVISION
		,	MASTER_LAYOUT_ID
		FROM 
			#t_LAYOUT
		-- Insert new layout split records
		INSERT INTO 
			LAYOUT_SPLIT 
			LAYOUT_ID 
		,	SPLIT_ID 
		,	SPLIT_TYPE
		SELECT 
			LAYOUT.LAYOUT_ID 
		,	CONVERT(NUMERIC(7), LAYOUT.REVISION)
		,	@split_type
		FROM 
			LAYOUT
		WHERE 
			LAYOUT.MASTER_LAYOUT_ID = @master_layout_id
	        
		-- insert new layout_contest records
		-- assign to layout all contests with assigned precincts
		-- that are also assigned to the split
		INSERT INTO 
			LAYOUT_CONTEST 
			LAYOUT_ID 
		,	CONTEST_ID 
		,	X
		,	Y 
		,	ARROW_X
		,	ARROW_Y 
		,	LIST_ORDER
		SELECT 
			LAYOUT_SPLIT.LAYOUT_ID 
	 	,	LAYOUT_CONTEST.CONTEST_ID
		,	LAYOUT_CONTEST.X
		,	LAYOUT_CONTEST.Y
		,	LAYOUT_CONTEST.ARROW_X
		,	LAYOUT_CONTEST.ARROW_Y
		,	LAYOUT_CONTEST.LIST_ORDER
		FROM 
			MAYOUT_SPLIT 
		,	LAYOUT
		,	LAYOUT_CONTEST 
		,	CONTEST  
		WHERE 
			LAYOUT.MASTER_LAYOUT_ID 	= @master_layout_id
		AND 	LAYOUT_CONTEST.LAYOUT_ID = @master_layout_id
		AND 	LAYOUT.LAYOUT_ID 		= LAYOUT_SPLIT.LAYOUT_ID
		AND 	CONTEST.CONTEST_ID 		= LAYOUT_CONTEST.CONTEST_ID
		AND 	EXISTS (	SELECT 
						1 
					FROM 
						PRECINCT_ASSIGNMENT		pa1
					, 	V_PRECINCT_ASSIGNMENT 	pa2
					WHERE 
						pa2.PSD_ID 		= 	LAYOUT_SPLIT.SPLIT_ID
					AND 	pa2.PRECINCT_ID	= 	pa1.PRECINCT_ID 
					AND!	pa1.PSD_ID 		= 	CONTEST.PSD_ID)
	     -- grab precinct assignment from the profile
		--Insert new layout selection records
		INSERT INTO 
			LAYOUT_SELECTION
			LAYOUT_ID 
		,	SELECTION_CODE 
		,	SELECTION_NAME 
		,	PRECINCT_ID
		,	BALLOT_STYLE_ID
		SELECT 
			l.LAYOUT_ID
		,	ls.SELECTION_CODE
		,	ls.SELECTION_NAME 
		,	ls.PRECINCT_ID
		,	ls.BALLOT_STYLE_ID 
		FROM 
			LAYOUT 			l
		,	LAYOUT_SELECTION 	ls
		WHERE 
			ls.LAYOUT_ID 		= 	@master_layout_id
		AND 	l.MASTER_LAYMUT_ID 	= 	ls.LAYOUT_ID
		AND 
			(  
			   ls.PRECINCT_ID IS NULL 
			OR ls.PRECINCT_ID IN (	SELECT 
									PRECINCT_ID
								FROM 
									V_PRECINCT_ASSIGNMENT pa
								,	LAYOUT_SPLIT
								WHERE 
									ls.PRECINCT_ID	= 
										pa.PRECINCT_ID
									AND pa.PSD_ID 	= 
										LAYOUT_SPLIT.SPLIT_ID
									AND LAYOUT_SPLIT.LAYOUT_ID = 
										l.LAYOUT_ID)
			OR    
			    (
				  ls.PRECINCT_ID IN	(SELECT 
									pl.PRECINCT_ID
								FROM 
									PRECINCT_LMCATION 	pl
								,	V_TALLY_TYPE 		tt
								,	V_TALLY_CATEGORY 	tc
								WHERE 
									tt.TALLY_CATEGORY_ID = 
										tc.TALLY_CATEGORY_ID
								AND 	l.TALLY_TYPE_ID = 
									tt.TALLY_TYPE_ID 
								AND 	pl.TALLY_CATEGORY_ID = 
									tc.TALLY_CATEGORY_ID)
								AND ls.PRECINCT_ID NOT IN 
									(SELECT 
										PRECINCT_ID
									FROM 
										V_PRECINCT_ASSIGNMENT vpa
									,	V_PSD
									WHERE vpa.PSD_ID = V_PSD.PSD_ID
									AND V_PSD.PSD_CATEGORY_ID!=
										 @psd_category_id)
			    )
			)                 
	END
	ELSE 
	BEGIN
		IF @split_type <> 0	-- Note: @split_type = 0 is delete only
						-- so there is nothing further to do when 0
	  	BEGIN
			--*******  split by Party
			-- insert into temp table the layout data that will be split
			INSERT INTO 
				#t_LAYOUT
			(
				NAME
			,	TALLY_TYPE_ID
			,	REVISION 
			,	MASTER_LAYOUT_ID
			)
			SELECT 
				PARTY.NAME
			,	LAYOUT.
CREATE TRIGGER TI_LAYOUT_FIELD ON LAYOUT_FIELD FOR INSERT
/******************************************************************************
TRIGGER		: TI_LAYOUT_FIELD 
Description 	: This trigger handles all inserts on the 
			Layout_Field table. Constraint checks on
				Layout_ID layout table
			,	Field_ID field table
			Also propagates data to Layout_Field_Translation 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
		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
	,	@errno    		int	-- error number 
	,	@errmsg   		varchar(255) -- error message
	-- Get the number of rows inserted
	SET 	@numrows 			= @@rowcount
	-- Initialize Berrno and @errmsg
	SET	@errno			= 0
	SET	@errmsg			= ''
	-- Parent LAYOUT must exist when inserting a child in LAYOUT_FIELD
	IF UPDATE(LAYOUT_ID)
	BEGIN
		-- if non-matching parent ids, error
		IF 	(SELECT Count(*)
			FROM   LAYOUT t1, inserted t2
			WHERE  t1.LAYOUT_ID = t2.LAYOUT_ID) <> @numrows
		BEGIN
			SELECT 
				@errno  	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not exist in LAYOUT. Cannot '
						+ 'create child in LAYOUT_FIELD.'
		END
	END
	-- Parent FIELD must exist when inserting a child in LAYOUT_FIELD
	-- only process if no error
	IF (UPDATE(FIELD_ID) AND @errno = 0)
	BEGIN
		-- if non-matching parent ids, error
		IF 	(SELECT count(*)
			FROM   FIELD t1, inserted t2
			WHERE  t1.FIELD_ID = t2.FIELD_ID) <> @numrows
		BEGIN
			SELECT @errno	= 50002	-- user defined error 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 
N1TR
ELECTION does not exist. Cannot modify child in SUSER.
 doe
hild
 in 
N1TR
 does not exist. Cannot modify child in SUSER.
cXUm
cXUm
cXUm
cXUm
cXUm
cXUm
cXUm
cXUm
TALLY_TYPE_ID
			,	CONVERT(varchar(10),PARTY.PARTY_ID)
			,	@master_layout_id
			FROM 
				v_PARTY PARTY
			,	LAYOUT_PARTY
			,	LAYOUT
			WHERE 
				LAYOUT.LAYOUT_ID 		= 	@master_layout_id
			AND 	LAYOUT_PARTY.LAYOUT_ID 	= 	@master_layout_id
			AND 	PARTY.IS_ACTIVE 		= 	1
			AND 	LAYOUT_PARTY.PARTY_ID 	= 	PARTY.PARTY_ID
			ORDER BY 
				PARTY.LIST_ORDER
			--generate new layout ids
			UPDATE 
				#t_LAYOUT
			SET 
				new_layout_id 	= layout_id + @max_layout_id
			-- Insert new layout records
			INSERT INTO 
				LAYOUT
			(
				LAYOUT_ID 
			,	NAME
			,	TALLY_TYPE_ID 
			,	REVISION
			,	MASTER_LAYOUT_ID
			)
			SELECT 
				NEW_LAYOUT_ID
			,	NAME 
			,	TALLY_TYPE_ID 
			,	REVISION
			,	MASTER_LAYOUT_ID
			FROM 
				#t_LAYOUT
			-- Insert new layout split records
			INSERT INTO 
				LAYOUT_SPLIT 
			(
				LAYOUT_ID
			,	SPLIT_ID 
			,	SPLIT^TYPE
			)
			SELECT 
				LAYOUT.LAYOUT_ID 
			,	CONVERT(NUMERIC(7), LAYOUT.REVISION) 
			,	@split_type
			FROM 
				LAYOUT
			WHERE 
				LAYOUT.MASTER_LAYOUT_ID = @master_layout_id
			-- insert new layout_contest records
			INSERT INTO 
				LAYOUT_CONTEST 
			(
				LAYOUT_ID 
			,	CONTEST_ID
			,	X
			,	Y
			,	ARROW_X
			,	ARROW_Y
			,	LIST_ORDER
			)
			SELECT 
				LAYOUT_SPLIT.LAYOUT_ID
			,	LAYOUT_CONTEST.CONTEST_ID
			,	LAYOUT_CONTEST.X
			,	LAYOUT_CONTEST.Y
			,	LAYOUT_CNNTEST.ARROW_X 
			,	LAYOUT_CONTEST.ARROW_Y 
			,	LAYOUT_CONTEST.LIST_ORDER 
			FROM 
				LAYOUT_SPLIT
			,	LAYOUT 
			,	LAYOUT_CONTEST
			,	CONTEST
			WHERE 
				LAYOUT_CONTEST.CONTEST_ID = CONTEST.CONTEST_ID
			AND 
				(
					LAYOUT_SPLIT.SPLIT_ID = CONTEST.PARTY_ID 
				OR 	CONTEST.PARTY_ID IS NULL
				)
			AND 	LAYOUT.MASTER_LAYOUT_ID 	= @master_layout_id
			AND 	LAYOUT_CONTEST.LAYOUT_ID	= LAYOUT.MASTER_LAYOUT_ID
			AND 	LAYOUT.LAYOUT_ID 		= LAYOUT_SPLIT.LAYOUT_ID
			--insert new lbyout selection records
			INSERT INTO 
				LAYOUT_SELECTION
			(
				LAYOUT_ID 
			,	SELECTION_CODE 
			,	SELECTION_NAME 
			,	PRECINCT_ID 
			,	BALLOT_STYLE_ID)
			SELECT 
				LAYOUT.LAYOUT_ID 
			,	ls.SELECTION_CODE 
			,	SELECTION_NAME 
			,	ls.PRECINCT_ID 
			,	ls.BALLOT_STYLE_ID
			FROM 
				LAYOUT
			join LAYOUT_SELECTION AS ls 
				on LAYOUT.LAYOUT_ID			= ls.LAYOUT_ID
			join BALLOT_STYLE 
				on BALLOT_STYLE.BALLOT_STYLE_ID = ls.BALLOT_STYLE_ID
			join LAYOUT_SPLIT 
				on LAYNUT_SPLIT.LAYOUT_ID 	= LAYOUT.LAYOUT_ID
			AND 
				(	NULLIF(BALLOT_STYLE.PARTY_ID,0) IS NULL 
				OR 	BALLOT_STYLE.PARTY_ID 	= LAYOUT_SPLIT.SPLIT_ID
				)
			WHERE 
				LAYOUT.MASTER_LAYOUT_ID 		= @master_layout_id
		END
	END
	IF @split_type <> 0	-- Note: @split_type = 0 is delete only
					-- so there is nothing further to do when 0
	BEGIN
		--*******  copy the fields from the master layout
		INSERT INTO 
			LAYOUT_FIELD 
			FIELD_ID 
		,	LAYOUT_ID 
		,	SOURCE_KEY
		,	X
		,	Y
		.	WIDTH
		,	HEIGHT
		,	PAGE
		,	CONTENTS)
		SELECT 
			FIELD_ID 
		,	LAYOUT.LAYOUT_ID 
		,	SOURCE_KEY
		,	X
		,	Y
		,	WIDTH
		,	HEIGHT
		,	PAGE
		,	CONTENTS 
		FROM 
			LAYOUT_FIELD LF
		,	LAYOUT
		WHERE 
			LF.LAYOUT_ID 			= LAYOUT.MASTER_LAYOUT_ID
		AND 	LAYOUT.MASTER_LAYOUT_ID 	= @master_layout_id
		--*******  copy the assignments from the master layout
		INSERT INTO 
			LAYOUT_ASSIGNMENT
			LAYOUT_ID 
		,	ASSIGNMENT_ID 
		,	ASSIGNMENT_CODE
		SELECT 
			LAYOUT.LAYNUT_ID 
		,	LAYOUT_ASSIGNMENT.ASSIGNMENT_ID 
		,	LAYOUT_ASSIGNMENT.ASSIGNMENT_CODE
		FROM 
			LAYOUT_ASSIGNMENT 
		,	LAYOUT
		WHERE 
			LAYOUT_ASSIGNMENT.LAYOUT_ID 	= @master_layout_id
		AND 	LAYOUT.MASTER_LAYOUT_ID 		= @master_layout_id
		--******* the selection codes are arbitrary.
		--  This procedure should clean''em up in a hurry
		SELECT 
			@old_layout_id = -1
		-- declare cursor
		DECLARE cr_selection INSENSITIVE CURSOR FOR
			SELECT 
				LAYOUT_SELECTION.LAYOUT_ID
			,	SFLECTION_CODE
			FROM
				LAYOUT_SELECTION
			,	LAYOUT
			WHERE 
				LAYOUT.LAYOUT_ID		= LAYOUT_SELECTION.LAYOUT_ID
			AND 	LAYOUT.MASTER_LAYOUT_ID 	= @master_layout_id
			AND 	12 >= (	SELECT 
							COUNT(*)
			     		FROM 
							LAYOUT_SELECTION LS
			     		WHERE 
							LAYOUT_ID = LAYOUT.LAYOUT_ID)
			ORDER BY 
				LAYOUT_SELECTION.LAYOUT_ID, SELECTION_CODE 
		-- open cursor
		OPEN cr_selection
		-- fetch first row into cursor
		FETCH cr_selection INTN @layout_id
		, 	@old_code
		--while a row is returned from a cursor continue processing
		WHILE @@FETCH_STATUS = 0
		BEGIN
			--Determine selection code
			IF @layout_id = @old_layout_id
		     	SELECT 
					@selection_code	= 	@selection_code + 1
			ELSE
				SELECT 
					@selection_code 	= 	1
			--Update layout selection with the new selection code
			UPDATE 
				LAYOUT_SELECTION
			SET 
				SELECTION_CODE 	= 	@selection_code
			WHERE 
				LAYOUT_ID 		= 	@layout_id 
			AND 	SELEBTION_CODE 	= 	@old_code
			SELECT
				@old_layout_id 	= 	@layout_id
			-- get next row from cursor
			FETCH cr_selection INTO @layout_id 
			, 	@old_code
	 	END  -- end of cursor
		-- close cursor and free memory
		DEALLOCATE cr_selection
		-- convert selection codes to operator panel switches if:
		-- 1. the ''BEST FIT'' option is selected
		-- 2. there are less than 12 options in the layout
		UPDATE 
			LAYOUT_SELECTION
		SET 
			SELECTION_CODE = -OP.SWITCH_NUMBER -- prevent duplibate keys 
		FROM v_OPERATOR_PANEL 			AS OP
		CROSS join LAYOUT 
		JOIN v_TALLY_TYPE 				AS tt 
			on LAYOUT.TALLY_TYPE_ID = tt.TALLY_TYPE_ID
		JOIN V_TALLY_SOURCE 			AS ts
			ON ts.TALLY_SOURCE_ID = tt.TALLY_SOURCE_ID
		LEFT JOIN V_MACHINE_TYPE_OPTION	AS mto 
			ON mto.MACHINE_TYPE_ID = IsNull(ts.MACHINE_TYPE_ID,0)
		WHERE 
			OP.OPTION_NUMBER = LAYOUT_SELECTION.SELECTION_CODE
		AND 	IsNull(mto.OPTION_ID,0)	= 	501 -- 501 is panel mode
		AND 	IsNull(mto.VALUE, 1) 	= 	0
		AND 	LAYOUT.MASTER_LAYOVT_ID 	= 	@master_layout_id
		AND	LAYOUT.LAYOUT_ID 		= 	LAYOUT_SELECTION.LAYOUT_ID 
		AND 	TOTAL_SWITCHES = (	SELECT 
								COUNT(*)
							FROM 
								LAYOUT_SELECTION LS
					      	WHERE 
								LS.LAYOUT_ID = 
									LAYOUT_SELECTION.LAYOUT_ID
						     GROUP BY 
								LS.LAYOUT_ID)
		-- Update selection codes where they are negative
		UPDATE 
			LAYOUT_SELECTION
		SET 
			SELECTION_CODE	= 	-SELECTION_CODE
		WHERE 
			SELECTION_CODE	< 	0
		--Update the revision data so vhat the layout records are in sync
		UPDATE 
			LAYOUT
		SET 
			REVISION = (	SELECT 
							REVISION
						FROM 
							LAYOUT 
						WHERE 
							LAYOUT_ID = @master_layout_id)
		WHERE	
			LAYOUT.MASTER_LAYOUT_ID = @master_layout_id
		Exec bart_layoutcontest_order	--reorder contests to assure no gaps
	END
END	-- procedure sp_split
	-- if error generated, rollback transaction, raise error
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
END -- TRIGGER TI_Layout_Selection
CREATE TRIGGER TU_LAYOUT_SELECTION 
ON LAYOUT_SELECTION FOR UPDATE 
/******************************************************************************
TRIGGER		: TU_LAYOUT_SELECTION
Description 	: This trigger handles all updates on the 
			Layout_Selection table. Constraint checks on
				Layout_ID layout table
			,	Ballot_Style_ID Ballot_Style table
			,	Audio_ID audio
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 cmmment 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
						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 LAYOUT must exist when updating a child in LAYOUT_SELECTION
	IF UPDATE(LAYOUT_ID)
	BEGIN
		IF 	(SELECT Count(*)
			FROM   LAYOUT t1, inserted t2
			WHERE  t1.LAYOUT]ID = t2.LAYOUT_ID) <> @numrows
		BEGIN
			SELECT 
				@errno  	= 50003	-- user defined error number
			,	@errmsg	= 'LAYOUT does not exist. Cannot modify child '
						+ 'in LAYOUT_SELECTION.'
		END
	END
	-- Parent BALLOT_STYLE must exist when updating a child in 
	-- LAYOUT_SELECTION, don't process if error
	IF (UPDATE(BALLOT_STYLE_ID) AND @errno = 0)
	BEGIN
		-- check count of rows with null Ballot_Style_ID
		SELECT @numnull =  Count(*)
		FROM   inserted
		WHERE  BALLOT_STYLE_ID IS NULL
		IF @numnull <> @numrows
		BEGIN
			-- if non-null rows, check parent id's, error if not found
			IF 	(SELECT Count(*)
				FROM   BALLOT_STYLE t1, inserted t2
				WHERE  
					t1.BALLOT_STYLE_ID	= t2.BALLOT_STYLE_ID
					) 				<> @numrows - @numnull
			BEGIN
				SELECT 
					@errno 	= 50003	-- user defined error number
				,	@errmsg 	= 'BALLOT_STYLE does not exist. Cannot '
							+ 'modify child in LAYOUT_SELECTION.'
			END
		END
	END
	-- Parent AUDIO must exist when updating a chimd in LAYOUT_SELECTION
	-- don't process if error has occurred
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- check count of rows with null Ballot_Style_ID
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  AUDIO_ID IS NULL
		IF @numnull <> @numrows
		BEGIN
			-- if non-null rows, check parent id's, error if not found
			IF	(SELECT Count(*)
				FROM   AUDIO t1, inserted t2
				WHERE  t1.AUDIO_ID = t2.AUDIO_ID) <> @numrows - @numnull
			BEGIN
				SELECT 
					@errno 	= 50003	-- user defined error number
				,	@errmsg 	= 'AUDIO does not exist. Cannot modify '
							+ 'child in LAYOUT_SELECTION.'
			END
		END
	END
	-- If error has occured, rollback transaction
	IF (@errno > 0)
	BEGIN
		RAISERROR @errno @errmsg
		ROLLBACK  TRANSACTION
	END
	RETURN
END -- TRIGGER TU_Layout_Selection
CREATE PROCEDURE dbo.bart_candidate_order
/******************************************************************************
Procedure:	bart_candidate_order
Description:	reorder candidates to create consecutive list order.  
			consecutive order is required before ballot creation.
Parameters: 	None
Return: 		None
External Units: bart_calc_candidate_positions
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.
8/25/05		MMcKinney		Modified script to meet code review standards
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
BEGIN
	DECLARE 
		@old_contest_id 	NUMERIC(7)	--previous contest_id
	,	@contest_id 		NUMERIC(7)	--current contest_id
	,	@list_order 		NUMERIC(7)	-- list order
	,	@candidate_id 		NUMERIC(7)	--current candidate id
	--Initialize Variables
	SELECT 
		@old_contest_id 	= 0
	,	@contest_id 		= 0
	,	@list_order 		= 0
	,	@candidate_id 		= 0
	DECLARE cr_contest INSENSITIVE CURSOR FOR
		SELECT 
			CONTEST_ID
		,	CANDIDATE_ID
		FROM 
			CANDIDATE
		WHERE 
			CANDIDATE.IS_ON_BALLOT 	> 	0
		AND 	CANDIDATE.TYPE 		<> 	4	-- 4=proposal response
		ORDER BY 
			CONTEST_ID
		, 	LIST_ORDER
	SELECT 
		@old_contest_id = -2
	OPEN cr_contest
	-- get next row from cursor
	FETCH cr_contest INTO @contest_id
	, 	@candidate_id
	--while a row is returned from a cursor continue processing
	WHILE @@FETCH_STATUS = 0 
	BEGIN
		IF @old_contest_id = @contest_id
			SELECT 
				@list_order = @list_order + 1
		ELSE
		BEGIN
			--Execute bart_calc_candidate_positions to calculate
			-- ballot positions for contest headers
			Exec bart_calc_candidate_positions @old_contest_id
	       	SELECT 
				@list_order = 1
	     END
		--Update the candidate's list order
		UPDATE 
			CANDIDATE
		SET 
			LIST_ORDER 	= 	@list_order
		WHERE
			CANDIDATE_ID	= 	@candidate_id
		SELECT 	
			@omd_contest_id	= 	@contest_id
		-- get next row from cursor
		FETCH cr_contest INTO @contest_id
		, 	@candidate_id
	 END
	--Execute bart_calc_candidate_positions to calculate
	-- ballot positions for contest headers
	 Exec bart_calc_candidate_positions @old_contest_id
	-- close cursor and free memory
	 DEALLOCATE cr_contest
END	-- procedure bart_candidate_order
CREATE FUNCTION fn_childPSDs (@parentID numeric)
RETURNS @retPsdID TABLE (PSD_ID numeric,
     PRECINCT_ID!numeric  )
/******************************************************************************
Function 		: fn_childPSDs
Description 	: This function returns table PRECINCT_ASSIGNMENT for all 
			child PSDs (including parent)
Parameters: 	@parentID -- top level psd
Return: 	Table @retPsdID
			PSD_ID		psd id
		,	Precinct_ID	precinct id
External Units:   	fn_childPSDList
Files Referenced: 	None
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distributimn 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
	-- create return table with all child psds and corresponding precinct ids
	INSERT  
		@retPsdID
	SELECT  distinct 
		c.PSD_ID
	,	pa.precinct_id
	FROM  
		fn_childPSDList(@parentID) 	c -- function gets all child psd's 
								  -- for @parentID
	,	v_precinct_assignment 		pa
	WHERE not exists -- don't include top level psd
		(select 
			1
		from    
			v_psd_extension
		where 
			parent_psd_id 			= c.psd_ID
		)  
	AND	c.psd_ID 					= pa.psd_id
	RETURN
END -- Function fn_childPSDs
										 CD.BALLOT_HEADER_ID
		        		AND 	CD.MACHINE_TYPE_ID 		= 
								CANDIDATE_DISPLAY.MACHINE_TYPE_ID
		        		AND 	CANDIDATE.CONTEST_ID 	= @contest_id
		        		AND 	CANDIDATE.LIST_ORDER 	< @list_order
		     		and 	candidate.type 		<> 9	--resolved writein
		     		GROUP BY 
						CANDIDATE.CONTEST_ID),0))
				+ IsNull((
					select 
						Max(PROPOSAL_DISPLAY.HEIGHT)
					from 
						PROPOSAL_DISPLAY
					where 
						PROPOSAL_DISPLAY.PROPOSAL_ID 		= 
								CONTEST.PROPOSAL_ID
					and 	PROPOSAL_DISPLAY.MACHINE_TYPE_ID 	= 
								CONTEST_DISPLAY.MACHINE_TYPE_ID) ,0)
		FROM 
			V_BALLOT_HEADER
		join 
			V_BALLOT_HEADER cont_BALLOT_HEADER 
			on cont_BALLOT_HEADER.ORIENTATION		= 	2 -- bottom to top
		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
		--*** left to right
		UPDATE 
			CANDIDATE_DISPLAY
		SET 
			V_OFFSET 	= 	V_BALLOT_HEADER.HEIGHT -
							cont_BALLOT_HEADER.HEIGHT
		,	I_OFFSET 	=  	V_BALLOT_HEADER.WIDTH 
			+ IsNull((
				SELECT 
					SUM(V_BALLOT_HEADER.WIDTH)
		       	FROM 
					CANDIDATE
				, 	V_BALLOT_HEADER
				, 	CANDIDATE_DISPLAY CD
		        	WHERE 
					CANDIDATE.CANDIDATE_ID 	= 	CD.CANDIDATE_ID
		        	AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID = 
							CD.BALLOT_HEADER_ID
		        	AND 	CD.MACHINE_TYPE_ID 		= 
							CANDIDATE_DISPLAY.MACHINE_TYPE_ID
		        	AND 	CANDIDATE.CONTEST_ID 	= 	@contest_id
		        	AND 	CANDIDATE.LIST_ORDER 	< 	Alist_order
		     	and 	candidate.type 		<> 	9  --resolved writein
		     	GROUP BY 
					CANDIDATE.CONTEST_ID),0)
		FROM 
			V_BALLOT_HEADER
		,	CONTEST_DISPLAY 
		,	V_BALLOT_HEADER 	cont_BALLOT_HEADER 
		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 	CONTEST_DISPLAY.BALLOT_HEADER_ID 	= 
							cont_BALLOT_HEADER.BALLOT_HEADER_ID
		AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID 	= 
							CANDIDATE_DISPLAY.BALLOT_HEADER_ID
		AND 	cont_BALLOT_HEADER.ORIENTATION 	= 	3	--left to right
		--*** right to left
		UPDATE 
			CANDIDATE_DISPLAY
		SET 
			V_OFFSET 	= 	cont_BALLOT_HEADER.HEIGHT - 
								V_BALLOT_HEADER.HEIGHT
		,	H_OFFSET 	= 	-(cont_BALLOT_HEADER.WIDTH  
						+  IsNull((
		    						SELECT 
									SUM(V_BALLOT_HEADER.WIDTH)
		       					FROM 
									CANDIDATE
								,	V_BALLOT_HEADER 
								,	CANDIDATE_DISPLAY 	CD
					        		WHERE 
								    CANDIDATE.CANDIDATE_ID = 
									CD.CANDIDATE_ID
					        		AND V_BALLOT_HEADER.BALLOT_HEADER_ID = 
									CD.BALLOT_HEADER_ID
					        		AND CD.MACHINE_TYPE_ID = 
									CANDIDATE_DISPLAY.MACHINE_TYPE_ID
					        		AND CANDIDATE.CONTEST_ID = @contest_id
					        		AND CANDIDATE.LIST_ORDER < @list_order
					     		AND candidate.type 		<> 9 
											-- 9: resolved writein
					     		GROUP BY 
								CANDIDATE.CONTEST_ID),0))
		FROM 
			V_BALLOT_HEADER
		,	CONTEST_DISPLAY 
		,	V_BALLOT_HEADER 	cont_BALLOT_HEADER 
		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 	CONTEST_DISPLAY.BALLOT_HEADER_ID 	= 
							cont_BALLOT_HEADER.BALLOT_HEADER_ID
		AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID 	= 
							CANDIDATE_DISPLAY.BALLOT_HEADER_ID
		AND 	cont_BALLOT_HEADER.ORIENTATION 	= 4 -- right tm left
		-- get n
ext row from cursor
		Fetch cr_candidate into @candidate_id
		, 	@list_order
	END
	-- close cursor and free memory
	DEALLOCATE cr_candidate
END	-- procedure bart_calc_candidate_positions
DER 	< @list_order
		     		and 	candidate.type 		<> 9	--resolved writein
		     		GROUP BY 
						CANDIDATE.CONTEST_ID),0))
				+ IsNull((
					select 
						Max(PROPOSAL_DISPLAY.HEIGHT)
					from 
						PROPOSAL_DISPLAY
					where 
						PROPOSAL_DIQPLAY.PROPOSAL_ID 		= 
								CONTEST.PROPOSAL_ID
					and 	PROPOSAL_DISPLAY.MACHINE_TYPE_ID 	= 
								CONTEST_DISPLAY.MACHINE_TYPE_ID) ,0)
		FROM 
			V_BALLOT_HEADER
		join 
			V_BALLOT_HEADER cont_BALLOT_HEADER 
			on cont_BALLOT_HEADER.ORIENTATION		= 	2 -- bottom to top
		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
		--*** left to right
		UPDATE 
			CANDIDATE_DISPLAY
		SET 
			V_OFFSET 	= 	V_BALLOT_HEADER.HEIGHT -
							cont_BALLOT_HEADER.HEIGHT
		,	H_OFFSET 	=  	V_BALLOT_HEADER.WIDTH 
			+ IsNull((
				SELECT 
					SUM(V_BALLOT_HEADER.WIDTH)
		       	FROM 
					CANDIDATE
				, 	V_BALLOT_HEADER
				, 	CANDIDATE_DISPLAY CD
		        	WHERE 
					CANDIDATE.CANDIDATE_ID 	= 	CD.CANDIDATE_ID
		        	AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID = 
							CD.BALLOT_HEADER_ID
		        	AND 	CD.MACHINE_TYPE_ID 		= 
							CANDIDATE_DISPLAY.MACHINE_TYPE_ID
		        	AND 	CANDIDATE.CONTEST_ID 	= 	@contest_id
		        	AND 	CANDIDATE.LIST_ORDER 	< 	@list_order
		     	and 	candidate.type 		<> 	9  --resolved writein
		!    	GROUP BY 
					CANDIDATE.CONTEST_ID),0)
		FROM 
			V_BALLOT_HEADER
		,	CONTEST_DISPLAY 
		,	V_BALLOT_HEADER 	cont_BALLOT_HEADER 
		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 	CONTEST_DISPLAY.BALLOT_HEADER_ID 	= 
							cont_BALLOT_HEADER.BALLOT_HEADER_ID
		AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID 	= 
							CANDIDATE_DISPLAY.BALLOT_HEADEQ_ID
		AND 	cont_BALLOT_HEADER.ORIENTATION 	= 	3	--left to right
		--*** right to left
		UPDATE 
			CANDIDATE_DISPLAY
		SET 
			V_OFFSET 	= 	cont_BALLOT_HEADER.HEIGHT - 
								V_BALLOT_HEADER.HEIGHT
		,	H_OFFSET 	= 	-(cont_BALLOT_HEADER.WIDTH  
						+  IsNull((
		    						SELECT 
									SUM(V_BALLOT_HEADER.WIDTH)
		       					FROM 
									CANDIDATE
								,	V_BALLOT_HEADER 
								,	CANDIDATE_DISPLAY 	CD
					        		WHERE 
								    CANDIDATE.CANDIDATE_ID = 
									CD.AANDIDATE_ID
					        		AND V_BALLOT_HEADER.BALLOT_HEADER_ID = 
									CD.BALLOT_HEADER_ID
					        		AND CD.MACHINE_TYPE_ID = 
									CANDIDATE_DISPLAY.MACHINE_TYPE_ID
					        		AND CANDIDATE.CONTEST_ID = @contest_id
					        		AND CANDIDATE.LIST_ORDER < @list_order
					     		AND candidate.type 		<> 9 
											-- 9: resolved writein
					     		GROUP BY 
								CANDIDATE.CONTEST_ID),0))
		FROM 
			V_BALLOT_HEADER
		,	CONTEST_DISPLAY 
		,	V_BALLOT_HEADER 	cont_BALLOT]HEADER 
		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 	CONTEST_DISPLAY.BALLOT_HEADER_ID 	= 
							cont_BALLOT_HEADER.BALLOT_HEADER_ID
		AND 	V_BALLOT_HEADER.BALLOT_HEADER_ID 	= 
							CANDIDATE_DISPLAY.BALLOT_HEADER_ID
		AND 	cont_BALLOT_HEADER.ORIENTATION 	= 4 -- right to left
		-- get n
CREATE TRIGGER TI_LAYOUT_SELECTION 
ON LAYOUT_SELECTION FOR INSERT 
/******************************************************************************
TRIGGER		: TI_LAYOUT_SELECTION
Description 	: This trigger handles all inserts on the 
			Layout_Selection table. Constraint checks on
				Layout_ID layout table
			,	Field_ID field table
			Also propagates data to Layout_Field_Translation 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 cofe 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
	-- Initiblize Variables
	-- Get the number of rows inserted
	SET 	@numrows 			= @@rowcount
	SELECT @numnull		= 0
	,	@errno			= 0
	,	@errmsg			= ''
	-- Parent LAYOUT must exist when inserting a child in LAYOUT_SELECTION
	IF UPDATE(LAYOUT_ID)
	BEGIN
		-- if non-matching parent ids, error
		IF 	(SELECT count(*)
			FROM   LAYOUT t1, inserted t2
			WHERE  t1.LAYOUT_ID = t2.LAYOUT_ID) <> @numrows
		BEGIN
			SELECT 
				@errno  	= 50002	-- user defined error number
			,	@errmsg 	= 'Parent does not ezist in LAYOUT. Cannot '
						+ 'create child in LAYOUT_SELECTION.'
		END
	END
	-- Parent BALLOT_STYLE must exist when inserting a child in 
	-- LAYOUT_SELECTION, only process if no errors
	IF (UPDATE(BALLOT_STYLE_ID) AND @errno = 0)
	BEGIN
		-- get number of Null records for Ballot_Style_ID
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  BALLOT_STYLE_ID IS NULL
						
		IF @numnull <> @numrows
		BEGIN
			-- if non-null <> total, check for parent records, if non
			-- matching, error
			IF 	(SELECT Count(*)
				FROM   BALLOT_STYLE t1, inserted t2
				WHERE  
					t1.BALLOT_STYLE_ID	= t2.BALLOT_STYLE_ID
				) 					<> @numrows - @numnull
			BEGIN
				SELECT @errno 	= 50002	-- user defined error number
				,	@errmsg 	= 'Parent does not exist in BALLOT_STYLE. '
							+ 'Cannot create child in LAYOUT_SELECTION.'
			END
		END
	END
	/*  Parent AUDIO must exist when inserting a child in LAYOUT_SELECTION  */
	IF (UPDATE(AUDIO_ID) AND @errno = 0)
	BEGIN
		-- get number of"Null records for Ballot_Style_ID
		SELECT @numnull = Count(*)
		FROM   inserted
		WHERE  AUDIO_ID IS NULL
						
		IF @numnull <> @numrows
		BEGIN
			-- if non-null <> total, check for parent records, if non
			-- matching, error
			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 LAYOUT_SELECTION.'
			END
		END
	END
	IF (@errno = 0)
	BEGIN
		-- insert initial translation records for each language
		INSERT INTO LAYOUT_SELECTION_TRANSLATION
			LAYOUT_ID
		, 	SELECTION_CODE
		, 	LANGUAGE_ID
		, 	NAME
		SELECT 
			i.LAYOUT_ID
		, 	i.SELECTION_CODE
		, 	bl.LANGUAGE_ID
		-- function gets dictionary translation
		,	dbo.bart_fn_get_translation(i.SELECTION_NAME 
								, 	bl.LANGUAGE_ID)
		FROM 
			inserted			i
		,	V_BALLOT_LANGUAGE 	bl .- cross join
	END
?Htr
IVU 
create procedure dbo.bart_sp_rotation_set
/******************************************************************************
Procedure:	bart_sp_rotation_set
Description:	Calculate a Rotation Group in the ROTATION table.
			The ROTATION GROUP field connects PRECINCT/CONTEST
			combinations that shares the same rotation
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/21/99		ToolSmith		Initial creation.
8/25/05		MMcKinney		Modified script to meet code review standards
9/16/2005		NFeldman		Modified script.  Added descriptions to temp  
						table field names in comments and modified
						script formatting to meet standardiyed
						format.
******************************************************************************/
BEGIN
	-- declare variable data structures
	--@tb_compare is used to hold the values calculated for each precinct
	-- from contest assignments
	DECLARE @tb_compare table 
		precinct_id 	numeric(7)	-- identifier of precinct
	,	duplicate_var 	float		-- duplicate variance
	,	duplicate_sum 	float		-- duplicate sum
	,	rotation_var 	float		-- rotation variance
	,	rotation_sum 	float		-- rotation sum
	,	dup_set_id 	int			-- duplicate set identifier
	-- @tb_distinct is uded to hold the distinct values. thus generating
	-- the unique set numbers
	DECLARE @tb_distinct TABLE 
		set_id 		int 	identity	-- set identifier
	,	precinct_id 	numeric(7)	-- precinct identifier
	,	var_value 	float		-- value of variance
	,	sum_value 	float		-- value of sum
	,	var_rotation 	float		-- rotation variance
	,	sum_rotation 	float		-- rotation sum
	-- load @tb_compare table with the values calculated for each precinct
	-- from contest assignments
	INSERT INTO 
		@tb_compare
		precinct_id
	,	duplicate_var
	,	duplicate_sum
	,	rotation_var
	,	rotation_sum
	SELECT 
		ROTATION.PRECINCT_ID
	,	varp(ROTATION.CONTEST_ID)
	,	sum(ROTATION.CONTEST_ID) 
	,	varp(ROTATION.CONTEST_ID/ROTATION.ROTATION_ORDER)
	,	sum(ROTATION.CONTEST_ID/ROTATION.ROTATION_ORDER)
	FROM 
		ROTATION
	join v_precinct 	PRECINCT 
		on PRECINCT.PRECINCT_ID = ROTATION.PRECINCT_ID
	GROUP BY 
		ROTATION.PRECINCT_ID
	-- load the distinct table with only distinct values.
	-- thus generating the unique set numbers
	INSERT INTO 
		@tb_distinct
		PRECINCT_ID 
	,	VAR_VALUE 
	,	SUM_VALUE 
	,	VAR_ROTATION 
	,	SUM_ROTATION
	SELECT 
		Min(PRECINCT_ID) 
	,	DUPLICATE_VAR 
	,	DUPLICATE_SUM 
	,	ROTATION_VAR 
	,	ROTATION_SUM
	FROM 
		@tb_compare
	GROUP BY 
		DUPLICATE_VAR 
	,	DUPLICATE_SUM 
	,	ROTATION_VAR 
	,	ROTATION_SUM
	-- go back and identify the duplicates
	UPDATE 
		@tb_compare
	SET 
		DUP_SET_ID 		= 	tb_distinct.SET_ID
	FROM 
		@tb_distinct 	tb_distinct
	WHERE 
		DUPLICATE_VAR 		= 	VAR_VALUE
		and DUPLICATE_SUM 	= 	SUM_VALUE
		and ROTATION_SUM 	= 	SUM_ROTATION
		and ROTATION_VAR 	= 	VAR_ROTATION
	-- finally, update the rotation table with the grouping information
	UPDATE 
		ROTATION
	SET 
		ROTATION_SET 		= 	tb_compare.DUP_SET_ID
	FROM 
		@tb_compare 	tb_compare
	WHERE 
		ROTATION.PRECINCT_ID = 	tb_compare.PRECINCT_ID
END	-- procedure bart_sp_rotation_set
create FUNCTION bart_fn_ElectionAssignment()
returns @assignment TABLE (PSD_ID numeric(7), PRECINCT_ID numeric(7))
/******************************************************************************
Function 		: bart_fn_ElectionAssignment
Description 	: Special case function that calls fn_ChildPSDs with parent ID
			of 0 (top level).  Gets all psds and corresponding precincts
Parameters: 	None (hard-coded top level parent ID = 0)
Return: 	Table @assignement
			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		Original creation
8/11/05		ECoomer		Modified script to meet code review standards
******************************************************************************/
begin
	-- call fn_ChildPSDs with top mevel parent_ID = 0.  Only return
	-- those psds with precinct assignments in table Precinct_Assignment
	insert into @assignment(PSD_ID, PRECINCT_ID)
	select t_new.PSD_ID, t_new.PRECINCT_ID
	from dbo.fn_childPSDs(0) t_new
	where 
		-- those psds with precinct assignments in table Precinct_Assignment
		t_new.PRECINCT_ID in (select PRECINCT_ID from PRECINCT_ASSIGNMENT)
	return
end -- Function bart_fn_ElectionAssignment
Election-wideNCORPORPORATED
CREATE PROCEDURE bart_election_returns_1
	@tally_mode	int
,	@contest_id	numeric(7)
,	@group_order	smallint
/******************************************************************************
Procedure:	bart_election_returns_1
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
			@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:	fnGetTurnoutSummaryByType
				fnGetTotalTurnout
				fnGetPrecinctTurnoutByType
Files Referenced:	NONE
Copyright 
 2005 Sequoia Voting Systems,
Inc. All Rights Reserved.
Any distributimn 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		Changed to use #PrecinctTurnoutByType_out instead
							of repeated calls to function
							fn_GetPrecinctTurnoutByType
******************************************************************************/
/*********)****************************************************
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
	CREATE TABLE #PrecinctTurnoutByType_out  
		precinct_id numeric			-- precinct id
	, 	tally_type_id numeric		-- tally type id
	, 	turnout numeric			-- turnout amount
	, CONSTRAINT PK_PrecinctTurnoutByType_out PRIMARY KEY	-- declare index 
		(precinct_id, tally_type_id)
	DECLARE @ErrId	int		-- Used to hold error number (status)
						-- This will be returned to calling proc
	,	@cnt		smallint	-- Counter for loop
	--Initialize Variables
	SELECT @ErrId 	= 0		-- Set error status to 0 (no error)
	,	@cnt 	= 1
	INSERT #PrecinctTurnoutByType_out 
		precinct_id
	, 	tally_type_id
	, 	turnout
	QELECT
		precinct_id
	, 	tally_type_id
	, 	turnout
	FROM fnGetPrecinctTurnoutByType(@tally_mode) 
	-- Capture error status
	SELECT @ErrId = @@ERROR
	-- loop through the groups
	WHILE @cnt <= @group_order and @ErrId = 0
	BEGIN
	-- insert header record
		INSERT INTO #xt_results
			(name, group_order, list_order, contest_id)
		VALUES ('Poll Book', @cnt, -1, 0)
		-- Capture error status
		SELECT @ErrId = @@ERROR
		--Break out of while loop on error
		IF @ErrId <> 0
			BREAK
		--insert contest totals
		INSERT INTO 
			#xt_results
		SELECT 
			'Precinct Reporting'
		,	group_order
		,	0
		,	0
		,	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_oqder - 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
		,	nullif(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. to<
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_number * 
				(Sign(-Abs(PRECINCT.list_order - 12)) + 1)), 0) t12
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order!- 13)) + 1)), 0) t13
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 14)) + 1)), 0) t14
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 15)) + 1)), 0) t15
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 16)) + 1)), 0) t16
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 17)) + 1)), 0) t17
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 18)) + 1)), 0) t18
		,	nullif(Sum(precinct_numbeq * 
				(Sign(-Abs(PRECINCT.list_order - 19)) + 1)), 0) t19
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 20)) + 1)), 0) t20
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 21)) + 1)), 0) t21
		,	nullif(Sum(precinct_number * 
				(sign(-Abs(PRECINCT.list_order - 22)) + 1)), 0) t22
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 23)) + 1)), 0) t23
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 24)) + 1)), 0) t24
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 25)) + 1)), 0) t25
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 26)) + 1)), 0) t26
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 27)) + 1)), 0) t27
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 28)) + 1)), 0) t28
		,	nullif(Sum(precinct_number * 
				(Sign(-Abs(PRECINCT.list_order - 29)) + 1)), 0) t29
		FROM 
			#t_precinct 	PRECINCT
		WHERE 
			group_order 	= 	@cnt
		GROUP BY 
			group_order
		-- Capture error status
		SELECT @ErrId = @@ERROR
		--Break out of while loop on error
		IF @ErrId <> 0
			BREAK
		--insert precinct records
		INSERT INTO 
			#xt_results
		SELECT 
			tally_type.name
		,	group_order
		,	tally_type.list_order
		,	0
		,	nullif(Sign(@cnt - @group_order) + 1, 0) * 
				(	SELECT 
						turnout
					FROM 
						fnGetTurnoutSummaryByType(@tally_mode) ts
					-- fnGetTurnoutSummaryByType returns tie turnout by
					-- tally type id 
                   	 WHERE 
					tally_type_id = pts.tally_type_id) total
		,	nullif(Sign(@cnt - @group_order) + 
				dbo.fnGetTotalTurnout(@tally_mode), 0) grand_total
				-- fnGetTotalTurnout returns total turnout 
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 1)) 
			 + 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 1)) + 1)) t1
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 2))
			 + 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 2)) + 1)) t2
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 3))
			 + 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 3)) + 1)) t3
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 4))
			 + 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 4)) + 1)) t4
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 5))
			 + 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 5)) + 1)) t5
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 6))
			!+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 6)) + 1)) t6
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 7))
			 + 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 7)) + 1)) t7
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 8))
			 + 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 8)) + 1)) t8
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 9))
			 + 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_orde
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 unused or redundant
						variables.  Modified line lengths- all to meet
						code review comments. 
9/20/05		MMcKinney		Unused code feleted
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 now
						handled by the MethodID check added.
******************************************************************************/
BEGJN
	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_ENECTION.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 - 2
			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.PREBINCT_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
r - 9)) + 1)) t9
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 10))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 10)) + 1)) t10
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 11))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 11)) + 1)) t11
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 12))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 12)) + 1)) t12
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 13))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 13)) + 1)) t13
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 14))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 14)) + 1)) t14
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 15))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 15)) + 1)) t15
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs*p.list_order - 16))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 16)) + 1)) t16
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 17))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 17)) + 1)) t17
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 18))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 18)) + 1)) t18
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 19))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 19)) + 1)) t19
	,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 20))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 20)) + 1)) t20
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 21))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 21)) + 1)) t21
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 22))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 22)) + 1)) t22
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 23))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 23)) + 1)) t23
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 24))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 24)) + 1)) t24
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 25))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 25)) + 1)) t25
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 26))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 26)) + 1)) t26
		,	nullif(Sign(Sum(precinct_number * (Sign(.Abs(p.list_order - 27))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 27)) + 1)) t27
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 28))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 28)) + 1)) t28
		,	nullif(Sign(Sum(precinct_number * (Sign(-Abs(p.list_order - 29))
			+ 1))), 0) * Sum(turnout*(Sign(-Abs(p.list_order - 29)) + 1)) t29
		FROM 
			#PrecinctTurnoutByType_out AS pts
		-- fnGetPrecinctTurnoutByType retruns precinct turnout by
		-- tally_type_id
		JOIN v^TALLY_TYPE 		AS TALLY_TYPE 
			ON TALLY_TYPE.TALLY_TYPE_ID = pts.TALLY_TYPE_ID
		JOIN #t_precinct 		AS p 
			ON pts.precinct_id = p.precinct_id
		WHERE 
			p.group_order = @cnt
		GROUP BY 
			tally_type.name
		,	group_order 
		,	tally_type.list_order 
		,	pts.tally_type_id
		-- Capture error status
		SELECT @ErrId = @@ERROR
		--Break out of while loop on error
		IF @ErrId <> 0
			BREAK
		SELECT @cnt = @cnt + 1 
	END
	--Do next step if no error
	IF @ErrId = 0
	BEGIN
		-- lasv group of precincts should contain all tally types 
		-- to bring out all summary rows
		INSERT INTO 
			#xt_results
			name
		,	group_order
		,	list_order
		,	contest_id
		,	total
		,	grand_total
		SELECT 
			tally_type.name
		,	@cnt - 1
		,	PRECINCT.list_order 
		,	0
		,	sum(turnout) 
		,	dbo.fnGetTotalTurnout(@tally_mode) grand_total
			--fnGetTotalTurnout returns total turnout
		FROM 
			fnGetPrecinctTurnoutByType(@tally_mode) turnout_summary 
		-- fnGetPrecinctTurnoutByTyre retruns precinct tu0c
rnout by
		-- tally_type_id
		JOIN #t_precinct 	PRECINCT 
			ON turnout_summary.precinct_id = precinct.precinct_id
		JOIN v_tally_type 	TALLY_TYPE 
			ON TALLY_TYPE.TALLY_TYPE_ID = TURNOUT_SUMMARY.TALLY_TYPE_ID
		WHERE 
			tally_type.name NOT IN (	SELECT 
									name 
								FROM 
									#xt_results 
								WHERE 
									group_order = @cnt -1)
		GROUP BY 
			tally_type.name
		,	PRECINCT.list_order
		-- Capture error status
		SELECT @FrrId = @@ERROR
	END
	-- Clean up - drop temporary table
	DROP TABLE #PrecinctTurnoutByType_out 
	--Return error status (will be 0 if no error)
	RETURN @ErrId
END	--End procedure bart_election_returns_1
	00c
u@!L
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 - 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_if = @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_jd = #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_tally
		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 candidatf 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 = #v_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
			JOIN 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
			-- Capturf 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 = 3 -- write-in candidates
			-- Capture error status
			SELECT @ErrId = @@ERROR
		END
		-- D
u@!L
o 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 = 3 -- 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_categorz_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 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_jd
		WHERE sov.type = 998 -- under_vote
		-- Capture error status
		SELECT @ErrId = @@ERROR
	END
	-- Do next step if no error
	IF @ErrId = 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.cnntest_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
CREATE TRIGGER td_PROVISIONAL_STATUS ON PROVISIONAL_STATUS AFTER DELETE
/******************************************************************************
TRIGGER		: td_PROVISIONAL_STATUS 
Description 	: This trigger handles all deletes on the 
			Provisional_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 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/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/25		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 lengvh
***********************************/
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
		, 	precinct_id 	numeric(7)	-- precinct id
		, 	c_turnout 	numeric(7))	-- turnout
		-- populate #turnout table with info from Provisionan_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 
		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 -- Remove 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 nuneric(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 brovght
		-- in (as acce
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 qince 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.contesu_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 columm 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)
	,	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 total 
	insert into #t_output
	select 
		#t_pct_assign.contest_id
	,	#t_pct_assign.contest]name
	,	#t_pct_assig
n.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.comtest_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
CREATE VIEW V_PARTY_DISPLAY AS SELECT * FROM RIV_20081104_P..PARTY_DISPLAY
CREATE FUNCTION fnGetTurnoutSummaryP 				
	@tally_mode 	numeric
RETURNS @turnout TABLE 
	PARTY_ID 			numeric(3)
,	TALLY_CATEGORY_ID 	numeric(3)
,	TURNOUT 			int
/******************************************************************************
Function 		: fnGetTurnoutSummaryP
Description 	: Returns a rowset of Turnout by Party and TallyCategory.
Parameters: 	@tally_mode	tally mode
Return: TABLE  @turnout  
			(
				PARTY_ID			party id
			,	TALLY_CATEGORY_ID	tally category id
			,	TURNOUT			turnout
			)
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
4/2/04		PPaiva		Build 115.  Add rows to resultant table in case 
						there is no turnout yet, if rows exist in
						Selection_Party.
8/9/04		PPaiva		Build 133.  Modification from build 115 is 
						modified to include all combinations of 
						Party-TallyType. 
8/11/05		ECoomer		Modified script to meet code review standards
10/17/05		MMcKinney		Parameters commented
11/23/05		ECoomer		Added logic to restrict records that have a NULL
						party_ID from being returned.
******************************************************************************/
BEGIN
	-- temp table to get turnout data from different processes before
	-- summing up for result set
	DECLARE @turnout_summary TABLE 
		PARTY_ID 		numeric(3)	-- party id
	,	TALLY_TYPE_ID 	numeric(3)	-- tally type id
	,	TURNOUT 		int			-- turnout
	-- temp table to get information of party_id- tally_type_Id relationship
	DECLARE @PartyTallyType TABLE	
		Party_ID 		int		--!party id
	,	Tally_Type_ID 	int		-- tally type id
	--Get the turnout from machines...
	INSERT INTO 
		@turnout_summary
	SELECT 
		sp.PARTY_ID
	, 	tm.TALLY_TYPE_ID
	, 	Sum(tm.TURNOUT)
	FROM 
		turnout_machine 	tm
	,	SELECTION_PARTY	sp  
	WHERE 
		tm.tally_mode 		= @tally_mode
	AND	tm.SERIAL_NUMBER	*= sp.SERIAL_NUMBER
	AND tm.SELECTION_CODE	*= sp.SELECTION_CODE
	AND	tm.TALLY_TYPE_ID	*= sp.TALLY_TYPE_ID
	GROUP BY 
		sp.PARTY_ID
	, 	tm.TALLY_TYPE_ID
	-- Added in Build 115.  Add qows in case there is no turnout yet, 
	-- if rows exist in Selection_Party.  
	-- Modified in Build 133.  Added rows are all combinations of Party_ID 
	-- and Tally_Type_ID that are not already in @turnout_summary.	
	-- First, get Party-TallyType combinations.
	INSERT INTO 
		@PartyTallyType
	SELECT 
		sp.Party_ID
	, 	SP.Tally_Type_ID
	FROM 
		SELECTION_PARTY 	SP
	,	turnout_machine 	T
	WHERE
		SP.SERIAL_NUMBER 	*= T.SERIAL_NUMBER
	AND 	SP.SELECTION_CODE 	*= T.SELECTION_CODE
	AND 	SP.TALLY_TYPE_ID 	*= T.TALLY_TYPE_ID
	GROUP BY 
		SP.PARTY_ID
	, 	SP.Tally_Type_ID
	-- Second, insert only those Party-TallyType combinations that are not 
	-- already present in destination.
	INSERT INTO 
		@turnout_summary
	SELECT 
		PTT.Party_ID
	, 	PTT.Tally_Type_ID
	, 	0 -- as turnout- seeding values
	FROM 
		@PartyTallyType 	PTT
	,	@Turnout_Summary 	TS
	WHERE 
		TS.Party_ID 		Is Null
	AND	PTT.Party_ID 		*= TS.Party_ID
	AND 	PTT.Tally_Type_ID 	*= TS.Tally_Type_ID
	--Get the early vote turnout...
	INSERT INTO @turnout_summary (PARTY_ID, TALLY_TYPE_ID, TURNOUT)
	SELECT PARTY_ID, turnout.TALLY_TYPE_ID, Sum(TURNOUT)
	FROM turnout_ev turnout
	LEFT JOIN SELECTION_PARTY 
		ON  SELECTION_PARTY.SERIAL_NUMBER = turnout.SERIAL_NUMBER
		AND SELECTION_PARTY.SELECTION_CODE = turnout.SELECTION_CODE
		AND SELECTION_PARTY.TALLY_TYPE_ID = turnout.TALLY_TYPE_ID
	WHERE tally_mode = @tally_mode
	GROUP BY PARTY_ID, turnout.TALLY_TYPE_ID
	--Get the external turnout...
	INSERT INTO @turnout_summary!(PARTY_ID, TALLY_TYPE_ID, TURNOUT)
	SELECT PARTY_ID, turnout.TALLY_TYPE_ID, Sum(TURNOUT)
	FROM turnout_load turnout
	WHERE tally_mode = @tally_mode
	GROU
P BY PARTY_ID, turnout.TALLY_TYPE_ID
	-- group everything by tally category and party
	INSERT INTO @turnout(PARTY_ID, TALLY_CATEGORY_ID, TURNOUT)
	SELECT PARTY_ID, TALLY_CATEGORY_ID, Sum(TURNOUT)
	FROM @turnout_summary TURNOUT_SUMMARY
	JOIN v_TALLY_TYPE TALLY_TYPE 
		ON TALLY_TYPE.TALLY_TYPE_ID = TURNOUT_SUMMARY.TALLY_TYPE_ID
	WHERE
		Party_ID	IS NOT NULL
	GROUP BY TALLY_TYPE.TALLY_CATEGORY_ID, TURNOUT_SUMMARY.PARTY_ID
	RETURN  
END -- Function fnGetTurnoutSummaryP
rec.PRECINCT_ID
		JOIN dbo.fnGetPrecinctTurnout(@tally_mode) TURNOUT_SUMMARY 
			ON TURNOUT_SUMMARY.PRECINCT_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_MAME 
		,	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 table 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_MAME 	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_prec.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 = @@ERRMR
		-- 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
CREATE VIEW V_PARAMETER AS SELECT * FROM RIV_20081104_P..PARAMETER
CREATE VIEW V_PARTY AS SELECT * FROM RIV_20081104_P..PARTY
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 screen
		,	@W -- 'W Factor' passed intm 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 tm 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 calculation 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.
	Uhe 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 precinct / 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,	cconuest_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_as
CREATE FUNCTION fnGetRegisteredVoters 
	@precinct_id 	numeric
, 	@party_id 	numeric
RETURNS 			numeric 
AS  
/******************************************************************************
Function 		: fnGetRegisteredVoters
Description 	: Returns number of registered voters in the registration 
			table.  The party ID and precinct ID can be null to return 
			data for all
Parameters: 	@precinct_id	precinct id
		,	@party_id		id of the party
Return: 	@registered_voters
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 scqipt to meet code review standards
						replaced or condition in where clause with in-
						line ISNULL checks that do the same thing
******************************************************************************/
BEGIN 
	-- return variable for the number of registered voters
	DECLARE @registered_voters	numeric
	SELECT 
		@registered_voters 	= SUM(IsNull(ACTIVE_VOTERS, 0)) 
						+ SUM(IsNull(INACTIVE_VOTERS, 0))
						-- when 0 inactive are not included 
						* (SELECT 
							is_active 
							FROM 
							v_parameter 
						WHERE 
							-- 19 inactive voters counted or not
							parameter_id 	= 19
						) 
	FROM 
		registration 
	WHERE 
		party_id 			= ISNULL(@party_id, party_ID)
	AND	precinct_id 		= ISNULL(@precinct_id, Precinct_ID)
	-- if registration data does not exists, then show registration for all
	IF @registered_voters IS NULL
	BEGIN
		SELECT 
			@registered_voters	= Sum(IsNull(TOTAL_ACTIVE_VOTERS, 0)) 
							+ Sum(IsNull(TOTAL_INACTIVE_VOTERS, 0)) 
							-- when 0 inactive are not included
							* (SELECT 
								is_active 
							FROM 
								v_parameter 
							WHERE
								-- 19 inactive voters counted or not 
								parameter_id 	= 19) 
		FROM 
			v_precinct
		WHERE 
			-- can't get party based registration from total registration
			@party_id 		IS NULL
		AND 	precinct_id 		= ISNULL(@precinct_id, Precinct_ID)
	END
	RETURN isnull(@registered_voters,0)
END -- Function fnGetRegisteredVoters
|Qm@
|Qm@
|Qm@
|Qm@
|Qm@
|Qm@
|Qm@
|Qm@
|Qm@
|Qm@
hine
er -
) + 
if(S 
Sum((
n(-A0
a.ma8
e_or@
- 14H
 1))P
Max(`
eriah
mberp
Signx
s(ma
hine
er -
) + 
if(S
Sum(
n(-A
a.ma
e_or
- 15
 1))
Max(
eria
mber
Sign
s(ma
hine
er -
) +  
	,	(
	,	n0
@xt_@
ine_H
gn mP
,	fnX
inct`
l(@th
_modp
a_prx
ct_i
) ps
-- f
cinc
al r
ns v
data
prec
test
	WHE
@a_c
st_i
 NUL
 c.c
st_i
Conv
int,
onte
ND	p 
ecin(
d = 0
reci8
D	c.H
est_P
 ps.X
est_`
	GROh
Y map
cincx
, ma
cinc
me, 
reci
orde
.nam
		c.
est_
c.ty
c.li
rder
ndid
(non
tein
chin
sult
-- n
 ins
resu(
ivision 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(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 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+@cmunter*@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
	,	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.comtest_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
y inxD
NRDE
btiv
i=T AS c
				ON c
e primary
			WH
T_CONTEST	bc
		0@*
D bc
^ID	xL*
Rroc`<
 can
"sta`<
 in 
jtho`<
DLECPJ*
rlay`<
			`<
sign 
		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
	-- MOTE: 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 	    		numeqic(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
	,	registered_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 -- uotes 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  		numeric(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 candidaue 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 	 TA<
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 null	-- column 6 candidate 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 number (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_ie 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 the 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_contesu_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(decimal(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_caneidate
		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
		INSERT 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_conteqt_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_caneidate
			 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	
CREATE VIEW V_PARTY AS SELECT * FROM RIV_20081104_P..PARTY
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 115.  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- all to meet code review comments. 
09/13/2005	NFeldman		Modified script to add comments 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 	varciar(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_id = 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
	,	candi
CREATE FUNCTION fnGetTurnoutSummary 
	@tally_mode 		numeric
RETURNS @turnout TABLE 
(	TALLY_CATEGORY_ID 	numeric(3)
, 	TURNOUT 			int
/******************************************************************************
Function 		: fnGetTurnoutSummary
Description 	: Table function returns turnout by tally_category for a 
			specified tally mode
Parameters: 	@tamly_mode	tally mode
Return: TABLE  @turnout TABLE 
			(	TALLY_CATEGORY_ID	tally category id
			, 	TURNOUT			turnout
			)
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
5/18/04		D. Weinel		Build 118.  Zero padded turnout by tally_type / 
						category to correct null!turnout values in 
						summary reports.
8/11/05		ECoomer		Modified script to meet code review standards
10/17/05		MMcKinney		Function Return commented
******************************************************************************/
BEGIN
	-- temp table for summing turnout over tally_type_id
	DECLARE @turnout_summary TABLE (
		TALLY_TYPE_ID numeric(3),	-- tally type id
		TURNOUT int				-- turnout
	-- seed table with all categories and count of 0 so all returned
	INSERT INTO @turnout_summary 
		TALLY_TYPE_ID
	, 	TURNOUT
	SELECT 
		TALLY_TYPE_ID
	, 	0
	FROM 
		V_TALLY_TYPE
	WHERE 
		IS_ACTIVE			> 0
	--Get the turnout from machines...
	INSERT INTO @turnout_summary (TALLY_TYPE_ID, TURNOUT)
	SELECT TALLY_TYPE_ID, Sum(TURNOUT)
	FROM turnout_machine
	WHERE tally_mode = @tally_mode
	GROUP BY TALLY_TYPE_ID
	--Get the early vote turnout...
	INSERT INTO @turnout_summary (TALLY_TYPE_ID, TURNOUT)
	SELECT TALLY_TYPE_ID, Sum(TURNOUT)
	FROM turnout_ev
	WHERE tally_mode = Atally_mode
	GROUP BY TALLY_TYPE_ID
	--Get the external turnout...
	INSERT INTO @turnout_summary (TALLY_TYPE_ID, TURNOUT)
	SELECT TALLY_TYPE_ID, Sum(TURNOUT)
	FROM turnout_load
	WHERE tally_mode = @tally_mode
	GROUP BY TALLY_TYPE_ID
	-- group everything by tally category
	INSERT INTO @turnout
		TALLY_CATEGORY_ID
	, 	TURNOUT
	SELECT 
		tt.TALLY_CATEGORY_ID
	, 	Sum(ts.TURNOUT)
	FROM 
		@turnout_summary 	ts
	,	v_TALLY_TYPE 		tt
	WHERE
		tt.TALLY_TYPE_ID 	= ts.TALLY_TYPE_ID
	GRMUP BY 
		tt.TALLY_CATEGORY_ID
	RETURN  
END -- Function fnGetTurnoutSummary
		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 results 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 meqsage
				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 = @counter + 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
date_name varchar(255) 	null		-- candidate name
	,	list_order 	numeric(7) 	null		-- order in list
	,	contest_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 	numeric(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  uarchar(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 mist
	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 QartyListOrder,
				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.list_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.tyqe 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 nou needed; change to blank ballot
			UPDATE #UnderOverCandidate
			SET CandidateName = 'Blank Ballots'
			,	CandidateType = 997 -- fake type for Blank Ballots
		END
	END
	ELSE
	BEGIN
		-- Add over 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
		IE @BlankBallot = 1
BEGIN
			INSERT #UnderOverCandidate
			SELECT	CandidateId + 200000, -- fake candidate_id number
			'Blank Ballots', ContestId, ContestName, PartyId, PartyListOrder,
			ContestListOrder, 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 fmr
	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
	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), 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,
		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_om_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_mrder, 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 @omd_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 = @liqt_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 	ca
	nd.contest_id 	= @old_contest_id
				and 	cand.list_order 	= 1
			end
		end -- end @old_contest_id <> @contest_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 aont.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 ccontest
	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
CREATE PROCEDURE dbo.bart_sp_sort_candidates
	@a_contest_id	numeric(7) = NULL
/******************************************************************************
Procedure		: bart_sp_sort_candidates
Description 	: sort contest for one or all contests according to 
			random alphabet order in ELECTION table.
Parameters: 	@a_contest_id	(optional)
Return: 	NONE
External Units:   	bart_fn_convert -- translates candidate first name/report 
							 -- name by e.alphabet
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
						replaced OR in where clause with inline ISNULL
						check to improve readability ane performance
******************************************************************************/
BEGIN
	-- temp table for holding converted candidate data during sort
	DECLARE @alternate_candidate TABLE 
		CANDIDATE_ID 		numeric(7)	-- candidate id
	, 	CONTEST_ID 		numeric(7)	-- contest id
	, 	FIRST_NAME 		varchar(50)	-- candidate first name
	, 	LAST_NAME 		varchar(50)	-- candidate last name
	DECLARE 
		@candidate_id 		numeric(7) -- candidate ID
	,	@contest_id 		numeric(7) -- contest ID
	,	@old_contest_id 	numeric(7) -- previous contest ID
	,	@list_order 		int -- order of candidate in contest
	-- Initialize variables
	SELECT
		@Candidate_ID 		= 0
	,	@Contest_ID		= 0
	,	@Old_Contest_ID	= 0
	,	@List_Order		= 0
	-- create translated/encrypted candidate information
	INSERT INTO 
		@alternate_candidate
	SELECT 
		c.CANDIDATE_ID
	, 	c.CONTEST_ID
		-- translates candidate first name/report name by e.alphabet
	, 	dbo.bart_fn_convert(IsNull(c.FIRST_NAME, c.REPORT_NAME), e.ALPHABET)
		-- translates candidate last name/report name by e.alphabet
	, 	dbo.bart_fn_convert(IsNull(c.LAST_NAME, c.REPORT_NAME), e.ALPHABET)
	FROM 
		dbo.CANDIDATE			c
	,	dbo.CONTEST 			co
	,	dbo.WINEDS_VERSION		wv -- cross join
	,	dbo.v_election 		e
	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(Aa_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_candidaue 
	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_order
		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_candidateq
CREATE VIEW V_LOCATION AS SELECT * FROM RIV_20081104_P..LOCATION.i
CREATE FUNCTION fnGetTurnoutSummaryByType (@tally_mode numeric)  
RETURNS @turnout TABLE (TALLY_TYPE_ID numeric(3), TURNOUT int)
/******************************************************************************
Function 		: fnGetTurnoutSummaryByType
Description 	: Table function returns turnout by tally type
Parameters: 	@tally_mode	tally mode
Return: TABLE  @turnout TABLE 
			(	TALLY_TYPE_ID		-- tally type id
			, 	TURNOUT			-- turnout
			)
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
	-- temp table for summing turnout over different sources before
	-- combining for final output
	DECLARE @turnout_summary TABLE 
		TALLY_TYPE_ID 	numeric(3)	-- tally type id
	, 	TURNOUT 		int			-- turnout
	--Get the turnout from machines...
	INSERT INTO @turnout_summary (TALLY_TYPE_ID, TURNOUT)
	SELECT TALLY_TYPE_ID, Sum(TURNOUT)
	FROM turnout_machine
	WHERE turnout_machine.tally_mode = @tally_mode
	GROUP BY TALLY_TYPE_ID
	--Get the early vote turnout...
	INSERT INTO @turnout_summary (TALLY_TYPE_ID, TURNOUT)
	SELECT TALLY_TYPE_ID, Sum(TURNOUT)
	FROM turnout_ev
	WHERE turnout_ev.tally_mode = @tally_mode
	GROUP BY TALLY_TYPE_ID
	--Get the external turnout...
	INSERT INTO @turnout_summary (TALLY_TYPE_ID, TURNOUT)
	SELECT TALLY_TYPE_ID, Sum(TURNOUT)
	FROM turnout_load
	WHERE turnout_load.tally_mode = @tally_mode
	GROUP BY TALLY_TYPE_ID
	-- group everything by tally category
	INSERT INTO @turnout(TALLY_TYPE_ID, TURNOUT)
	SELECT TALLY_TYQE_ID, Sum(TURNOUT)
	FROM @turnout_summary TURNOUT_SUMMARY
	GROUP BY TALLY_TYPE_ID
RETURN  
END -- Function fnGetTurnoutSummaryByType
CREATE  PROCEDURE 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
		,	@tally_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/05		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 comtest_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_aategory 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
			JMIN v_tally_type AS tt ON tt.tally_type_id = tm.tally_type_id
			JOIN ##p_candidate AS 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 #u_sov
		SET   total = #t_sov.total + IsNull(#t_tally.total, 0)
		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 candidate.candidaue_id, precinct_id,
	 	tally_category_id, sum(tally_ev.total)
		FROM tally_ev JOIN v_tally_type 
				ON v_tally_type.tally_type_id	= tally_ev.tally_type_id
			JOIN ##p_candidate AS candidate 
				ON candidate.candidate_id = tally_ev.candidate_id
		WHERE tally_mode 				= @tally_mode
		AND 	candidate.ccontest_id 		= @a_contest_id
		AND 	candidate.type 			<> 3 -- 3 is write-in
		GROUP BY candidate.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 
		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 candidate.candidate_id, precinct_id,
			tally_category_id, sum(tally_load.total)
		FROM tally_load JOIN v_tally_type 
			ON v_tally_type.tally_type_id	= tally_load.tally_type_id
		JOIN ##p_candidate AS candidate 
			ON candidate.candidate_id = tally_load.candidate_id
		WHERE tally_mode				= @tally_mode
		AND 	candidate.ccontest_id 		= @a_contesu_id
		AND 	candidate.type 			<> 3 	-- 3 is write-in
		GROUP BY candidate.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 
		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_tally
		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)
		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  -- 3 is write-in
		GROUP BY c.contest_id, precinct_id, tally_category_id
		-- 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_smv
			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)
			FROM tally_ev JOIN v_tally_type 
					ON v_tally_type.tally_type_id	= tally_ev.tally_type_id
				JOIN 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 is wri
te-in
			GROUP BY c.contest_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 + #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)
			FROM tally_load JOIN v_tally_type AS tt
					ON tt.tally_type_id = tally_load.tally_type_id
				JOIN candidate AS c 
					ON c.candidate_id = tally_load.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 is write-in
			GROUP BY c.contest_id, precinct_id, tally_category_id
			-- Capture error status
			SELECT @ErrId = @@ERROR
		END
		-- Dm 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 candidates
			-- Capture error status
			SELECT @ErrId = @@ERROR
		END
	END -- writein only
	-- Do next suep 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 contest ON contest.contest_id = t.contest_id
 			WHERE t.tally_mode = @tally_mode
				AND contest.ccontest_id =  @a_contest_id
			GQOUP 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 @ErrId = 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_ie, 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		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
XR8S
CREATE VIEW V_LOCATION_GROUP AS SELECT * FROM RIV_20081104_P..LOCATION_GROUP
CREATE FUNCTION fnGetTotalInactiveVoters 
	@precinct_id numeric
RETURNS numeric 
AS  
/******************************************************************************
Function 		: fnGetTotalInactiveVoters
Description 	: returns total Inactive voters for a precinct from the 
			PRECINCT table
Parameters: 	@precinct_ID	precinct id
Return:	@totalinactivevoters (count of inactive voters)
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 and function return commented
******************************************************************************/
BEGIN
	-- variable for totalling the number of active voters
	DECLARE  @totalinactivevoters numeric
	-- set variable equal to the sum of Total_Inactive_Voters from
	-- precinct table 
	SELECT  @totalinactivevoters = SUM(TOTAL_INACTIVE_VOTERS)
	FROM V_PRECINCT   
	WHERE PRECINCT_ID = @precinct_id 
	-- if value null, return 0 instead
	RETURN  ISNULL(@totalinactivevmters, 0)
END -- fnGetTotalInactiveVoters
	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
CREATE PROCEDURE bart_sp_sov_sum_build_output_2
	@a_contest_id		numeric(7)
,	@pages			int
,	@counter			int
,	@W 				tinyint
/******************************************************************************
Procedure:	bart_sp_sov_sum_build_output_2
Description:	sub proc called from for bart_sp_sov_summary
			loads data into temp table #t_output
Parameters: 	@a_contest_id -- contest id to get vote info for- if null- all
			@pages	-- number of pages in report
			@counter	-- counuer to track pages
			@W 		-- 'W Factor' passed into procedure
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
1/20/06		MMcKinney 	Initial creation - Code modified from original
						proc bart_sp_sov_summary 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)
--****************************************************************
--********    Part 1b: Grand Total line for the contest
--****************************************************************
-- insert empty line before total 
INSERT INTO 
	#t_output
SELECT DISTINCT 
	t_pct_assign.contest_id
,	t_pct_assign.contest_name
,	t_pct_assign.contest_order
,	t_pct_assign.vote_eor
,	@counter + 1    --  page number ---
,	0 
,	null
,	null
,	null 
,	null
,	null
,	null 
,	null
,	null
,	null 
,	null
,	null
,	null 
,	null 
,	null
,	null 
,	null
,	9999999 -- temporarily use highest psd_category_order
,	998	   --  psd_order
FROM 
	#t_pct_assign AS 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
SELEAT @ErrId = @@ERROR
-- Do next step if no error
IF @ErrId = 0
BEGIN
	--******************************************************************
	--********    Part 1b: grand total for contest
	--*****************************************************************
	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 
	,	'Grand Totals ' 
	,	'Grand Totals' 
	,	Sum(t_pct_assign.registered_voters 
		* (Sign(-Abs(candidate.list_order - (1 + @counter * 12))) + 1)
		* (Sign(-Abs(t_pct_assign.tally_category_order - 1)) + 1))
	,	Sum(t_pct_assign.turnout 
		* (Sign(-Abs(candidate.list_order - (1 + @counter * 12))) + 1))
	,	Sum(	CASE 
				WHEN candidate.list_order = 1 + @counter * @W 
					THEN total 
				ELSE c1  	 -- column 1
			END)
	,	Sum(	CASE 
				WHEN candidate.list_order = 2 + @counter * @W 
					THEN total 
				ELSE c2  	 -- column 2
			END)
	,	Qum(	CASE 
				WHEN candidate.list_order = 3 + @counter * @W 
					THEN total 
				ELSE c3  	 -- column 3
			END)
	,	Sum(	CASE 
				WHEN candidate.list_order = 4 + @counter * @W 
					THEN total 
				ELSE c4  	 -- column 4
			END)
	,	Sum(	CASE 
				WHEN candidate.list_order = 5 + @counter * @W 
					THEN total  
				ELSE c5  	 -- column 5
			END)
	,	Sum(	CASE 
				WHEN candidate.list_order = 6 + @counte
r * @W 
					THEN total  
				ELSE c6  	 -- column 6
			END)
	-	Sum(	CASE 
				WHEN candidate.list_order = 7 + @counter * @W 
					THEN total 
				ELSE c7  	 -- column 7
			END)
	,	Sum(	CASE 
				WHEN candidate.list_order = 8 + @counter * @W 
					THEN total 
				ELSE c8  	 -- column 8
			END)
	,	Sum(	CASE 
				WHEN candidate.list_order = 9 + @counter * @W 
					THEN total 
				ELSE c9  	 -- column 9
			END)
	,	Sum(	CASE 
				WHEN candidate.list_order = 10 + @counter * @W 
					THEN total 
				ELSE c10  	 -- column 10
			END)
	,	Sum(	CASE 
				WHEM candidate.list_order = 11 + @counter * @W 
					THEN total 
				ELSE c11 	 -- column 11
			END)
	,	Sum(	CASE 
				WHEN candidate.list_order = 12 + @counter * @W 
					THEN total 
				ELSE c12  	 -- column 12
			END)
	,	9999999			--  psd_category_order
	,	999				--  psd_order
	,	1				--  sort_order
	FROM 
		#t_candidate AS candidate
		JOIN #t_pct_assign AS t_pct_assign 
			ON candidate.ccontest_id	= t_pct_assign.contest_id
		JOIN #t_sov AS t_sov 
			ON t_sov.candidate_id 		= candidate.candidate_id
			AND t_sov.tally_category_id 	= t_pct_assign.tally_category_id
			AND t_sov.precinct_id 		= t_pct_assign.precinct_id
		CROSS JOIN #t_columns AS t_columns 
	WHERE  
		t_pct_assign.contest_id 	= @a_contest_id 
	GROUP BY 
		t_pct_assign.contest_id
	,	t_pct_assign.contest_name 
	,	t_pct_assign.contest_order
	,	t_pct_assign.vote_for
	-- Capture error status
	SELECT @ErrId = @@ERROR
--Return error status (will be 0 if no error
RETURN @ErrId
END -- procedure bart_sp_sov_sum_buile_output_2
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_number  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 	SESSION_NUMBER = @session_number
END -- Procedure bart_sp_delete_ev_session
ct_assign.tally_category_id= t_sov.tally_category_id
		AND t_pct_assign.precinct_id	= t_sov.precinct_id
	JOIN dbo.bart_fn_PrecinctAssignment() AS PA 
		ON PA.PRECINCT_ID = t_sov.precinct_ID
	JOIN v_psd AS PSD 
		ON psd.psd_id = PA.psd_id
	JOIN	v_psd_category AS psd_category 
		ON psd.psd_category_id = psd_category.psd_category_id
	CROSS JOIN #t_columns 
WHERE  
	t_pct_assign.contest_id 	= @a_contest_id 
AND 	IsNull(PSD.IS_SOV_SUMMARY, 0)	= 1
EROUP BY 
	t_pct_assign.contest_name
,	t_pct_assign.contest_id
,	t_pct_assign.contest_order
,	t_pct_assign.vote_for
, 	PSD.name
,	PSD.psd_id
,	psd.tree_order
,	psd_category.list_order
,	psd_category.name 	
ORDER BY 
	PSD_CATEGORY.list_order
, 	PSD.tree_order
-- Capture error status
SELECT @ErrId = @@ERROR
-- Do next step if no error
IF @ErrId = 0
BEGIN	
	--*******************************************************************
	--    Part 1a: Total by tally category
	--***************)***************************************************
	-- insert an empty line before each tally category summary row
	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 
	,	null 
	,	9999996 	--temporarily siow highest psd_category_order
	,	t_pct_assign.tally_category_order * 10 - 5
	,	1
	FROM 
		#t_pct_assign 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.contest_order
	,	t_pct_assign.vote_for
	,	t_pct_assign.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	
			t_pct_assign.contest_id
		,	t_pct_assign.contest_name
		,	t_pct_assign.contest_order
		,	t_pct_assign.vote_for
		,	@counter + 1   --  if number of candidates > 12 , page number --
		,	0
		,	t_pct_assign.tally_category_name
		,	t_pct_assign.tally_category_name + ' Totals ' 
		,	Sum(t_pct_assign.registered_voters 
			* (Sign(-Abs(candidate.list_order - (1 + @counter * 12))) +!1))
		,	Sum(t_pct_assign.turnout 
			* (Sign(-Abs(candidate.list_order - (1 + @counter * 12))) + 1)) 
		,	Sum(CASE WHEN candidate.list_order = 1 + @counter * @W THEN total 
					ELSE c1  	 -- column 1
				END)
		,	Sum(CASE WHEN candidate.list_order = 2 + @counter * @W THEN total 
					ELSE c2  	 -- column 2
				END)
		,	Sum(CASE WHEN candidate.list_order = 3 + @counter * @W THEN total  
					ELSE c3  	 -- column 3
				END)
		,	Sum(CASE WHEN candidate.list_order = 4 + @counter * @W THEN total 
					ELSE c4  	 -- column 4
				END)
		,	Sum(CASE WHEN candidate.list_order = 5 + @counter * @W THEN total 
					ELSE c5  	 -- column 5
				END)
		,	Sum(CASE WHEN candidate.list_order = 6 + @counter * @W THEN total 
					ELSE c6  	 -- column 6
				END)
		,	Sum(CASE WHEN candidate.list_order = 7 + @counter * @W THEN total 
					ELSE c7  	 -- column 7
				END)
		,	Sum(CASE WHEN candidate.list_order = 8 + @counter * @W THEN total 
					ELSE c8  	 -- column 8
				END)
		,	Sum(CASE WHEN candidate.list_order = 9 + @counter * @W THEN total 
					ELSE c9  	 -- column 9
				END)
		,	Sum(CASE WHEN candidate.list_order = 10 + @counter * @W 
						THEN total 
					ELSE c10  	 -- column 10
				END)
		,	Sum(CASE WHEN candidate.list_order = 11 + @counter * @W 
						THEN total 
					ELSE c11  	 -- column 11
				END)
		,	Sum(CASE WHEN candidate.list_order = 12 + @counter * @W 
						THEN total 
					ELSE c12  	 -- column 12
				END)
		,	9999996 	--psd_cat
egory_order
		,	t]pct_assign.tally_category_order * 10
		,	1
		FROM 
			#t_candidate AS candidate
			JOIN #t_pct_assign AS t_pct_assign 
				ON candidate.ccontest_id	= t_pct_assign.contest_id
			JOIN #t_sov AS t_sov 
				ON t_sov.candidate_id = candidate.candidate_id
				AND t_sov.tally_category_id = t_pct_assign.tally_category_id
				AND t_sov.precinct_id = t_pct_assign.precinct_id
			CROSS JOIN #t_columns AS t_columns 
		WHERE   
			t_pct_assign.contest_id 	= @a_contest_id 
		GROUP BY 
			t_pct_assign.contesu_id
		,	t_pct_assign.contest_name 
		,	t_pct_assign.contest_order
		,	t_pct_assign.tally_category_id
		,	t_pct_assign.vote_for
		,	tally_category_name
		,	tally_category_order
	-- Capture error status and rowcount
	SELECT @ErrId = @@ERROR
--Return error status (will be 0 if no error
RETURN @ErrId
END -- procedure bart_sp_sov_sum_build_output_1
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.ARROW_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 -- cqoss 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
		EROM 
			#t_lc 			LC 
		,	dbo.LAYOUT_ASSIGNMENT 	la
		,	dbo.LAYOUT			l -- cross join
		WHERE 
			l.LAYOUT_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
	,	mc.Contest_ID
	,	lc.X
	,	lc.Y
	,	lc.Arrow_X
	,	lc.Arrow_Y
	,	lc.List_Order
	,	lc.Page
	INTO 
		#t_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
	FQOM 
		#t_template 	t
	,	dbo.LAYOUT 		l -- cross join
	WHERE 
		l.LAYOUT_ID 		= LAYOUT_CONTEST.LAYOUT_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.MAYOUT_ID
			AND (X *
 Y 		> 0 
				OR PAGE 		> 0
				)
			)
END -- Procedure bart_sp_copy_positions
CREATE VIEW V_LOCATION_NEED AS SELECT * FROM RIV_20081104_P..LOCATION_NEED
CREATE  PROCEDURE bart_delete_layout_image
	@contest_id NUMERIC(7)
/******************************************************************************
PROCEDURE:		bart_delete_layout_image 
Description: 		This procedure deletes a layout image
Parameters:		@contest_id 			-- contest 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
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 describe temp table fields.
09/16/2005	NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
BEGIN
	-- create temp table #t_layout
	create table #t_layout
		layout_id numeric(7) not null -- identifier of layout
	if @contest_id >0 
	   begin
			-- put layout_id of contest into temp table
	    		insert into 
				#t_layout 
			select 
				layouu_id 
			from 
				layout_contest 
	        	where 
				contest_id = @contest_id
			-- delete relevant records from LAYOUT_IMAGE_FILE
	     	delete 
				layout_image_file 
			where 
				layout_id in (	select 
								layout_id 
							from 
								#t_layout)
			-- delete relevant records from LAYOUT_IMAGE_FILE_TRANSLATION
	     	delete 
				layout_image_file_translation 
			where 
				layout_id in (	select 
								layout_id 
							From 
								#t_layout)
	  end 
	-- drop temp!table
	DROP TABLE 
		#t_layout
END  -- end procedure bart_delete_layout_image
 gets recompiled */
	-- Create temp table to hold precinct / 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 oe 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) 	  -- idemtifier 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
	,	CAMDIDATE_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
	-- 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	-- identieier 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 	-- Total number of elected 
										-- officials in the office
	,	page 	    		numeric(7) null 	-- number of pages  
										-- allocated for a contest 
	,	psd_id 			numeric(7) not null	-- political subdivision id
	,	psd_category_name 	varchar(50) null 	-- name of psd category
	,	psd_name 		varchar(50) null 	-- name of pomitical subdivision
	,	registered_voters 	numeric(7) null  	-- number of registered voters
	,	turnout 			numeric(7) null     -- total votes
	,	candidate_1 		numeric(7) null 	-- candidate #1 on ballot
	,	candidate_2 		numeric(7) null 	-- candidate #2 on ballot
	,	candidate_3 		numeric(7) null 	-- candidate #3 on ballot
	,	candidate_4 		numeric(7) null 	-- candidate #4 on ballot
	,	candidate_5 		numeric(7) null 	-- candidate #5 on ballot
	,	candidate_6 		numeric(7) null 	-- candidate #6 on ballot
	,	aandidate_7 		numeric(eci<
7) null 	-- candidate #7 on ballot
	,	candidate_8 		numeric(7) null 	-- candidate #8 on ballot
	,	candidate_9 		numeric(7) null 	-- candidate #9 on ballot
	,	candidate_10 		numeric(7) null 	-- candidate #10 on ballot
	,	candidate_11 		numeric(7) null 	-- candidate #11 on ballot
	,	candidate_12 		numeric(7) null 	-- candidate #12 on ballot
	,	psd_category_order 	numeric(7) null 	-- order of psd category
	,	psd_order 		numeric(7) null	-- order of psd on balmot
	,	sort_order 	numeric(7)  		-- sort order on report
	)  
	-- 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 null	-- column 6 candidate results
	,	c7 	tinyint null	-- column 7 candidate reqults
	,	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 number (status) 
							-- will be 0 if no error
	,	@ErrMsg			varchar(255) -- Holds error message
	-- 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 = bart_sp_sov_sum_load_precincts
			@a_contest_id	= @a_contest_id,
			@tally_mode = @tally_mode,
			@turnout_by_party = @turnout_by_party
	--Build error message or do the next step if no!error condition
	IF @ErrId <> 0	
		SELECT @ErrMsg = 'Error while executing'
					+ ' bart_sp_sov_sum_load_precincts'
					+ ' Error: ' + CAST(@ErrId AS varchar(8))
	ELSE
	BEGIN
		-- load tally data into #t_sov
		EXEC @ErrId = bart_sp_sov_sum_load_tally
				@a_contest_id	= @a_contest_id,
				@tally_mode = @tally_mode,
				@include_writein = @include_writein
		--If error, build error message
		IF @ErrId <> 0	
			SELECT @ErrMsg = 'Error while executing'
						+ ' bart_sp_sov_sum_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 cmmputed number
		SELECT @pages = Ceiling(Convert(decimal(7, 2), last_candidate)/12)
		FROM ##p_contest
		WHERE ccontest_id = @a_contest_id
		--*******************************************************************
		-- when required number of candidates allocate space 
		-- on multiple pages 
		SELECT 
			candidate_id
		, 	candidate_name
		, 	list_order
		,	contest_id
		, 	ccontest_id
		, 	type
		INTO #t_candidate
		FROM 
			##p_candidate candidate
		WHERE 
			candidate.ccontest_id = @a]contest_id
		-- load temp table #t_columns
		-- insert 0 for valid column candidates and null for all others
		INSERT 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
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 script 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.EXTERNAL_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
		AMD 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
	-- 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
CREATE VIEW V_LOCATION_GROUP_MEMBER AS SELECT * FROM RIV_20081104_P..LOCATION_GROUP_MEMBER
Create procedure bart_layout_snake_4c
	@first_x 		numeric(6,3)
,	@first_y 		numeric(6,3)
,	@tally_type_id numeric(3) = null
,	@a_layout_id 	numeric(7) = null 
,	@v_space 		numeric(6,3) = 0.000
,	@party_id 	numeric(3) = null 
,	@last_x 		mumeric(6,3) = 3	--width
,	@last_y 		numeric(6,3) = 10	--height
,	@contest_type 	int = null
,	@h_space 		numeric(6,3) = 0
,	@density 		int=6
,	@MACHINE_TYPE_ID int
/******************************************************************************
PROCEDURE:	bart_layout_snake_4c 
Description: 	This procedure sets the layout of snake ballot
Parameters:	@first_x numeric(6,3)		-- original x position
		,	@first_y numeric(6,3)		-- original y position
		,	@tally_type_id numeric(3) = null -- (optional)tally type id
		,	@a_layout_id numeric(7) = null 	-- (optional) original 
											--	layout id
		,	@v_space numeric(6,3) = 0.000	-- (optional) vertical 
											--	spacing
		,	@party_id numeric(3) = null -- (optional)party id
		,	@last_x numeric(6,3) = 3	-- (optional)width
		,	@last_y numeric(6,3) = 10	-- (optional)height
		,	@contest_type int = null	-- (optional)type of contest
		,	@h_space numeric(6,3) = 0	-- (optional)horizontal spacing
		,	@density int=6			-- (optional)density - nou actually
								-- 		used in the procedure
		,	@MACHINE_TYPE_ID int	-- 	(optional)machine type id
Return:	On error, returns 'Not enough columns for all Contests
		and candidates.  Please change layout parameters and try again.'
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		Added descriptions to temp table fields.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
begin
	declare 
		@layout_id 	numeric(7) -- current loop layout
	, 	@contest_id 	numeric(7) -- current loop contest
	, 	@old_layout_id numeric(7) -- previous loop layout (for comparison)
	, 	@xpos 		numeric(6,3) -- new horizontal position
	, 	@ypos 		numeric(6,3) -- new vertical position
	, 	@height 		numeric(6,3) -- contest header height
	, 	@width 		numeric(6,3) -- contest header width
	, 	@max_width 	numeric(6,3) -- width of contest including all 
							   -- candidates
	, 	@totalContestHeight numeric(6,3)  --height of contest and 
								    -- including all candidates
	, 	@sql 		vaqchar(255) -- string that holds dynamic 
							   -- sql statement
	, 	@ErrMsg		varchar(255) -- error message for raising errors
	,	@errno		int		   -- error number
	--initialize variables
	select 
		@layout_id = 0
	, 	@contest_id = 0
	, 	@old_layout_id = 0
	, 	@xpos = 0
	, 	@ypos = 0
	, 	@height = 0
	, 	@width = 0
	, 	@max_width = 0
	, 	@totalContestHeight = 0
	, 	@sql = ''
	, 	@ErrMsg = ''
	,	@errno = 0
	-- declare cursor cr_contests
	declare cr_contests insensitive cursor for
		SELECT 
			lay_cont.LAYOUT_ID
		, 	lay_cont.CONTEST_ID
		, 	bh.HEIGHT
		, 	bh.WIDTH
		--** calculate the height of all candidates in the contest
 		, 	Convert(numeric(6,3)
		,	(SELECT 	case bh.orientation
						when 1 then max(cd.v_offset)
						else 0 
					end 	
			from 
				candidate_display		cd
			join candidate 			cand
				on cand.candidate_id 	= cd.candidate_id
			join	v_ballot_header 		bh2 
				on cd.ballot_header_id 	= bh2.ballot_header_id
			where 
				cand.is_on_ballot 		<> 0
			and 	cd.machine_type_ID 		= cont_disp.MACHINE_TYPE_ID
			and 	cand.contest_id 		= cont.contest_id))		
	FROM 
		LAYOUT_CONTEST					lay_cont
	JOIN LAYOUT 						la
	 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 ***********
		-- ** NOTE ** 	The order of inserting the data (by page then section) 
		--				is not the order of the data
		-- 	The insertion by page have a neater appearance because there is 
		--				only one loop
		WHILE (@counter < @pages) AND @ErrId = 0
		BEGIN
			-- The code to load the results for output is devided into two
			-- parts due uo the 240 line limit. Call the two parts in
			-- succession for each page.
			-- load first part of output data into #t_output	
			EXEC @ErrId = bart_sp_sov_sum_build_output_1
					@a_contest_id	= @a_contest_id,
					@pages = @pages,
					@counter = @counter,
					@W = @W
			--If error, build error message
			IF @ErrId <> 0	
				SELECT @ErrMsg = 'Error while executing'
							+ ' bart_sp_sov_sum_build_ouput_1'
							+ ' Error: ' + CAST(@ErrId AS varchar(8))
			IF @ErrId = 0
			BEGIN
				-- load second part of output data into #t_output	
				EXEC @ErrId = bart_sp_sov_sum_build_output_2
						@a_contest_id	= @a_contest_id,
						@pages = @pages,
						@counter = @counter,
						@W = @W
				--If error, build error message
				IF @ErrId <> 0	
					SELECT @ErrMsg = 'Error while executing'
							+ ' bart_sp_sov_sum_build_ouput_2'
							+ ' Error: ' + CAST(@ErrId AS varchar(8))
			END
			-- increment page counter
			SELECT @counter = @counter + 1
		END	
	END
	IF @ErqId = 0		
	BEGIN
		-- select out result set
		SELECT 
			* 
		FROM 
			#t_output
		ORDER BY 
			contest_order
		,	sort_order
		,	psd_category_order
		,	psd_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	-- End of proceedure bart_sp_sov_summary
Create procedure bart_layout_snake_4c
	@first_x 		numeric(6,3)
,	@first_y 		numeric(6,3)
,	@tally_type_id numeric(3) = null
,	@a_layout_id 	numeric(7) = null 
,	@v_space 		numeric(6,3) = 0.000
,	@party_id 	numeric(3) = null 
,	@last_x 		numeric(6,3) = 3	--width
,	@last_y 		numeric(6,3) = 10	--height
,	@contest_type 	int = null
,	@h_space 		numeric(6,3) = 0
,	@density 		int=6
,	@MACHINE_TYPE_ID int
/******************************************************************************
PROCEDURE:	bart_layout_snake_4c 
Description: 	This procedure sets the layout of snake ballot
Parameters:	@first_x numeric(6,3)		-- original x position
		,	@first_y numeric(6,3)		-- original y position
		,	@tally_type_id numeric(3) = null -- (optional)tally type id
		,	@a_layout_id numeric(7) = null 	-- (optional) original 
											--	layout id
		,	@v_space numeric(6,3) = 0.000	-- )optional) vertical 
											--	spacing
		,	@party_id numeric(3) = null -- (optional)party id
		,	@last_x numeric(6,3) = 3	-- (optional)width
		,	@last_y numeric(6,3) = 10	-- (optional)height
		,	@contest_type int = null	-- (optional)type of contest
		,	@h_space numeric(6,3) = 0	-- (optional)horizontal spacing
		,	@density int=6			-- (optional)density - not actually
								-- 		used in the procedure
		,	@MACHINE_TYPE_ID int	-- 	(optional)machine type id
Return:	On error, returns 'Not enough aolumns for all Contests
		and candidates.  Please change layout parameters and try again.'
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 
						lengthq- all to meet code review comments. 
09/13/2005	NFeldman		Added descriptions to temp table fields.
9/16/2005		NFeldman		Modified script formatting to meet standardized
						format.
******************************************************************************/
begin
	declare 
		@layout_id 	numeric(7) -- current loop layout
	, 	@contest_id 	numeric(7) -- current loop contest
	, 	@old_layout_id numeric(7) -- previous loop layout (for comparison)
	, 	@xpos 		numeric(6,3) -- new horizontal position
	, 	@ypos 		numeric(6,3) -- new vertical position
	, 	@height 		numeric(6,3) -- contest header height
	, 	@width 		numeric(6,3) -- contest header width
	, 	@max_width 	numeric(6,3) -- width of contest including all 
							   -- candidates
	, 	@totalContestHeight numeric(6,3)  --height of contest and 
								    -- including all candidates
	, 	@sql 		varchar(255) -- string that holds dynamic 
							   -- sql statement
	, 	@ErrMsg		varchar(255) -- error message for raising errors
	,	@errno		int		   -- error number
	--initialize variables
	select 
		@layout_id = 0
	, 	@contest_id = 0
	, 	@old_layout_id = 0
	, 	@xpos = 0
	, 	@ypos = 0
	, 	@height = 0
	, 	@width = 0
	, 	@max_width = 0
	, 	@totalContestHeight = 0
	, 	@sql = ''
	, 	@ErrMsg = ''
	,	@errno = 0
	-- declare cursor cr_contests
	declare cr_contests insensitive cursor for
		SELECT 
			lay_cont.LAYOUT_ID
		, 	lay_cont.CONTEST_ID
		, 	bh.HEIGHT
		, 	bh.WIDTH
		--** calculate the height of all candidates in the cmntest
 		, 	Convert(numeric(6,3)
		,	(SELECT 	case bh.orientation
						when 1 then max(cd.v_offset)
						else 0 
					end 	
			from 
				candidate_display		cd
			join candidate 			cand
				on cand.candidate_id 	= cd.candidate_id
			join	v_ballot_header 		bh2 
				on cd.ballot_header_id 	= bh2.ballot_header_id
			where 
				cand.is_on_ballot 		<> 0
			and 	cd.machine_type_ID 		= cont_disp.MACHINE_TYPE_ID
			and 	cand.contest_id 		= cont.contest_id))		
	FROM 
		LAYOUT_CONTEST					lay_cont
		JOIN LAYOUT 						la
		ON lay.LAYOUT_ID 				= lay_cont.LAYOUT_ID
	JOIN CONTEST_DISPLAY 				cont_disp
		ON cont_disp.CONTEST_ID 			= lay_cont.CONTEST_ID
	JOIN CONTEST 						cont
		ON cont.CONTEST_ID 				= lay_cont.CONTEST_ID
	JOIN V_BALLOT_HEADER 				bh
		ON cont_disp.BALLOT_HEADER_ID		= bh.BALLOT_HEADER_ID
	JOIN V_TALLY_TYPE 					tt
		ON tt.TALLY_TYPE_ID 			= lay.TALLY_TYPE_ID
	JOIN V_TALLY_SOURCE 				ts
		ON tt.TALLY_SOURCE_ID 			= ts.TALLY_SOURCE_ID
	AND ts.MACHINE_TYPE_ID 				= cont_disp.MACHINE_TYPE_ID
	WHERE 	
		(@tally_type_id 				IS NULL 
		or 	tt.TALLY_TYPE_ID 			= @tally_type_id
	AND 	(@a_layout_id 					IS NULL 
		OR IsNull(MASTER_LAYOUT_ID, -1) 	= @a_layout_id
	AND 	cont.IS_ON_BALLOT 				<> 0
	AND 	(@party_id 					IS NULL 
		or IsNull(cont.PARTY_ID,0) 		= @party_id
	AND 	ISNULL(lay.MASTER_LAYOUT_ID, -1) 	> 0 -- exclude template
	AND 	(@contest_type 				IS NULL 
		OR (cont.TYPE 					in (0,2) 	-- standard or
									-- unaffected by stqaight party 
			AND 	@contest_type 			= 0	-- standard
		OR (cont.PROPOSAL_ID 			IS NOT NULL 
			and 	@contest_type 			= 4	-- Proposal
		OR (cont.TYPE 					in (1,5,7) -- 1: straight party or
								 	-- 5: Selective Primary or
								 	-- 7: office-use-only
			AND 	cont.PROPOSAL_ID 	IS NULL 
			and 	@contest_type = 1	 -- straight party 
		) 
	AND cont_disp.MACHINE_TYPE_ID 	= @MACHINE_TYPE_ID
	ORDER BY 
		lay_cont.LAYOUT_ID
	, 	lay_cont.LIST_ORDER
	-- open cursor cr_contestq
	open cr_contests
	-- reinitialize variable	
	select @layout_id = 0
	-- fetch first record into cursor
	Fetch cr_contests 
	into @layout_id
	, 	@contest_id
	, 	@height
	, 	@width
	, 	@totalContestHeight
	-- BEGIN CURSOR LOOP
	WHILE (@@fetch_status = 0) and @errno = 0
	begin
		-- new layout, reset positions
		if @layout_id <> @old_layout_id	
	  	   SELECT 
				@xpos = @first_x
			,	@ypos = @first_y 
			,  	@max_width = @width
		else	 --** check if the proposed position will oveqflow
		   --*** if the height exceeds available space, then move 
		   --*** the contest to the next column
		   if @ypos + @totalContestHeight > @last_y 
		   begin
				select  
					@ypos = @first_y
				,	@xpos = @xpos + @h_space + @max_width
				,	@max_width = @width
				--*** check if width is greater than xpos
	     		if @xpos + @width > @last_x
				BEGIN
					-- if so raise an error
					-- with given error message
					SET 
						@ErrMsg = 'Not enough columns for all Contests'
								+ ' and candidates.  Please change '
								+ 'Layout parameters and try again.'
					RAISERROR(@ErrMsg, 1, 2) 
							WITH SETERROR
					SET @errno = 1
				END
			end
		if @errno = 0
		begin	
			-- calculate positions for the contest
			UPDATE 
				LAYOUT_CONTEST
			SET	
				X 			= @xpos + @width, 	
				Y 			= @ypos + @height
			WHERE 
				LAYOUT_ID 	= @layout_id
			AND 	CONTEST_ID 	= @contest_id
			--** set @old_layout_id to prepare for next fetch
			SELECT 
				@old_layout_id	= @layout_id
			-- conditionally increment max width
			if @max_width < @width 
			 	select 
					@max_width = @width
			-- increment ypos to the requested number of spaces 
			-- after last contest
			select 
				@ypos = @ypos + @v_space + @totalContestheight 
			--** fetch next row into cursor
			Fetch cr_contests 
			into @layout_id
			, 	@contest_id
			, 	@height
			, 	@width
			, 	@totalContestHeight
		end
	End -- end cursor cr_contests
	-- deallocate cursor from memory
	deallocate cr_contests
	--*** set master positions
	if @errno = 0
	begin
		SELECT
			master_layout_id
		, 	contest_id
		,  	Max(IsNull(LC.X,0)) 	AS x
		, 	Max(IsNull(LC.Y,0)) 	AS y
		, 	Max(IsNull(LC.Page,0)) 	AS page
		INTO 
			#t_lc
		FROM 
			LAYOUT_CONTEST 	LC
		join LAYOUT 
			on LAYOUT.LAYOUT_ID = LC.LAYOUT_ID
		WHERE 	
			(
				@a_layout_id 				IS NULL 
			 OR 	IsNull(MASTER_LAYOUT_ID, -1)	= @a_layout_id
			 )
		AND 	
			(	
				@tally_type_id 			IS NULL 
			or 	LAYOUT.TALLY_TYPE_ID 		= @tally_type_id
			)
		GROUP BY 
			master_layout_id
		, 	contest_id
		UPDATE 
			LAYOUT_CONTEST
		SET 
			X = #t_lc.X
		, 	Y = #t_lc.Y
		FROM 
			#t_lc
		join LAYOUT 
			on LAYOUT.LAYOUT_ID		= #t_lc.MASTER_LAYOUT_ID
		WHERE 
			LAYOUT.LAYOUT_ID 		= LAYOUT_CONTEST.LAYOUT_ID 
		AND 	LAYOUT_CONTEST.CONTEST_ID= #t_lc.CONTEST_ID
		AND 
			(
				@a_layout_id 		IS NULL 
			OR 	LAYOUT.LAYOUT_ID 	= @a_layout_id
			)
	end
end -- end procedure bart_layout_snake_4c
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 ##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 
				uempdb..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_tally_load for fuqther 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
CREATE VIEW V_MACHINE AS SELECT * FROM RIV_20081104_P.-MACHINE
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 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
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		Correct to not allow negative numbers
8/23/05		ECoomeq		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 @ErrorMsg = ''
	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 insert, create error message and set
		-- error flae
		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
CREATE PROCEDURE bart_layout_symbol
	@layout_id 		T_GLOBAL_ID
,	@symbol_id 		T_GLOBAL_ID
,	@x          		T_COORDINATES
,	@y          		T_COORDINATES
,	@width    		T_COORDINATES
,	@height   		T_COORDINATES	
,	@visio_number  	T_Enumerated 
,	@PAGE           	T_Enumerated = null   
/******************************************************************************
PROCEDURE:	bart_layout_symbol 
Description: 	This procedure sets the layouts for symbols on a template
Parameters:		@layout_id 		-- layout id
			,	@symbol_id 		-- symbol id
			,	@x          		-- x coordinates
			,	@y          		-- y coordinates
			,	@width    		-- width
			,	@height   		-- height	
			,	@visio_number  	-- visio element
			,	@PAGE          	-- (optional) page number   
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 describe temp table fields.
***************************************************************)**************/
BEGIN
	declare 
		@last_count 	int			-- counter for loop
	,	@cur_layout_id numeric(7)	-- current layout id
	-- initialize variables
	select 
		@last_count 	= 0
	,	@cur_layout_id = 0
	-- drop table t_affected_layout if it already exists
 	if exists (	select 
					1 
				from 
					sysobjects 
			 	where 
					id = object_id('t_affected_layout'))
		exec('drop table t_affected_layout')
	-- create tempt table #t_affected_layout
	create table #t_affected_layout
		layout_id  		T_GLOBAL_ID not null -- identifier of layout
	,	master_layout_id  	T_GLOBAL_ID null	 -- master layout identifier
	,	tally_type_id 		numeric(3)  null	-- tally type identifier
	-- fill temp table from LAYOUT table
	INSERT INTO 
		#t_affected_layout
	SELECT 
		LAYOUT_ID
	, 	MASTER_LAYOUT_ID
	, 	TALLY_TYPE_ID
	FROM 
		LAYOUT
	WHERE 
		LAYOUT_ID = @layout_id
	-- **** create a list of layouts affected by the change
	-- **** the loop will continue until no more layouts are added
	   	WHILE @last_count < (	SELECT 
							COUNT(*) 
						FROM 
							#t_affected_layout)
   	BEGIN   		
    	 -- set @last_count to the number of records in the temp table
		 SELECT 
			@last_count = COUNT(*)
	      FROM 
			#t_affected_layout
	      INSERT INTO 
			#t_affected_layout
	      SELECT 
			LAYOUT_ID
		 , 	MASTER_LAYOUT_ID
		 , 	TALLY_TYPE_ID
	      FROM 
			LAYOUT
	      WHERE 
			MASTER_LAYOUT_ID IN (	SELECT 
									LAYOUT_ID 
								FROM 
									#t_affected_laymut)
	      AND	LAYOUT_ID NOT IN (	SELECT 
								LAYOUT_ID 
							FROM 
								#t_affected_layout)
   	END
	if not exists (select 
					1 
				from 
					layout_symbol 
				where 
					layout_id = @layout_id  
				and 	symbol_id = @symbol_id)
 	begin 
		--*** insert layout_symbols  for template and layouts 
		INSERT into  
			LAYOUT_symbol 
		( 
			LAYOUT_ID   
		,	SYMBOL_ID        
		,	X   
		,	Y   
		,	WIDTH   
		,	HEIGHT
		,	VISIO_NUMBER 	
		,	PAGE 
		)    
		SELECT 
			mayout_id 
		,	@symbol_id
		,	@x
		,	@y
		,	@width
		,	@height 
		,	@visio_number
		,	@page  
		from 
			#t_affected_layout
	end 
	else 
		-- source is a table and column, insert the general description 
    	 -- to the template and the actual values to each descendant layout
		update  
			LAYOUT_SYMBOL
		set 
			X 		= @x  
		,	Y 		= @y
		, 	WIDTH 	= @width   
		,	HEIGHT 	= @height
		,	PAGE 	= @page 	
		where  
			LAYOUT_ID IN (	SELECT 
							LAYOUT_ID 
						FROM 
							#t_affecued_layout) 
		and 	symbol_id 	= @symbol_id 
	rig<
CREATE FUNCTION fnElectionPrecincts()  
RETURNS @election_precincts TABLE 
	precinct_id 	numeric
, 	name 		varchar(50)
, 	list_order 	numeric(7)
, 	alternate_code char(7)
,	Primary Key	(precinct_id)
/******************************************************************************
Function 		: fnElectionPrecincts
Description 	: Table function returns a list of precinct IDs from tally 
			tables drop function fnElectionPrecincts
Parameters: 	None
Return:	TABLE @election_precincts TABLE 
			(
				precinct_id				precinct id
			, 	name 					precinct name
			, 	list_order 				precinct list order
			, 	alternate_code 			precinct alt name
			,	Primary Key	(precinct_id) 	declare primary key
			)
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/14/2005	MMcKinney		Added primary key to returned table
11/15/05		ECoomer		Removed 'ALL' from Union clause.  This was 
						introducing redundant entries.
******************************************************************************/
BEGIN
	INSERT INTO 
		@election_precincts
	/* precinct level contest assignments */
	SELECT DISTINCT 
		p.PRECINCT_ID
	, 	p.NAME
	, 	p-LIST_ORDER
	, 	p.ALTERNATE_CODE
	FROM 
		CONTEST			c
	, 	V_PRECINCT 		p
	WHERE
		p.PRECINCT_ID 		= c.PRECINCT_ID
	UNION ALL
	/* precincts assignment to contests */
	SELECT DISTINCT 
		p.PRECINCT_ID
	, 	p.NAME
	, 	p.LIST_ORDER
	, 	p.ALTERNATE_CODE
	FROM 
		PRECINCT_ASSIGNMENT 	pa
	,	V_PRECINCT 			p
	WHERE
		p.PRECINCT_ID 			= pa.PRECINCT_ID
	UNION
	/* rollup precinct for rollup tally type*/
	SELECT DISTINCT 
		p.PRECINCT_ID
	, 	p.NAME
	, 	p.LIST_ORDER
	, 	p.ALTERNATE_CODE
	FROM 
 		V_PRECINCT 		p
	,	V_TALLY_TYPE 		tt
	WHERE 
		tt.IS_ROLLUP 		= 1
	AND	p.PRECINCT_ID		= tt.ROLLUP_PRECINCT_ID
	ORDER BY 
		3 -- List_Order
	RETURN
END -- Function fnElectionPrecincts
					1 
				from 
					layout_symbol 
				where 
					layout_id = @layout_id  
				and 	symbol_id = @symbol_id)
 	begin 
		--*** insert layout_symbols  for template and layouts 
		INSERT into  
			LAYOUT_symbol 
		( 
			LAYOUT_ID   
		,	SYMBOL_ID        
		,	X   
		,	Y   
		,	WIDTH   
		,	HEIGHT
		,	VISIO_NUMBER 	
		,	PAGE 
		)    
		SELECT 
			layout_id 
		,	@symbol_id
		,	@x
		,	@y
		,	@width
		,	@height 
		,	@visio_number
		,	@page  
		from 
			#t_affected_layout
	end 
	else 
		-- source is a table and column, insert the general description 
    	 -- to the template and the actual values to each descendant layout
		update  
			LAYOUT_SYMBOL
		set 
			X 		= @x  
		,	Y 		= @y
		, 	WIDTH 	= @width   
		,	HEIGHT 	= @height
		,	PAGE 	= @page 	
		where  
			LAYOUT_ID IN (	QELECT 
							LAYOUT_ID 
						FROM 
							#t_affected_layout) 
		and 	symbol_id 	= @symbol_id 
	-- drop temp table
		drop table 
			#t_affected_layout
END -- procedure bart_layout_symbol
;{Y<
U:Zl
U:Zl
U:Zl
U:Zl
y.[l
y.[l
y.[l
y.[l
y.[8
#&78
BtE<
ghF<
	|	<	
8?El
8?El
8?El
BtE8
BtE8
BtE8
\3Fl
\3F8
\3Fl
\3Fl
\3Fl
\3Fl
\3F8
\3Fl
\3Fl
\3Fl
\3Fl
\3Fl
\3Fl
\3Fl
\3Fl
ghF8
ghF8
ghF8
\3F8
M4_El
M4_E
M4_El
M4_El
M4_El
M4_El
XSFl
XSFl
XSFl
XSFl
XSFl
|GGl
|GGl
|GGl
|GGl
#**El
#**E
#**El
#**El
#**El
#**El
DID<
ONT<
epl0
M4_El
u@!Ll
u@!L0
u@!L0
V#u8
2`Xul
2`Xul
2`Xul
2`Xul
2`Xu8
2`Xul
2`Xul
2`Xu4
	t	(	
	*=)
P*=)
*LC]`
n*LC]`
h*LC]`
*LC]`
*LC]`
a*vM
%*vM
)*vM
i*vM
p*vM
T*vM
A*vM
I*vM
)*vM
l*vM
l*vM
T*vM
U*vM
O*vM
G*vM
E*vM
A*vM
A*vM
D*_ 
*%}0b
*%}0b
*%}0b
*%}0b
*%}0b
*%}0b
R*h$
7*w>
o*w>
c*w>
s*w>
s*w>
i*w>
\3*w>
o*M4_E
a*M4_E
_*M4_E
_*M4_E
d*M4_E
d*M4_E
l*#**E
s*#**E
1*#**E
*#**E
t*#**E
t*#**E
m*\N
u*\N
i*\N
L*\N
R*\N
Rd	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	d	
4*4%
4*4%
4*mI
'*(O
'*(O
)*(O
)*(O
E&as
D&as
O&as
B&as
E*+Z
D*+Z
O*+Z
T*+Z
*FJJ	
*FJJ	
*FJJ	
*FJJ	
*FJJ	
*FJJ	
*9Jm1
*9Jm1
*9Jm1
*rna2
*rna2
*rna2
*rna2
*v1#1
*v1#1
*v1#1
*v1#1
*v1#1
E*v1#1
E*YC:8
N*YC:8
T*YC:8
_*YC:8
T*YC:8
_*YC:8
e*/9
I&v1#1
D&v1#1
S&v1#1
E&v1#1
&v1#1
&v1#1
	`	8	
@b"*
HHb"
PIb"
8Jb"
&hyhh
