SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[p_insert_lavorazione]
	@DOC_COD			UNIQUEIDENTIFIER OUTPUT
	,@PRA_COD			UNIQUEIDENTIFIER OUTPUT
	,@VEI_COD			UNIQUEIDENTIFIER OUTPUT
	,@CLI_COD			UNIQUEIDENTIFIER OUTPUT
	,@PRG_COUNTER		INT OUTPUT
	,@PRA_CUBOMAGN		NVARCHAR(25)
	,@PRA_STATO			NVARCHAR(50)
	,@PRA_DATA_ENTR		DATETIME
	,@PRA_DATA_PREVISTA_CONS	DATETIME
	,@VEI_DESCR			NVARCHAR(60)
	,@VEI_COLORE		NVARCHAR(30)
	,@VEI_TARGA			NVARCHAR(12)
	,@VEI_NUM_SMA		INT
	,@CLI_NOME_L		NVARCHAR(40)
	,@CLI_NOME_F		NVARCHAR(40)
	,@CLI_TEL			NVARCHAR(25)
	,@CLI_CELL			NVARCHAR(25)
	,@TLA_COD			INT
	,@REP_ORDER_NUMBER	TINYINT
	,@CLI_NOT_LOCKED	BIT
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

	---------------------------------------- START --------------------------------------------
	-- In caso di errore, blocca la transazione e la rende uncommittable.
	-- Se fosse OFF (il default) sarebbe fatta la ROLLBACK solo dei comandi falliti
	-- e non di tutta la transazione.
	SET XACT_ABORT ON

---------------------------------------- OPERAZIONI PRELIMINARI ---------------------------
	-- Variabile usata per eseguire la RAISERROR fuori dalla CATCH, in modo da entrare nella  
	-- catch del chiamante
	DECLARE @ErrorMessage NVARCHAR(4000);
	DECLARE @ErrorSeverity INT;
	DECLARE @ErrorState INT;
	DECLARE @ErrorLine INT;
	DECLARE @bError AS BIT
	SET @bError = 0

	BEGIN TRY
		BEGIN TRANSACTION
			DECLARE @VAL_COD					AS INT
			DECLARE @IVA_COD					AS INT
			DECLARE @CAT_COD					AS INT
			DECLARE @parm_sco_man_cs_perc		AS FLOAT
			DECLARE @parm_sco_mat_cs_perc		AS FLOAT
			DECLARE @parm_sco_ric_perc			AS FLOAT
			DECLARE @parm_stato_accordo			AS TINYINT
			DECLARE @parm_stato_certificazione	AS TINYINT
			DECLARE @parm_stato_calc_cso		AS TINYINT
			DECLARE @parm_stato_detr_sr			AS TINYINT
			DECLARE @parm_tipo_calcolo			AS TINYINT
			DECLARE @parm_stato_tempi_sr		AS TINYINT
			DECLARE @parm_stato_accessori		AS TINYINT
			DECLARE @parm_finitura_perc			AS TINYINT
			DECLARE @parm_finitura_max_ore		AS TINYINT
			DECLARE @parm_rifiuti_perc			AS FLOAT
			DECLARE @parm_rifiuti_max			AS SMALLMONEY
			DECLARE @parm_tempo_agg_ve_ms		AS FLOAT
			DECLARE @parm_tempo_agg_ve_ds		AS FLOAT
			DECLARE @parm_tempo_agg_ve_me		AS FLOAT
			DECLARE @parm_tempo_agg_ve_mi		AS FLOAT
			DECLARE @parm_tempo_agg_ve_pe		AS FLOAT
			DECLARE @parm_ele_sep_ore_ve		AS FLOAT
			DECLARE @parm_muc_ms_ge_elesep		AS SMALLMONEY
			DECLARE @parm_muc_ds_ge_elesep		AS SMALLMONEY
			DECLARE @parm_muc_me_ge_elesep		AS SMALLMONEY
			DECLARE @parm_muc_mi_ge_elesep		AS SMALLMONEY
			DECLARE @parm_muc_pe_ge_elesep		AS SMALLMONEY
			DECLARE @parm_muc_ms_l_elesep		AS SMALLMONEY
			DECLARE @parm_muc_ds_l_elesep		AS SMALLMONEY
			DECLARE @parm_muc_me_l_elesep		AS SMALLMONEY
			DECLARE @parm_muc_mi_l_elesep		AS SMALLMONEY
			DECLARE @parm_muc_pe_l_elesep		AS SMALLMONEY
			DECLARE @parm_sma_ms				AS SMALLMONEY
			DECLARE @parm_sma_ds				AS SMALLMONEY
			DECLARE @parm_sma_me				AS SMALLMONEY
			DECLARE @parm_sma_mi				AS SMALLMONEY
			DECLARE @parm_sma_pe				AS SMALLMONEY
			DECLARE @parm_sma_fondo				AS SMALLMONEY
			DECLARE @parm_sma_trasp				AS SMALLMONEY
			DECLARE @parm_muc_costo				AS SMALLMONEY
			DECLARE @parm_prep_tinta_ore		AS FLOAT
			DECLARE @parm_rifiuti_costo			AS SMALLMONEY
			DECLARE @parm_perc_var_tempi_sr		AS SMALLINT
			DECLARE @parm_perc_var_tempi_la		AS SMALLINT
			DECLARE @parm_perc_var_tempi_ve		AS SMALLINT
			DECLARE @parm_perc_var_tempi_me		AS SMALLINT
			DECLARE @parm_suppl_perc_ds			AS FLOAT
			DECLARE @parm_suppl_perc_me			AS FLOAT
			DECLARE @parm_suppl_perc_mi			AS FLOAT
			DECLARE @parm_suppl_perc_pe			AS FLOAT
			DECLARE @parm_perc_var_ric			AS SMALLINT
			DECLARE @parm_lucidatura_ore		AS FLOAT
			DECLARE @parm_pul_int_est_ore		AS FLOAT
			DECLARE @parm_costoh_car			AS SMALLMONEY
			DECLARE @parm_costoh_mec			AS SMALLMONEY
			DECLARE @parm_perc_cass_naz_prev	AS TINYINT
			DECLARE @parm_perc_rit_acc			AS TINYINT
			DECLARE @parm_stato_sfum_auto		AS TINYINT
			DECLARE @iva_aliq					AS INT
			DECLARE @voc_prezzo_iva				AS SMALLMONEY
			DECLARE @voc_iva					AS SMALLMONEY
		
			-- PRENDIAMO I PARAMETRI DI MANUTENZIONE GENERALE
			SELECT 
				@parm_sco_man_cs_perc		= parm_sco_man_cs_perc,
				@parm_sco_mat_cs_perc		= parm_sco_mat_cs_perc,
				@parm_sco_ric_perc			= parm_sco_ric_perc,
				@parm_stato_accordo			= parm_stato_accordo,
				@parm_stato_certificazione	= parm_stato_certificazione,
				@parm_stato_calc_cso		= parm_stato_calc_cso,
				@parm_stato_detr_sr			= parm_stato_detr_sr,
				@parm_tipo_calcolo			= parm_tipo_calcolo,
				@parm_stato_tempi_sr		= parm_stato_tempi_sr,
				@parm_stato_accessori		= parm_stato_accessori,
				@parm_finitura_perc			= parm_finitura_perc,
				@parm_finitura_max_ore		= parm_finitura_max_ore,
				@parm_rifiuti_perc			= parm_rifiuti_perc,
				@parm_rifiuti_max			= parm_rifiuti_max,
				@parm_tempo_agg_ve_ms		= parm_tempo_agg_ve_ms,
				@parm_tempo_agg_ve_ds		= parm_tempo_agg_ve_ds,
				@parm_tempo_agg_ve_me		= parm_tempo_agg_ve_me,
				@parm_tempo_agg_ve_mi		= parm_tempo_agg_ve_mi,
				@parm_tempo_agg_ve_pe		= parm_tempo_agg_ve_pe,
				@parm_ele_sep_ore_ve		= parm_ele_sep_ore_ve,
				@parm_muc_ms_ge_elesep		= parm_muc_ms_ge_elesep,
				@parm_muc_ds_ge_elesep		= parm_muc_ds_ge_elesep,
				@parm_muc_me_ge_elesep		= parm_muc_me_ge_elesep,
				@parm_muc_mi_ge_elesep		= parm_muc_mi_ge_elesep,
				@parm_muc_pe_ge_elesep		= parm_muc_pe_ge_elesep,
				@parm_muc_ms_l_elesep		= parm_muc_ms_l_elesep,
				@parm_muc_ds_l_elesep		= parm_muc_ds_l_elesep,
				@parm_muc_me_l_elesep		= parm_muc_me_l_elesep,
				@parm_muc_mi_l_elesep		= parm_muc_mi_l_elesep,
				@parm_muc_pe_l_elesep		= parm_muc_pe_l_elesep,
				@parm_sma_ms				= parm_sma_ms,
				@parm_sma_ds				= parm_sma_ds,
				@parm_sma_me				= parm_sma_me,
				@parm_sma_mi				= parm_sma_mi,
				@parm_sma_pe				= parm_sma_pe,
				@parm_sma_fondo				= parm_sma_fondo,
				@parm_sma_trasp				= parm_sma_trasp,
				@parm_muc_costo				= parm_muc_costo,
				@parm_prep_tinta_ore		= parm_prep_tinta_ore,
				@parm_rifiuti_costo			= parm_rifiuti_costo,
				@parm_perc_var_tempi_sr		= parm_perc_var_tempi_sr,
				@parm_perc_var_tempi_la		= parm_perc_var_tempi_la,
				@parm_perc_var_tempi_ve		= parm_perc_var_tempi_ve,
				@parm_perc_var_tempi_me		= parm_perc_var_tempi_me,
				@parm_suppl_perc_ds			= parm_suppl_perc_ds,
				@parm_suppl_perc_me			= parm_suppl_perc_me,
				@parm_suppl_perc_mi			= parm_suppl_perc_mi,
				@parm_suppl_perc_pe			= parm_suppl_perc_pe,
				@parm_perc_var_ric			= parm_perc_var_ric,
				@parm_lucidatura_ore		= parm_lucidatura_ore,
				@parm_pul_int_est_ore		= parm_pul_int_est_ore,
				@parm_costoh_car			= parm_costoh_car,
				@parm_costoh_mec			= parm_costoh_mec,
				@parm_perc_cass_naz_prev	= parm_perc_cass_naz_prev,
				@parm_perc_rit_acc			= parm_perc_rit_acc,
				@parm_stato_sfum_auto		= parm_stato_sfum_auto
			FROM parametri_manutenzione
			-- CHECK 'N ADJUST PARAMETRI DI MANUTENZIONE GENERALE
			IF	@parm_rifiuti_costo IS NULL
			BEGIN
				SET @parm_rifiuti_costo = 0
			END
			IF	@parm_muc_costo IS NULL
			BEGIN
				SET @parm_muc_costo = 0
			END
			IF	@parm_sma_fondo IS NULL
			BEGIN
				SET @parm_sma_fondo = 0
			END
			IF	@parm_sma_trasp IS NULL
			BEGIN
				SET @parm_sma_trasp = 0
			END
			IF	@parm_sma_ms IS NULL
			BEGIN
				SET @parm_sma_ms = 0
			END
			IF	@parm_sma_ds IS NULL
			BEGIN
				SET @parm_sma_ds = 0
			END
			IF	@parm_sma_me IS NULL
			BEGIN
				SET @parm_sma_me = 0
			END
			IF	@parm_sma_mi IS NULL
			BEGIN
				SET @parm_sma_mi = 0
			END
			IF	@parm_sma_pe IS NULL
			BEGIN
				SET @parm_sma_pe = 0
			END

			-- PRENDIAMO LA VALUTA PER NUOVA PRATICA/CONSUNTIVO
			SET @VAL_COD = (SELECT TOP 1 val_cod FROM valute)
		
			-- PRENDIAMO L'ALIQUOTA IVA
			SELECT @IVA_COD  = iva_cod,
				   @iva_aliq = iva_aliq 
				   FROM aliquote_iva WHERE iva_ordinaria = 1
			IF	NOT (@iva_aliq > 0)
			BEGIN
				SET @iva_aliq = 22
			END
			IF	NOT (@IVA_COD > 0)
			BEGIN
				SET @IVA_COD = 1
			END

			DECLARE @CLI_NOME VARCHAR(max)
			DECLARE @CLI_NOME_SIZE int
		
			SELECT @CLI_NOME_SIZE = character_maximum_length FROM information_schema.columns  
				WHERE table_name = 'clienti' AND column_name = 'cli_nome'

			SET @CLI_NOME = @CLI_NOME_L + ' ' + @CLI_NOME_F
			SET @CLI_NOME = LEFT(@CLI_NOME, @CLI_NOME_SIZE)

			IF	@CLI_COD = CAST(CAST(0 AS BINARY) AS UNIQUEIDENTIFIER) --'00000000-0000-0000-0000-000000000000'
			BEGIN
				-- NUOVO CLIENTE - Parametro in output passato dal chiamante
				SET @CLI_COD = NEWID()
				-- QUINDI, IN OGNI CASO, ANCHE NUOVO VEICOLO
				SET @VEI_COD = CAST(CAST(0 AS BINARY) AS UNIQUEIDENTIFIER)
			
				-- Prende dai parametri di contabilità il mastro di default per il conto clienti
				DECLARE @DEFAULT_MASTRO_ID AS INT
				SELECT @DEFAULT_MASTRO_ID = parcont_conto_clienti_default_mastro_id FROM parametri_contabilita
					WHERE parcont_tipo_cont = 5 -- UESSE (ParametriContabilita.h)

				-- Imposta un valore univoco per la chiave univoca cnt_codice (vincolo conti_UC1)
				DECLARE @NEW_CNT_ID_TEMP AS NVARCHAR(10)
				SET @NEW_CNT_ID_TEMP = RIGHT(CAST(CRYPT_GEN_RANDOM(10) AS BIGINT), 9)

				-- Inserisce il relativo conto avente come descrizione la ragione sociale del cliente e un mastro di default preso dai parametri di contabilità
				INSERT INTO conti
							(cnt_codice,		cnt_descr,		cnt_mas_id,			cnt_tipcnt_id)
					VALUES	(@NEW_CNT_ID_TEMP,	@CLI_NOME,	@DEFAULT_MASTRO_ID, 2) -- 2=tipo conto Clienti

				-- Legge la nuova identità
				DECLARE @NEW_CNT_ID AS INT
				SELECT @NEW_CNT_ID = SCOPE_IDENTITY()

				-- Forma il codice del conto per il cliente
				DECLARE @CNT_CODICE AS NVARCHAR(16)
				SET @CNT_CODICE = 'C'  + REPLICATE('0', 9 - LEN(CAST(@NEW_CNT_ID AS VARCHAR))) + CAST(@NEW_CNT_ID AS VARCHAR)

				-- Aggiorna il codice del conto usando la nuova identità
				UPDATE conti set cnt_codice = @CNT_CODICE 
					WHERE cnt_id = @NEW_CNT_ID

				-- Compone il nuovo cli_codice (per AdHoc)
				DECLARE @MAX_CLI_CODICE AS INT
				SELECT @MAX_CLI_CODICE = MAX(CAST(cli_codice as int)) FROM clienti WHERE cli_codice NOT LIKE '%[^0-9]%' -- Se cli_codice è numerico
				SET @MAX_CLI_CODICE = @MAX_CLI_CODICE + 1

				DECLARE @CLI_CODICE_NEXT AS NVARCHAR(10)
				SET @CLI_CODICE_NEXT = REPLICATE('0', 10 - LEN(CAST(@MAX_CLI_CODICE AS VARCHAR(10)))) + CAST(@MAX_CLI_CODICE AS VARCHAR(10))

				INSERT INTO clienti 
					(	cli_cod,		cli_codice,		cli_ultima_modifica,cli_nome,		cli_nome_f, 
						cli_nome_l,		cli_indi,		cli_cap,			cli_citta,		cli_prov,
						cli_nazione,	cli_tel, 		cli_tel2,			cli_fax,		cli_tel_cell,
						cli_email, 		cli_rec_iva,	cli_cod_fisc,		cli_part_iva,	cli_pers_fisi, 
						cli_sesso,		cli_nat_data,	cli_nat_com,		cli_nat_prov,	cli_ass_o_cp, 
						cli_ban_iban,	cli_ban_cc,		cli_ban_cin,		ban_cod,	 	prof_cod,		
						pag_cod,		cli_cnt_id
					) 
					VALUES	
					(	@CLI_COD,		@CLI_CODICE_NEXT,NULL,				@CLI_NOME,		@CLI_NOME_F, 
						@CLI_NOME_L,	'',				'',					'',				'', 
						'',				@CLI_TEL,		'',					'',				@CLI_CELL, 
						'',				2,				'',					'',				1, 
						' ',			NULL,			'',					'',				1, 
						'',				'',				'',					NULL,			NULL, 
						NULL,			@NEW_CNT_ID
					)
			END
			ELSE
			BEGIN
				IF	@CLI_NOT_LOCKED = 1
				BEGIN
					DECLARE @CLI_ASS_O_CP AS TINYINT
					SELECT @CLI_ASS_O_CP = cli_ass_o_cp FROM clienti
						WHERE cli_cod = @CLI_COD
					IF	@CLI_ASS_O_CP = 2
					BEGIN
						SET @CLI_ASS_O_CP = 3
					END
					UPDATE clienti SET cli_nome		= @CLI_NOME,
									   cli_nome_f	= @CLI_NOME_F,
									   cli_nome_l	= @CLI_NOME_L,
									   cli_tel		= @CLI_TEL,
									   cli_tel_cell = @CLI_CELL,
									   cli_ass_o_cp = @CLI_ASS_O_CP
						WHERE cli_cod = @CLI_COD
				END
			END
		
			-- N.B. I valori di default sono presi dal costruttore CVeicolo
			IF	@VEI_COD = CAST(CAST(0 AS BINARY) AS UNIQUEIDENTIFIER) --'00000000-0000-0000-0000-000000000000'
			BEGIN
				-- NUOVO VEICOLO - Parametro in output passato dal chiamante
				SET @VEI_COD = NEWID()
				INSERT INTO veicoli 
				(	vei_cod,		vei_ultima_modifica,mod_codice,			 ver_codice,		
					vei_num_sma,	vei_descr,			vei_vernice,		 vei_targa, 
					vei_telaio,		vei_num_motore,		vei_num_modello,	 vei_data_imma, 
					vei_imm_nazione,vei_assic,			vei_cod_impr,		 vei_ramo_poliz, 
					vei_num_poliz,	vei_cod_age,		vei_age_nome,		 vei_age_denom, 
					vei_age_indi,	vei_age_cap,		vei_age_citta,		 vei_age_prov, 
					vei_age_nazione,vei_age_tel,		vei_age_email,		 vei_tip_veic, 
					vei_pra_nome,	vei_pra_nome_f,		vei_pra_nome_l,		 vei_pra_ind, 
					vei_pra_cap,	vei_pra_citta,		vei_pra_prov,		 vei_pra_nazione, 
					vei_pra_tel,	vei_pra_email,		vei_pra_prof,		 vei_pra_cod_fisc, 
					vei_pra_part_iva,vei_pra_per_fisi,	vei_pra_sesso,		 vei_pra_nat_data,
					vei_pra_nat_com,vei_pra_nat_prov,	vei_pra_prop,		 vei_loc_nome, 
					vei_loc_nome_f, vei_loc_nome_l,		vei_loc_ind,		 vei_loc_cap, 
					vei_loc_citta,	vei_loc_prov,		vei_loc_nazione,	 vei_loc_tel, 
					vei_loc_email,	vei_loc_prof,		vei_loc_cod_fisc,	 vei_loc_part_iva, 
					vei_loc_per_fisi,vei_loc_sesso,		vei_loc_nat_data,	 vei_loc_nat_com, 
					vei_loc_nat_prov,vei_privil,		vei_data_scad_privil,vei_portata,
					vei_tara,		vei_passo,			vei_num_posti,		 vei_allestim, 
					vei_num_assi,	vei_gia_targa,		vei_cod_omolog,		 vei_rim_targa, 
					vei_rim_telaio, vei_rim_imm_nazione,cli_cod,			 mod_codice_etax, 
					ver_codice_etax
				) 
				VALUES 
				(	@VEI_COD, NULL, '', '', @VEI_NUM_SMA, @VEI_DESCR, @VEI_COLORE, @VEI_TARGA, '', '', '', NULL,
					'', '', '', 0, '', '', '', '', '', '', '', '', '', '', '', 0, '', '', 
					'', '', '', '', '', '', '', '', '', '', '', 1, ' ', NULL, '', '', 0, '', 
					'', '', '', '', '', '', '', '', '', '', '', '', 1, ' ', NULL, '', '', '', 
					NULL, 0, 0, 0.0, 0, '', 0, '', '', '', '', '', @CLI_COD, '', ''
				)
			END
			ELSE
			BEGIN
				UPDATE veicoli SET vei_descr = @VEI_DESCR,
								   vei_vernice = @VEI_COLORE,
								   vei_targa = @VEI_TARGA,
								   vei_num_sma = @VEI_NUM_SMA
					WHERE vei_cod = @VEI_COD
			END

			-- NUOVA PRATICA - Parametro in output passato dal chiamante
			-- N.B. I valori di default sono presi dal costruttore CPratica()
			SET @PRA_COD = NEWID()
			INSERT INTO pratiche 
			(	pra_cod,		pra_ultima_modifica,pra_rif_pra,		pra_inc_data, 
				pra_data_cons,	pra_data_acc1,		pra_data_acc2,		pra_data_peri_per, 
				pra_imp_ric,	pra_imp_liq,		pra_spese_acc,		pra_imp_conc, 
				pra_peri_nome,	pra_data_peri,		pra_data_entr,		pra_data_cons_pv, 
				pra_data_prevista_cons, pra_data_ini1, pra_data_ini2,	pra_data_fin1, 
				pra_data_fin2,	pra_num_ord_lav,	pra_data_ord_lav,	pra_num_pra_gar, 
				pra_anno_pra_gar, pra_cubo_magnetico, pra_numero_ordine,pra_riparaz, 
				pra_foto,		pra_num_foto,		pra_note_per_stampa,pra_note, 
				pra_stato_per,	pra_presso,			pra_presso_cod,		pra_presso_localita, 
				pra_rip_cod,	pra_rip_rag_soc,	pra_rip_tipol,		pra_rip_tar_banda_da, 
				pra_rip_tar_banda_a, pra_rip_tar_applic, pra_coerenza_danno, 
				pra_notula_si_no,pra_parc_riscossa, pra_perizia_risc,	pra_caso_cai, 
				pra_grado_cai,	pra_val_emu,		pra_prog_cp,		pra_imp_conc_con, 
				pra_pronta_liquid,pra_motivo_non_liquid,pra_rip_antiecon,pra_pneum, 
				pra_km,			pra_owner,			pra_stato,			vei_cod, 
				val_cod,		sin_cod,			per_cod,			car_cod,
				tla_cod,		rep_order_number,	pra_data_apertura
			)
			VALUES 
			(	@PRA_COD, NULL, '', NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, '', NULL, 
				-- pra_data_entr : prendiamo solo la parte DATE (intera) del DATETIME
				--CAST(FLOOR(CAST(GETDATE() AS float)) AS datetime),
				@PRA_DATA_ENTR,
				NULL, @PRA_DATA_PREVISTA_CONS, NULL, NULL, NULL, NULL, '', NULL, '', 0, @PRA_CUBOMAGN, '', 0, 0, 0,
				'', '', 0, '', 4, '', '', '', '', 0, 0, 0, 32, 0, 0, 0, '', 0, 1.0, 0, 0, 0, 0,
				0, 0.0, 0, 1, @PRA_STATO, @VEI_COD, @VAL_COD, NULL, 0, 0, @TLA_COD, @REP_ORDER_NUMBER,
				GETDATE()
			)

			INSERT INTO rel_pratiche 
						(pra_cod, pra_cod_vs)
				VALUES	(@PRA_COD, NULL)

			-- NUOVO PROGRESSIVO - Parametro in output passato dal chiamante
			--DECLARE @PRG_COUNTER AS INT
			IF NOT EXISTS(SELECT prg_progr FROM progressivi WHERE prg_doc_tipo = 1 AND prg_anno = YEAR(GETDATE()) AND prg_progr = '')
			BEGIN
				INSERT INTO progressivi 
						(prg_doc_tipo, prg_anno, prg_progr, prg_counter)
				VALUES	(1, YEAR(GETDATE()), '', 1)
				SET @PRG_COUNTER = 1
			END
			ELSE
			BEGIN
				SET @PRG_COUNTER = (SELECT prg_counter FROM progressivi WHERE prg_doc_tipo = 1 AND prg_anno = YEAR(GETDATE()) AND prg_progr = '') + 1
				UPDATE progressivi SET prg_counter = @PRG_COUNTER WHERE prg_doc_tipo = 1 AND prg_anno = YEAR(GETDATE()) AND prg_progr = ''
			END

			-- NUOVO CONSUNTIVO
			IF EXISTS (SELECT doc_cod FROM documenti WHERE doc_super_tipo = 1 AND doc_numero = @PRG_COUNTER AND doc_num_alt = '' AND YEAR(doc_data) = YEAR(GETDATE()))
			BEGIN
				-- RAISERROR con severity 11-19 fa eseguire il CATCH block
				RAISERROR ('Una lavorazione con lo stesso numero di quella che si vuole creare esiste gia''. Probabilmente occorre aggiornare il contatore progressivo dei consuntivi.', -- Message text.
						   16, -- Severity.
						   1 -- State.
						   );
			END
			ELSE
			BEGIN
				DECLARE @doc_tot_imponibile	AS SMALLMONEY
				DECLARE @doc_tot_imposta	AS SMALLMONEY
				DECLARE @doc_tot_generale	AS SMALLMONEY
				SET @doc_tot_imponibile = 0.0
				SET @doc_tot_imposta	= 0.0
				SET @doc_tot_generale	= 0.0
				IF	@parm_muc_costo > 0
				BEGIN
					-- AGGIUNGIAMO AI TOTALI LA VOCE MATERIALI
					SET @doc_tot_imponibile = @doc_tot_imponibile + @parm_muc_costo
					SET @doc_tot_imposta	= @doc_tot_imposta	  + (@parm_muc_costo * (@iva_aliq / 100.0))
					SET @doc_tot_generale	= @doc_tot_generale   + (@parm_muc_costo * ((100.0 + @iva_aliq) / 100.0))
				END
				IF	@parm_rifiuti_costo > 0
				BEGIN
					-- AGGIUNGIAMO AI TOTALI LA VOCE SMALTIMENTO RIFIUTI
					SET @doc_tot_imponibile = @doc_tot_imponibile + @parm_rifiuti_costo
					SET @doc_tot_imposta	= @doc_tot_imposta	  + (@parm_rifiuti_costo * (@iva_aliq / 100.0))
					SET @doc_tot_generale	= @doc_tot_generale   + (@parm_rifiuti_costo * ((100.0 + @iva_aliq) / 100.0))
				END
				-- IDENTITA' DOCUMENTO - Parametro in output passato dal chiamante
				SET @DOC_COD = NEWID()
				INSERT INTO documenti
				(	doc_cod,					doc_bound,						doc_tipo,			
					doc_super_tipo,				doc_tipo_doc_fisc,				doc_tipo_origine,
					doc_data,					doc_numero,						doc_num_alt,
					doc_num_reg,				doc_sco_perc_man,				doc_sco_perc_mat,
					doc_sco_perc_ric,			doc_arrotondamento_su_tot,		doc_stato_accordo,
					doc_stato_certificazione,	doc_stato_cso,					doc_stato_detrazioni_sr,
					doc_stato_ripar_ore_cons,	doc_stato_conf,					doc_stato_provv,
					doc_tipo_calcolo,			doc_stato_tempi_sr,				doc_stato_accessori,
					doc_tot_detrazioni,			doc_tot_imponibile,				doc_tot_imposta,	
					doc_tot_generale,			doc_tot_incassato,				doc_insuff_ass_imponibile,
					doc_insuff_ass_imposta,		doc_insuff_ass_totale,			doc_indenn_imponibile,
					doc_indenn_imposta,			doc_indenn_totale,				doc_franc_imponibile,
					doc_franc_imposta,			doc_franc_totale,				doc_tot_ard_imponibile,
					doc_tot_ard_imposta,		doc_tot_ard_totale,				doc_tot_ard_no_iva_mo_totale,
					doc_tot_indenn_contrattuale,doc_note,						doc_ordinamento,
					doc_finit_perc,				doc_finit_max,					doc_rifiuti_perc,
					doc_rifiuti_max,			doc_temp_agg_ve_ms,				doc_temp_agg_ve_ds,
					doc_temp_agg_ve_me,			doc_temp_agg_ve_mi,				doc_temp_agg_ve_pe,
					doc_elesep_ore_ve,			doc_parm_muc_ms_ge_elesep,		doc_parm_muc_ds_ge_elesep,
					doc_parm_muc_me_ge_elesep,	doc_parm_muc_mi_ge_elesep,		doc_parm_muc_pe_ge_elesep,
					doc_parm_muc_ms_l_elesep,	doc_parm_muc_ds_l_elesep,		doc_parm_muc_me_l_elesep,
					doc_parm_muc_mi_l_elesep,	doc_parm_muc_pe_l_elesep,		doc_prezzo_sma_ms,
					doc_prezzo_sma_ds,			doc_prezzo_sma_me,				doc_prezzo_sma_mi,
					doc_prezzo_sma_pe,			doc_prezzo_fondo,				doc_prezzo_trasparente,
					doc_muc,					doc_prep_tinta,					doc_rifiuti,
					doc_var_perc_sr,			doc_var_perc_la,				doc_var_perc_ve,
					doc_var_perc_me,			doc_var_perc_oreope_sr,			doc_var_perc_oreope_la,
					doc_var_perc_oreope_ve,		doc_var_perc_oreope_me,			doc_suppl_perc_ds,
					doc_suppl_perc_me,			doc_suppl_perc_mi,				doc_suppl_perc_pe,
					doc_var_perc_ric,			doc_lucidatura,					doc_pul_int_est,
					doc_costoh_car,				doc_costoh_mec,					doc_perc_cassa_naz_prev,
					doc_perc_rit_acconto,		doc_val_emu,					val_cod_display,
					doc_val_display_emu,		doc_contabil,					pag_cod,
					pra_cod,					val_cod,						doc_tot_sr,
					doc_tot_la,					doc_tot_ve,						doc_tot_me,
					doc_suppl_perc_sma_ds,		doc_finit,						doc_temp_agg_ve,
					doc_tot_tempi_suppl,		doc_tot_tempi_ve,				doc_tot_imponibile_ex_degr,
					doc_tot_ric_degr,			doc_tot_ric_ex_degr_imponibile,	doc_tot_ric_ex_degr_iva,
					doc_tot_ric_ex_degr_totale,	doc_tot_ric_imponibile,			doc_tot_ric_iva,
					doc_tot_ric_totale,			doc_tot_mat_imponibile,			doc_tot_mat_iva,
					doc_tot_mat_totale,			doc_tot_uso_dim_imponibile,		doc_tot_uso_dim_iva,
					doc_tot_uso_dim_totale,		doc_tot_man_car_imponibile,		doc_tot_man_car_iva,
					doc_tot_man_car_totale,		doc_tot_man_mec_imponibile,		doc_tot_man_mec_iva,
					doc_tot_man_mec_totale,		doc_tot_ore_man_car,			doc_tot_ore_man_mec,
					doc_peri_tipo,				cau_cod,						doc_stato_sfum_auto,
					doc_ver_codice_altro_vei,	doc_banca,						doc_locked
				)
				VALUES
				(	@DOC_COD,					1,								104, 
					1,							0,								0, 
					-- doc_data : prendiamo solo la parte DATE (intera) del DATETIME
					CAST(FLOOR(CAST(GETDATE() AS float)) AS datetime),	@PRG_COUNTER, '',	
					0,							@parm_sco_man_cs_perc,			@parm_sco_mat_cs_perc, 
					@parm_sco_ric_perc,			0.0,							@parm_stato_accordo,
					@parm_stato_certificazione,	@parm_stato_calc_cso,			@parm_stato_detr_sr, 
					0,							0,								0, 
					@parm_tipo_calcolo,			@parm_stato_tempi_sr,			@parm_stato_accessori, 
					0,							@doc_tot_imponibile,			@doc_tot_imposta, 
					@doc_tot_generale,			0.0,							0.0,	
					0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, '', 32, 
					@parm_finitura_perc,		@parm_finitura_max_ore,			@parm_rifiuti_perc, 
					@parm_rifiuti_max,			@parm_tempo_agg_ve_ms,			@parm_tempo_agg_ve_ds, 
					@parm_tempo_agg_ve_me,		@parm_tempo_agg_ve_mi,			@parm_tempo_agg_ve_pe, 
					@parm_ele_sep_ore_ve,		@parm_muc_ms_ge_elesep,			@parm_muc_ds_ge_elesep, 
					@parm_muc_me_ge_elesep,		@parm_muc_mi_ge_elesep,			@parm_muc_pe_ge_elesep, 
					@parm_muc_ms_l_elesep,		@parm_muc_ds_l_elesep,			@parm_muc_me_l_elesep,
					@parm_muc_mi_l_elesep,		@parm_muc_pe_l_elesep,			@parm_sma_ms, 
					@parm_sma_ds,				@parm_sma_me,					@parm_sma_mi, 
					@parm_sma_pe,				@parm_sma_fondo,				@parm_sma_trasp, 
					@parm_muc_costo,			@parm_prep_tinta_ore,			@parm_rifiuti_costo, 
					@parm_perc_var_tempi_sr,	@parm_perc_var_tempi_la,		@parm_perc_var_tempi_ve, 
					@parm_perc_var_tempi_me,	0,								0, 
					0,							0,								@parm_suppl_perc_ds, 
					@parm_suppl_perc_me,		@parm_suppl_perc_mi,			@parm_suppl_perc_pe, 
					@parm_perc_var_ric,			@parm_lucidatura_ore,			@parm_pul_int_est_ore, 
					@parm_costoh_car,			@parm_costoh_mec,				@parm_perc_cass_naz_prev, 
					@parm_perc_rit_acc,			1,								0, 
					1,							0,								NULL, 
					@PRA_COD,					@VAL_COD,						0.0, 
					0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
					0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0,	NULL, 
					@parm_stato_sfum_auto,	'', '', 0
				)
			END
			IF	@parm_muc_costo > 0
			BEGIN
				-- CALCOLI PER VOCE MATERIALI
				SET @voc_prezzo_iva = @parm_muc_costo * ((100.0 + @iva_aliq) / 100.0)
				SET @voc_iva = @parm_muc_costo * (@iva_aliq / 100.0)
				-- PRENDIAMO LA 1ma CATEGORIA DI TIPO MATERIALI
				SELECT TOP 1 @CAT_COD = cat_cod FROM categorie where cat_tipo = 1
				INSERT INTO voci
				(	voc_tipo,				voc_descr,				voc_prezzo,			voc_prezzo_iva,
					voc_aliq,				voc_sconto_perc,		voc_qta,			voc_unita_misura,
					voc_imponibile,			voc_iva,				voc_totale,			voc_qta_lav,
					voc_cod_costr,			voc_diff_sr,			voc_diff_la,		voc_diff_ve,
					voc_tempo_sr,			voc_tempo_la,			voc_tempo_ve,		voc_tempo_me,
					voc_detr_sr,			voc_peso_v,				voc_peso_t,			voc_peso_f,
					mod_codice,				ver_codice,				par_codice,			acc_codice,
					tippar_codice,			grp_cod,				voc_modificata,		com_cod,
					voc_forma_cso,			voc_tipo_inserimento,	voc_origine_ricambio,
					voc_stato_ordine,		ope_key,				voc_ope_data,		att_ope_key,
					attbase_cod,			iva_cod_doc_provv,		voc_aliq_doc_provv,	voc_iva_doc_provv,
					voc_tot_doc_provv,		voc_prog_ord_ute,		voc_num_divis,		voc_inclusa,
					doc_cod,				doc_cod_rif,			iva_cod,			cat_cod,
					voc_cod_costr_alt,		voc_descr_alt,			voc_prezzo_alt,		voc_doc_tipo_rif,
					voc_doc_super_tipo_rif,	voc_doc_tipo_doc_fisc_rif,					voc_doc_tipo_origine_rif,
					voc_doc_data_rif,		voc_doc_numero_rif,							voc_doc_num_alt_rif,
					voc_doc_tot_imponibile_rif,	voc_doc_tot_imposta_rif,				voc_doc_tot_generale_rif
				)
				VALUES
				(
					25,			'Materiali di uso e consumo',		@parm_muc_costo,	@voc_prezzo_iva,
					@iva_aliq,				@parm_sco_mat_cs_perc,	1,					0,
					@parm_muc_costo,		@voc_iva,				@voc_prezzo_iva,	0,
					'',						'',						'',					'',
					0.0,					0.0,					0.0,				0.0,
					0.0,					0.0,					0.0,				0.0,
					'',						'',						'',					'',
					'',						0,						32,					0,
					0,						'',						'',					
					'',						NULL,					NULL,				NULL,
					1,						0,						0,					0.0,
					0.0,					0,						0,					0,
					@DOC_COD,				NULL,					@IVA_COD,			@CAT_COD,
					'',						'',						0.0,				0,
					0,						0,						0,
					NULL,					0,						'',
					0.0,					0.0,					0.0
				)
			END
			IF	@parm_rifiuti_costo > 0
			BEGIN
				-- IMPOSTIAMO IL PROGRESSIVO PER L'ORDINAMENTO
				DECLARE @voc_prog_ord_ute	AS INT
				SET @voc_prog_ord_ute = 0
				IF	@parm_muc_costo > 0
				BEGIN
					SET @voc_prog_ord_ute = 1
				END			
				-- CALCOLI PER VOCE SMALTIMENTO RIFIUTI
				SET @voc_prezzo_iva = @parm_rifiuti_costo * ((100.0 + @iva_aliq) / 100.0)
				SET @voc_iva = @parm_rifiuti_costo * (@iva_aliq / 100.0)
				-- PRENDIAMO LA 1ma CATEGORIA DI TIPO VOCI COMPLEMENTARI
				SELECT TOP 1 @CAT_COD = cat_cod FROM categorie where cat_tipo = 3
				INSERT INTO voci
				(	voc_tipo,				voc_descr,				voc_prezzo,			voc_prezzo_iva,
					voc_aliq,				voc_sconto_perc,		voc_qta,			voc_unita_misura,
					voc_imponibile,			voc_iva,				voc_totale,			voc_qta_lav,
					voc_cod_costr,			voc_diff_sr,			voc_diff_la,		voc_diff_ve,
					voc_tempo_sr,			voc_tempo_la,			voc_tempo_ve,		voc_tempo_me,
					voc_detr_sr,			voc_peso_v,				voc_peso_t,			voc_peso_f,
					mod_codice,				ver_codice,				par_codice,			acc_codice,
					tippar_codice,			grp_cod,				voc_modificata,		com_cod,
					voc_forma_cso,			voc_tipo_inserimento,	voc_origine_ricambio,
					voc_stato_ordine,		ope_key,				voc_ope_data,		att_ope_key,
					attbase_cod,			iva_cod_doc_provv,		voc_aliq_doc_provv,	voc_iva_doc_provv,
					voc_tot_doc_provv,		voc_prog_ord_ute,		voc_num_divis,		voc_inclusa,
					doc_cod,				doc_cod_rif,			iva_cod,			cat_cod,
					voc_cod_costr_alt,		voc_descr_alt,			voc_prezzo_alt,		voc_doc_tipo_rif,
					voc_doc_super_tipo_rif,	voc_doc_tipo_doc_fisc_rif,					voc_doc_tipo_origine_rif,
					voc_doc_data_rif,		voc_doc_numero_rif,							voc_doc_num_alt_rif,
					voc_doc_tot_imponibile_rif,	voc_doc_tot_imposta_rif,				voc_doc_tot_generale_rif
				)
				VALUES
				(
					31,			'Smaltimento rifiuti',				@parm_rifiuti_costo,@voc_prezzo_iva,
					@iva_aliq,				0.0,					1,					0,
					@parm_rifiuti_costo,	@voc_iva,				@voc_prezzo_iva,	0,
					'',						'',						'',					'',
					0.0,					0.0,					0.0,				0.0,
					0.0,					0.0,					0.0,				0.0,
					'',						'',						'',					'',
					'',						0,						32,					0,
					0,						'',						'',					
					'',						NULL,					NULL,				NULL,
					1,						0,						0,					0.0,
					0.0,					@voc_prog_ord_ute,		0,					0,
					@DOC_COD,				NULL,					@IVA_COD,			@CAT_COD,
					'',						'',						0.0,				0,
					0,						0,						0,
					NULL,					0,						'',
					0.0,					0.0,					0.0
				)
			END
		COMMIT TRANSACTION
	END TRY
	BEGIN CATCH
		-- N.B. Gli errori con una gravità minore o uguale a 10 sono considerati 
		--      avvisi o messaggi informativi e non vengono gestiti dai blocchi TRY...CATCH. 
		SET @bError = 1
		-- N.B. ERROR_MESSAGE(), ERROR_LINE() ecc. sono utilizzabili solo nel blocco CATCH. 
		SELECT @ErrorMessage = ERROR_MESSAGE(),
			   @ErrorLine = ERROR_LINE(),
			   @ErrorSeverity = ERROR_SEVERITY(),
			   @ErrorState = ERROR_STATE();
		SET @ErrorMessage = @ErrorMessage + ' Linea: ' + CONVERT(VARCHAR(10), @ErrorLine)
		IF	XACT_STATE() = -1 -- Se Transazione bloccata e uncommittable
		BEGIN
			ROLLBACK TRANSACTION
		END	
		IF	XACT_STATE() = 1 -- Transazione committable
		BEGIN
			COMMIT TRANSACTION
			SET @ErrorMessage = @ErrorMessage + ' MEMORIZZAZIONE COMUNQUE EFFETTUATA!'
		END	
		-- Se XACT_STATE() = 0 significa che non c'è nessuna transazione e una COMMIT
		-- o una ROLLBACK fallirebbero

		-- N.B. RAISERROR può generare errori con contesto compreso esclusivamente 
		--      tra 1 e 127. Il Motore di database può generare errori con contesto 0.
		--      Quindi controlliamo.
		IF	@ErrorState < 1
		OR  @ErrorState > 127
		BEGIN
			SET @ErrorState = 1
		END
	END CATCH

	-- Resetta lo stato al valore di default.
	SET XACT_ABORT OFF

	SET NOCOUNT OFF

	IF	@bError = 1
	BEGIN
		-- N.B. RAISERROR può generare errori con contesto compreso esclusivamente 
		--      tra 1 e 127. Il Motore di database può generare errori con contesto 0.
		--      Quindi controlliamo.
		IF	@ErrorState < 1
		OR  @ErrorState > 127
		BEGIN
			SET @ErrorState = 1
		END
		--RAISERROR('Trovati errori', 11, 1)
		-- Ritorniamo al chiamante le informazioni originali relative all'errore che ha causato
		-- l'esecuzione del CATCH block.
		RAISERROR (@ErrorMessage, -- Message text.
				   @ErrorSeverity, -- Severity.
				   @ErrorState -- State.
				   )
	END

	RETURN 0
---------------------------------------- THE END ----------------------------------------
END

GO
