RSS Feed!

About me

I am a business intelligence developer working at Bizware since August 2015. In this blog I will present code samples, primarilly in tsql but also findings in all other parts of the Microsoft BI-stack.


Disclaimer: All code should be considered as "as-is", i.e. badly tested and not working until extensive testing have been made by anyone reading the code. :)


Happy coding!

Archive for the ‘Server’ Category

SQL Everyday – beräkna bostadskostnad och nettokapital

Sunday, July 13th, 2014

Hej!

Här om dagen skapade jag en stored procedure för att räkna ut bostadskostnaden mellan en hyresrätt och bostadsrätt, då jag stod i valet och kvalet om vad jag ville köpa eller hyra lägenhet.  Det finns självklart andra överväganden som inte kan tas med i beräkningen; läge, standard, utrustning, utsikt, intresse av renovering/inredning och mycket annat. Sen kanske man inte alltid kan välja, men om man kan välja kan denna sql-procedur hjälpa dig att få en översikt om hur kostnader, men också nettokapital förändras över en längre tid. Nettokapitalet bygger på sparande i sparkonto, värdepapper och bostadsvärde och räknas även det ut i proceduren.

För att få rätt data in i proceduren och inte ge någon slags översvämning i antalet inputparametrar så har jag lagt delar av dessa variabler i två styrtabeller: bostad och scenario. Bostadstabellen bygger på förväntade kostnader, ursprungsvärderingar och insatser. Eftersom ingen vet hur börsen, räntan, inflationen och värderingar ändras över tid så kan man behöva spela upp flera scenarion, detta läggs i scenariotabellen.

Bostad

CREATE TABLE [dbo].[Bostad](
[BostadId] [int] IDENTITY(1,1) NOT NULL,
[BostadNamn] [varchar](100) NULL,
[TypAvBostad] [varchar](20) NULL,
[BostadInköpskostnad] [money] NULL,
[BostadInsats] [money] NULL,
[NettoInkomstPerMånad] [money] NULL,
[HyraEllerAvgiftPerMånad] [money] NULL,
[ÖverlåtelseAvgift] [money] NULL,
[MäklarArvodeIProcentVidFörsäljning] [money] NULL,
[AvdragIProcentVidFörsäljning] [decimal](6, 2) NULL,
[UnderhållPerMånad] [money] NULL,
[VinstavdragIProcent] [decimal](6, 2) NULL,
[AmorteringPerMånad] [money] NULL,
[SparandeSparkontoInsats] [money] NULL,
[SparandeMånadssparProcentPerNettoAllt] [money] NULL,
[AktierInsats] [money] NULL,
[AktierMånadssparProcentPerNettoAllt] [money] NULL,
[FonderInsats] [money] NULL,
[FonderMånadssparProcentPerNettoAllt] [money] NULL,
[ElperMånad] [money] NULL,
[FörsäkringperMånad] [money] NULL,
[BredbandperMånad] [money] NULL,
[TvperMånad] [money] NULL,
[MatPerMånad] [money] NULL,
[ÖvrigaUtgifterPerMånad] [money] NULL,
[RänteAvdragIProcentPerÅr] [decimal](6, 2) NULL,
CONSTRAINT [PK_Bostad] PRIMARY KEY CLUSTERED
(
[BostadId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

Scenario

CREATE TABLE [dbo].[Scenario](
[ScenarioId] [int] IDENTITY(1,1) NOT NULL,
[ScenarioKod] [varchar](10) NOT NULL,
[StartÅr] [int] NULL,
[SlutÅr] [int] NULL,
[InflationProcentPerÅr] [decimal](6, 3) NULL,
[VärdeFörändringProcentPerÅr] [decimal](6, 3) NULL,
[NettoInkomstFörändringProcentPerÅr] [decimal](6, 3) NULL,
[RänteAvdragProcentPerÅr] [decimal](6, 3) NULL,
[RäntaProcentPerÅr] [decimal](6, 3) NULL,
[AktieFörändringProcentPerÅr] [decimal](6, 3) NULL,
[FonderFörändringProcentPerÅr] [decimal](6, 3) NULL,
[SparkontoFörändringProcentPerÅr] [decimal](6, 3) NULL,
PRIMARY KEY CLUSTERED
(
[ScenarioId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


Vi sätter in lite dummydata för att få två bostadsalternativ med en relativt hög sparkvot i bostadstabellen:

INSERT INTO [MISC].[dbo].[Bostad]
([BostadNamn]
,[TypAvBostad]
,[BostadInköpskostnad]
,[BostadInsats]
,[NettoInkomstPerMånad]
,[HyraEllerAvgiftPerMånad]
,[ÖverlåtelseAvgift]
,[MäklarArvodeIProcentVidFörsäljning]
,[AvdragIProcentVidFörsäljning]
,[UnderhållPerMånad]
,[AmorteringPerMånad]
,[SparandeSparkontoInsats]
,[SparandeMånadssparProcentPerNettoAllt]
,[AktierInsats]
,[AktierMånadssparProcentPerNettoAllt]
,[FonderInsats]
,[FonderMånadssparProcentPerNettoAllt]
,[ElperMånad]
,[FörsäkringperMånad]
,[BredbandperMånad]
,[TvperMånad]
,[MatPerMånad]
,[ÖvrigaUtgifterPerMånad])
VALUES
(
'storgatan 1, 53 kvm',--<BostadNamn, varchar(100),> -- Namnet på bostaden
'Bostadsrätt',--,<TypAvBostad, varchar(20),> -- villa, bostadsrätt, hyresrätt
1800000,--,<BostadInköpskostnad, money,> -- Inköpskostnaden för villa och bostadsrätt i lokal valuta
270000,--,<BostadInsats, money,> -- Insatsen i lokal valuta
18000,--,<NettoInkomstPerMånad, money,> -- Inkomsten efter skatteavdrag (inkl. även andra bidrag netto)
3000,--,<HyraEllerAvgiftPerMånad, money,> -- hyresrätt: månadshyra, bostadrätt: avgift, villa: schablonskatt? eller 0
1000,--,<ÖverlåtelseAvgift, money,> -- kostnad vid inflyttning: hyresrätt: avgifter till förmedlare, bostadsrätt: pant, villa: pantbrev etc
2.5,--,<MäklarArvodeIProcentVidFörsäljning, money,> -- vid brf och hyresrätt
22,--,<AvdragIProcentVidFörsäljning, decimal(6,2),> -- reavinstskatt i %
1500,--,<UnderhållPerMånad, money,> -- underhåll per månad exkl renovering. 0 för hyresrätt, ca 750-2000 för brf, 2000-5000 för villa, något lägre för radhus.
2500,--,<AmorteringPerMånad, money,> -- för brf/villa: amortering på lånet (räknas INTE som kostnad i senare skede, då amortering är ett sorts sparande)
25000,--,<SparandeSparkontoInsats, money,> -- saldo på sparkontot i början av beräkningen, behöver inte användas
60,--,<SparandeMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på sparkonto
10000,--,<AktierInsats, money,> -- saldo på ISK/KF/VP-depå i början av beräkningen (för aktier), behöver inte användas
40,--,<AktierMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på ISK/KF/VP-depå
0,--,<FonderInsats, money,> -- saldo på ISK/KF/VP-depå i början av beräkningen (för fonder), behöver inte användas
0,--,<FonderMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på ISK/KF/VP-depå (för fonder), behöver inte användas
300,--,<ElperMånad, money,> -- kostnaden för el per månad
200,--,<FörsäkringperMånad, money,> -- kostnaden för försäkringar per månad relaterade till huset, familjeförsäkring
300,--,<BredbandperMånad, money,> -- kostnaden för bredband per månad (inkluderar även hemtelefoni)
200,--,<TvperMånad, money,> -- kostnaden för tv per månad (inklusive tv-avgift)
1500,--,<MatPerMånad, money,> -- kostnaden för mat per månad
2000--,<ÖvrigaUtgifterPerMånad, money,> -- kostnaden för andra utgifter per månad
)
,
(
'villavägen 1, 150 kvm',--<BostadNamn, varchar(100),> -- Namnet på bostaden
'Villa',--,<TypAvBostad, varchar(20),> -- villa, bostadsrätt, hyresrätt
3800000,--,<BostadInköpskostnad, money,> -- Inköpskostnaden för villa och bostadsrätt i lokal valuta
670000,--,<BostadInsats, money,> -- Insatsen i lokal valuta
36000,--,<NettoInkomstPerMånad, money,> -- Inkomsten efter skatteavdrag (inkl. även andra bidrag netto)
500,--,<HyraEllerAvgiftPerMånad, money,> -- hyresrätt: månadshyra, bostadrätt: avgift, villa: schablonskatt? eller 0
100000,--,<ÖverlåtelseAvgift, money,> -- kostnad vid inflyttning: hyresrätt: avgifter till förmedlare, bostadsrätt: pant, villa: pantbrev etc
2.5,--,<MäklarArvodeIProcentVidFörsäljning, money,> -- vid brf och hyresrätt
22,--,<AvdragIProcentVidFörsäljning, decimal(6,2),> -- reavinstskatt i %
4500,--,<UnderhållPerMånad, money,> -- underhåll per månad exkl renovering. 0 för hyresrätt, ca 750-2000 för brf, 2000-5000 för villa, något lägre för radhus.
5000,--,<AmorteringPerMånad, money,> -- för brf/villa: amortering på lånet (räknas INTE som kostnad i senare skede, då amortering är ett sorts sparande)
50000,--,<SparandeSparkontoInsats, money,> -- saldo på sparkontot i början av beräkningen, behöver inte användas
50,--,<SparandeMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på sparkonto
30000,--,<AktierInsats, money,> -- saldo på ISK/KF/VP-depå i början av beräkningen (för aktier), behöver inte användas
50,--,<AktierMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på ISK/KF/VP-depå
0,--,<FonderInsats, money,> -- saldo på ISK/KF/VP-depå i början av beräkningen (för fonder), behöver inte användas
0,--,<FonderMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på ISK/KF/VP-depå (för fonder), behöver inte användas
700,--,<ElperMånad, money,> -- kostnaden för el per månad
400,--,<FörsäkringperMånad, money,> -- kostnaden för försäkringar per månad relaterade till huset, familjeförsäkring
600,--,<BredbandperMånad, money,> -- kostnaden för bredband per månad (inkluderar även hemtelefoni)
400,--,<TvperMånad, money,> -- kostnaden för tv per månad (inklusive tv-avgift)
5000,--,<MatPerMånad, money,> -- kostnaden för mat per månad
7000--,<ÖvrigaUtgifterPerMånad, money,> -- kostnaden för andra utgifter per månad
)

GO

och lite data i scenario-tabellen:

INSERT INTO [MISC].[dbo].[Scenario]
([ScenarioKod]
,[StartÅr]
,[SlutÅr]
,[InflationProcentPerÅr]
,[VärdeFörändringProcentPerÅr]
,[NettoInkomstFörändringProcentPerÅr]
,[RänteAvdragProcentPerÅr]
,[RäntaProcentPerÅr]
,[AktieFörändringProcentPerÅr]
,[FonderFörändringProcentPerÅr]
,[SparkontoFörändringProcentPerÅr])
VALUES
(
'Scenario1', --<ScenarioKod, varchar(10),> -- Namn på scenario
0, --,<StartÅr, int,> -- startår för raden
3, --,<SlutÅr, int,> -- slutår för raden
1, --,<InflationProcentPerÅr, decimal(6,3),>
4, --,<VärdeFörändringProcentPerÅr, decimal(6,3),>
2, --,<NettoInkomstFörändringProcentPerÅr, decimal(6,3),>
30, --,<RänteAvdragProcentPerÅr, decimal(6,3),>
2.5, --,<RäntaProcentPerÅr, decimal(6,3),>
5, --,<AktieFörändringProcentPerÅr, decimal(6,3),>
5, --,<FonderFörändringProcentPerÅr, decimal(6,3),>
1--,<SparkontoFörändringProcentPerÅr, decimal(6,3),>
),
(
'Scenario1', --<ScenarioKod, varchar(10),> -- Namn på scenario
4, --,<StartÅr, int,> -- startår för raden
6, --,<SlutÅr, int,> -- slutår för raden
3, --,<InflationProcentPerÅr, decimal(6,3),>
-3, --,<VärdeFörändringProcentPerÅr, decimal(6,3),>
4, --,<NettoInkomstFörändringProcentPerÅr, decimal(6,3),>
20, --,<RänteAvdragProcentPerÅr, decimal(6,3),>
5.5, --,<RäntaProcentPerÅr, decimal(6,3),>
-4, --,<AktieFörändringProcentPerÅr, decimal(6,3),>
-3, --,<FonderFörändringProcentPerÅr, decimal(6,3),>
5--,<SparkontoFörändringProcentPerÅr, decimal(6,3),>
),
(
'Scenario1', --<ScenarioKod, varchar(10),> -- Namn på scenario
7, --,<StartÅr, int,> -- startår för raden
12, --,<SlutÅr, int,> -- slutår för raden
4, --,<InflationProcentPerÅr, decimal(6,3),>
1, --,<VärdeFörändringProcentPerÅr, decimal(6,3),>
5, --,<NettoInkomstFörändringProcentPerÅr, decimal(6,3),>
10, --,<RänteAvdragProcentPerÅr, decimal(6,3),>
6.5, --,<RäntaProcentPerÅr, decimal(6,3),>
7, --,<AktieFörändringProcentPerÅr, decimal(6,3),>
6, --,<FonderFörändringProcentPerÅr, decimal(6,3),>
5--,<SparkontoFörändringProcentPerÅr, decimal(6,3),>
),
(
'Scenario1', --<ScenarioKod, varchar(10),> -- Namn på scenario
13, --,<StartÅr, int,> -- startår för raden
20, --,<SlutÅr, int,> -- slutår för raden
2.5, --,<InflationProcentPerÅr, decimal(6,3),>
3, --,<VärdeFörändringProcentPerÅr, decimal(6,3),>
4, --,<NettoInkomstFörändringProcentPerÅr, decimal(6,3),>
0, --,<RänteAvdragProcentPerÅr, decimal(6,3),>
5.5, --,<RäntaProcentPerÅr, decimal(6,3),>
7, --,<AktieFörändringProcentPerÅr, decimal(6,3),>
7, --,<FonderFörändringProcentPerÅr, decimal(6,3),>
3--,<SparkontoFörändringProcentPerÅr, decimal(6,3),>
)

GO

Stored procedure

-- =============================================
-- Author: Robin Langell		
-- Create date: 2014-06-08
-- Description:	Räknar ut bostadskostnader
-- =============================================
CREATE PROCEDURE [dbo].[usp_BostadsKostnad]
	@BostadId1 int = 1,-- första bostadid,
	@BostadId2 int = 2,-- andra bostadid,
	@PeriodAntalÅr int = 15,
	@PeriodStart date = '2014-08-01',
	@InkluderaBostadFörsäljningKostnaderOchVinsterFlagga int = 1,
	@ScenarioKod varchar(10) = 'A'
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

    -- Pseudokod:
    -- hämta all info från tabellen. (id)
    SELECT
      RadNr = ROW_NUMBER() OVER (ORDER BY (SELECT NULL) )
      ,[BostadId]
      ,[BostadNamn]
      ,[TypAvBostad]
      ,[BostadInköpskostnad]
      ,[BostadInsats]
      ,[NettoInkomstPerMånad]
      ,[HyraEllerAvgiftPerMånad]
      ,[ÖverlåtelseAvgift]
      ,[MäklarArvodeIProcentVidFörsäljning]
      ,[AvdragIProcentVidFörsäljning]
      ,[UnderhållPerMånad]
      ,[AmorteringPerMånad]
      ,[SparandeSparkontoInsats]
      ,[SparandeMånadssparProcentPerNettoAllt]

      ,[AktierInsats]
      ,[AktierMånadssparProcentPerNettoAllt]
      ,[FonderInsats]
      ,[FonderMånadssparProcentPerNettoAllt]
      ,[ElperMånad]
      ,[FörsäkringperMånad]
      ,[BredbandperMånad]
      ,[TvperMånad]
      ,[MatPerMånad]
      ,[ÖvrigaUtgifterPerMånad]
    INTO #Bostad_grunddata
    FROM dbo.Bostad GD
    WHERE BostadId IN (@BostadId1,@BostadId2)

    -- skapa tabell med månader från startdatum
           ;WITH
				L0   AS(SELECT 1 AS C UNION ALL SELECT 1 AS O), -- 2 rows
				L1   AS(SELECT 1 AS C FROM L0 AS A CROSS JOIN L0 AS B), -- 4 rows
				L2   AS(SELECT 1 AS C FROM L1 AS A CROSS JOIN L1 AS B), -- 16 rows
				L3   AS(SELECT 1 AS C FROM L2 AS A CROSS JOIN L2 AS B), -- 256 rows
				L4   AS(SELECT 1 AS C FROM L3 AS A CROSS JOIN L3 AS B), -- 65,536 rows
				L5   AS(SELECT 1 AS C FROM L4 AS A CROSS JOIN L4 AS B), -- 4,294,967,296 rows
				Nums AS(SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS N FROM L5)
			SELECT TOP (12*@PeriodAntalÅr)
				MånadsNr = N-1,
				Månad = DATEADD(MONTH, N-1, @PeriodStart),
				År = CAST( FLOOR( (N-1) / 12.00 ) AS INT),
				S.InflationProcentPerÅr,
				S.NettoInkomstFörändringProcentPerÅr,
				S.RäntaProcentPerÅr,
				S.RänteAvdragProcentPerÅr,
				S.VärdeFörändringProcentPerÅr,
				S.AktieFörändringProcentPerÅr,
				S.FonderFörändringProcentPerÅr,
				S.SparkontoFörändringProcentPerÅr
				
			INTO #Månader
			FROM Nums N
				LEFT JOIN dbo.Scenario S
					ON CAST( FLOOR( (N.N-1) / 12.00 ) AS INT) BETWEEN S.StartÅr AND S.SlutÅr
			WHERE S.ScenarioKod = @ScenarioKod
			
    DECLARE
		@bostad_i int = 1,
		@bostad_i_max int = (SELECT MAX(RadNr) FROM #Bostad_grunddata )
		
    DECLARE
       @current_BostadId as DECIMAL(38,18)
      ,@current_BostadNamn as varchar(100)
      ,@current_TypAvBostad as varchar(50)
      ,@current_BostadInköpskostnad as DECIMAL(38,18)
      ,@current_BostadInsats as DECIMAL(38,18)
      ,@current_NettoInkomstPerMånad as DECIMAL(38,18)
      ,@current_HyraEllerAvgiftPerMånad as DECIMAL(38,18)
      ,@current_ÖverlåtelseAvgift as DECIMAL(38,18)
      ,@current_MäklarArvodeIProcentVidFörsäljning as DECIMAL(38,18)
      ,@current_AvdragIProcentVidFörsäljning as DECIMAL(38,18)
      ,@current_UnderhållPerMånad as DECIMAL(38,18)
      ,@current_AmorteringPerMånad as DECIMAL(38,18)
      ,@current_SparandeSparkontoInsats as DECIMAL(38,18)
      ,@current_SparandeMånadssparProcentPerNettoAllt as DECIMAL(38,18)
      ,@current_SparandeProcentPerÅrUtv as DECIMAL(38,18)
      ,@current_AktierInsats as DECIMAL(38,18)
      ,@current_AktierMånadssparProcentPerNettoAllt as DECIMAL(38,18)
      ,@current_AktierProcentPerÅrUtv as DECIMAL(38,18)
      ,@current_FonderInsats as DECIMAL(38,18)
      ,@current_FonderMånadssparProcentPerNettoAllt as DECIMAL(38,18)
      ,@current_FonderProcentPerÅrUtv as DECIMAL(38,18)
      ,@current_ElperMånad as DECIMAL(38,18)
      ,@current_FörsäkringperMånad as DECIMAL(38,18)
      ,@current_BredbandperMånad as DECIMAL(38,18)
      ,@current_TvperMånad as DECIMAL(38,18)
      ,@current_MatPerMånad as DECIMAL(38,18)
      ,@current_ÖvrigaUtgifterPerMånad as DECIMAL(38,18)
      ,@current_Lån as DECIMAL(38,18) = -1
      ,@current_BelåningsgradIProcent as DECIMAL(20,17) = NULL
      ,@current_BostadsVärde as DECIMAL(38,18) = NULL
      ,@current_RänteKostnad as DECIMAL(38,18) = NULL
      ,@current_RänteProcent as DECIMAL(38,18) = NULL
      ,@current_NettoInkomstFörändringProcentPerÅr AS DECIMAL(38,18)
      ,@current_RänteAvdragProcentPerÅr as DECIMAL(38,18)
      ,@current_värdeFörändringProcentPerÅr as DECIMAL(38,18)
      ,@current_InflationIProcentPerÅr as DECIMAL(38,18)
    
    CREATE TABLE #BoOchSparBudget
		(
			ID INT,
			ScenarioKod varchar(10),
			Datum date,
			Lägenhetsnamn varchar(100),
			TypAvBostad varchar(50),
			Månad_Inkomst money,
			-- Månadsrelaterad info:
			Månad_TotalKostnad money,
			Månad_Räntekostnad money,
			Månad_AktuellSkuld money,
			Månad_Bostadsvärde money,
			Månad_Amortering money,
			Månad_Belåningsgrad decimal(12,8),
			Månad_ÖvrigaUtgifterUnderMånad money,
			Månad_SparkvotAvNettoInkomst money,
			-- Ack:
			Ackumulerad_Kostnad money,
			Ackumulerad_RänteKostnad money,
			Ackumulerad_Amortering money,
			Ackumulerad_AktieKonto money,
			Ackumulerad_FonderKonto money,
			Ackumulerad_SparKonto money,
			NettoSkuldsättning money,
			FörsäljningsKostnader money
		)
    
    CREATE TABLE #Månadskostnader
		(
					current_Månad date,
					current_InflationIProcentPerÅr decimal(38,18),
					current_Lån decimal(38,18),
					current_BostadsVärde decimal(38,18),
					current_BelåningsgradIProcent decimal(38,18),
					current_RänteProcent decimal(38,18),
					current_RänteKostnad decimal(38,18),
					current_ÖvrigKostnad decimal(38,18)
		)
    
    -- loopa per bostadId   
    WHILE (@bostad_i <= @bostad_i_max )
		BEGIN
			
			SELECT
			   @current_BostadId								= BostadId
			  ,@current_BostadNamn								= BostadNamn
			  ,@current_TypAvBostad								= TypAvBostad
			  ,@current_BostadInköpskostnad						= BostadInköpskostnad
			  ,@current_BostadInsats							= BostadInsats
			  ,@current_NettoInkomstPerMånad					= NettoInkomstPerMånad
			  ,@current_HyraEllerAvgiftPerMånad					= HyraEllerAvgiftPerMånad
			  ,@current_ÖverlåtelseAvgift						= ÖverlåtelseAvgift
			  ,@current_MäklarArvodeIProcentVidFörsäljning		= MäklarArvodeIProcentVidFörsäljning
			  ,@current_AvdragIProcentVidFörsäljning			= AvdragIProcentVidFörsäljning
			  ,@current_UnderhållPerMånad						= UnderhållPerMånad
			  ,@current_AmorteringPerMånad						= AmorteringPerMånad
			  ,@current_SparandeSparkontoInsats					= SparandeSparkontoInsats
			  ,@current_SparandeMånadssparProcentPerNettoAllt   = SparandeMånadssparProcentPerNettoAllt
			  ,@current_AktierInsats							= AktierInsats
			  ,@current_AktierMånadssparProcentPerNettoAllt		= AktierMånadssparProcentPerNettoAllt
			  ,@current_FonderInsats							= FonderInsats
			  ,@current_FonderMånadssparProcentPerNettoAllt		= FonderMånadssparProcentPerNettoAllt
			  ,@current_ElperMånad								= ElperMånad
			  ,@current_FörsäkringperMånad						= FörsäkringperMånad
			  ,@current_BredbandperMånad						= BredbandperMånad
			  ,@current_TvperMånad								= TvperMånad
			  ,@current_MatPerMånad								= MatPerMånad
			  ,@current_ÖvrigaUtgifterPerMånad					= ÖvrigaUtgifterPerMånad	
			  ,@current_BostadsVärde							= @current_BostadInköpskostnad
			FROM #Bostad_grunddata
			WHERE RadNr = @bostad_i

			-- loopa per månad
				-- ackumulera
				-- summera			
			DECLARE
				@månad_i int = 1
				,@månad_i_max int = (SELECT MAX(MånadsNr) FROM #Månader )
				,@current_Månad date = (SELECT MIN(Månad) FROM #Månader )
				-- börjar alltid på år 0:
				,@current_År int = 0
				,@årFörändringFlagga bit = 0
				,@Current_NettoSparande money = 0
				,@Current_Ackumulerad_Kostnad money = 0
				,@Current_Ackumulerad_RänteKostnad money = 0
				,@Current_Ackumulerad_Amortering money = 0
				,@Current_Försäljningskostnad money = 0
				
			WHILE (@månad_i <= @månad_i_max)
				BEGIN
					
					-- hämta månader, kolla om år har ändrats:
					SELECT
						@current_Månad = Månad,
						@current_År = År,
						@årFörändringFlagga = CASE WHEN @current_År = År THEN 1 ELSE 1 END,
						@current_InflationIProcentPerÅr	= M.InflationProcentPerÅr,
						@current_NettoInkomstFörändringProcentPerÅr = M.NettoInkomstFörändringProcentPerÅr,
						@current_RänteProcent = RäntaProcentPerÅr,
						@current_RänteAvdragProcentPerÅr = RänteAvdragProcentPerÅr,
						@current_värdeförändringProcentPerÅr = M.VärdeFörändringProcentPerÅr,
						@current_AktierProcentPerÅrUtv = M.AktieFörändringProcentPerÅr,
						@current_FonderProcentPerÅrUtv = M.FonderFörändringProcentPerÅr,
						@current_SparandeProcentPerÅrUtv = M.SparkontoFörändringProcentPerÅr
					FROM #Månader M
					WHERE @månad_i = MånadsNr
				
					
				SELECT
					-- räkna ut nettolönen (ny varje år):	
					@current_NettoInkomstPerMånad = CASE 
														WHEN @månad_i % 12 = 1 THEN @current_NettoInkomstPerMånad * (1 + (@current_NettoInkomstFörändringProcentPerÅr/100.00) ) 
														ELSE @current_NettoInkomstPerMånad
													END,
					-- Följer inflationen:
					@current_HyraEllerAvgiftPerMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ) ,
					@current_ElperMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ),
					@current_FörsäkringperMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ),
					@current_BredbandperMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ), 
					@current_TvperMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ), 
					@current_MatPerMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ), 
					@current_ÖvrigaUtgifterPerMånad	*= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) )
													

/* **************************************************** */
-- Övriga månadsutgifter:
/* **************************************************** */

						SELECT 
							@Current_NettoSparande = @current_NettoInkomstPerMånad - 
														( @current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad )
														-
														CASE 
															WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift
															ELSE 0
														END
					

						SELECT @Current_Ackumulerad_Kostnad += 
														( @current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad )
														+
														CASE 
															WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift
															ELSE 0
														END	

/* **************************************************** */
-- Sparande:
/* **************************************************** */

						SELECT
							@current_AktierInsats = ( @current_AktierInsats + ( (@current_AktierMånadssparProcentPerNettoAllt / 100.00) * @Current_NettoSparande ) ) * (1 + ( (@current_AktierProcentPerÅrUtv/100.00) / 12.00) ),
							@current_FonderInsats = ( @current_FonderInsats + ( (@current_FonderMånadssparProcentPerNettoAllt / 100.00) * @Current_NettoSparande ) ) * (1 + ( (@current_FonderProcentPerÅrUtv/100.00) / 12.00) ),
							@current_SparandeSparkontoInsats = ( @current_SparandeSparkontoInsats + ( (@current_SparandeMånadssparProcentPerNettoAllt / 100.00) * @Current_NettoSparande ) ) * (1 + ( (@current_SparandeProcentPerÅrUtv/100.00) / 12.00) )
						
	
					-- Vid hyresrätt:
				IF(@current_TypAvBostad = 'Hyresrätt')
					BEGIN
					
						INSERT INTO #BoOchSparBudget
						(
							ID,
							Datum ,
							Lägenhetsnamn ,
							TypAvBostad ,
							-- Månadsrelaterad info:
							Månad_TotalKostnad ,
							Månad_Räntekostnad ,
							Månad_AktuellSkuld ,
							Månad_Bostadsvärde ,
							Månad_Amortering ,
							Månad_Belåningsgrad ,
							Månad_ÖvrigaUtgifterUnderMånad ,
							Månad_SparkvotAvNettoInkomst ,
							-- Ack:
							Ackumulerad_Kostnad ,
							Ackumulerad_RänteKostnad ,
							Ackumulerad_Amortering ,
							Ackumulerad_AktieKonto ,
							Ackumulerad_FonderKonto ,
							Ackumulerad_SparKonto ,
							NettoSkuldsättning ,
							Månad_Inkomst,
							ScenarioKod,
							FörsäljningsKostnader
						)
						SELECT 	
							@bostad_i,				
							@current_Månad,
							@current_BostadNamn,
							@current_TypAvBostad,
							Månad_TotalKostnad = 
												@current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad
												+
												CASE 
													WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift
													ELSE 0
												END
												,
							Månad_Räntekostnad = NULL,
							Månad_AktuellSkuld = NULL,
							Månad_Bostadsvärde = NULL,
							Månad_amortering = NULL,
							Månad_belåningsgrad = NULL,
							Månad_ÖvrigaUtgifterUnderMånad = @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad,
							Månad_SparkvotAvNettoInkomst = @Current_NettoSparande / @current_NettoInkomstPerMånad,
							-- Ack:
							Ackumulerad_kostnad = @Current_Ackumulerad_Kostnad,
							Ackumulerad_RänteKostnad = NULL,
							Ackumulerad_Amortering = NULL,
							Ackumulerad_AktieKonto = @current_AktierInsats,
							Ackumulerad_FonderKonto = @current_FonderInsats,
							Ackumulerad_SparKonto = @current_SparandeSparkontoInsats,
							NettoSkuld = ISNULL(@current_Lån, 0) - (@current_AktierInsats + @current_FonderInsats + @current_SparandeSparkontoInsats),
							NettoInkomstPerMånad = @current_NettoInkomstPerMånad,
							@ScenarioKod,
							FörsäljningsKostnader = 0
					END
			ELSE IF (@current_TypAvBostad IN ( 'Bostadsrätt', 'Villa', 'Radhus') )
				BEGIN

				
			--	/* **************************************************** */
			--	-- Bostadsrelaterade månadsutgifter:
			--	/* **************************************************** */

				SELECT
					-- räkna ut skulden efter amortering:
					@current_Lån =
						CASE 
							WHEN @månad_i = 1 AND @current_BostadInköpskostnad > 0 THEN @current_BostadInköpskostnad - @current_BostadInsats
							WHEN @current_Lån >= 0 THEN @current_Lån - @current_AmorteringPerMånad
						END


				SELECT 
				-- räkna ut bostadsvärdet:
					@current_BostadsVärde *= (1+((@current_värdeförändringProcentPerÅr/100.00)/12.00))
					--@current_BostadsVärde = @current_BostadsVärde 
										
				SELECT 
					-- räkna ut belåningsgraden:
					@current_BelåningsgradIProcent = @current_Lån / @current_BostadsVärde
				
				SELECT 
					-- räkna ut månadsräntekostnaden på lånet:
					@current_RänteKostnad = @current_Lån * ((@current_RänteProcent/100.00)/12.00) * (1-(@current_RänteAvdragProcentPerÅr/100.00) )

					-- Ackumulerade värden:
				SELECT
					@Current_Ackumulerad_RänteKostnad =  ISNULL(@Current_Ackumulerad_RänteKostnad, 0) + @current_RänteKostnad,
					@Current_Ackumulerad_Kostnad += 
														( @current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad )
														+
														ISNULL(@current_RänteKostnad, 0 )
														+
														CASE 
															WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift
															ELSE 0
														END	,
					@Current_Ackumulerad_Amortering += @current_AmorteringPerMånad,
					@Current_Försäljningskostnad = 
													CASE 
														WHEN @månad_i = @månad_i_max AND @InkluderaBostadFörsäljningKostnaderOchVinsterFlagga = 1 
															THEN 
																-- om vinst vid försäljning:
																CASE
																	WHEN @current_BostadsVärde > @current_BostadInköpskostnad THEN
																			(@current_BostadsVärde - @current_BostadInköpskostnad) 
																			* (@current_AvdragIProcentVidFörsäljning/100.00)
																	ELSE 0
																END +
																@current_BostadsVärde * (@current_MäklarArvodeIProcentVidFörsäljning/100.00)
														ELSE 0
													END														
/* ********************************** */
-- #BoOchSparBudget
/* ********************************** */

						INSERT INTO #BoOchSparBudget
						(
							ID,
							Datum ,
							Lägenhetsnamn ,
							TypAvBostad ,
							-- Månadsrelaterad info:
							Månad_TotalKostnad ,
							Månad_Räntekostnad ,
							Månad_AktuellSkuld ,
							Månad_Bostadsvärde ,
							Månad_Amortering ,
							Månad_Belåningsgrad ,
							Månad_ÖvrigaUtgifterUnderMånad ,
							Månad_SparkvotAvNettoInkomst ,
							-- Ack:
							Ackumulerad_Kostnad ,
							Ackumulerad_RänteKostnad ,
							Ackumulerad_Amortering ,
							Ackumulerad_AktieKonto ,
							Ackumulerad_FonderKonto ,
							Ackumulerad_SparKonto ,
							NettoSkuldsättning ,
							Månad_Inkomst,
							ScenarioKod,
							FörsäljningsKostnader
						)
						SELECT 	
							@bostad_i,
							@current_Månad,
							@current_BostadNamn,
							@current_TypAvBostad,
							Månad_TotalKostnad = 
												@current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad
												+
												ISNULL(@current_RänteKostnad, 0)
												+
												CASE 
													WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift
													ELSE 0
												END
												+
												@Current_Försäljningskostnad
												,
							Månad_Räntekostnad = @current_RänteKostnad,
							Månad_AktuellSkuld = @current_Lån,
							Månad_Bostadsvärde = @current_BostadsVärde,
							Månad_amortering   = @current_AmorteringPerMånad,
							Månad_belåningsgrad = @current_BelåningsgradIProcent,
							Månad_ÖvrigaUtgifterUnderMånad = @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad,
							Månad_SparkvotAvNettoInkomst = @Current_NettoSparande / @current_NettoInkomstPerMånad,
							-- Ack:
							Ackumulerad_kostnad = @Current_Ackumulerad_Kostnad + @Current_Försäljningskostnad,
							Ackumulerad_RänteKostnad = @Current_Ackumulerad_RänteKostnad,
							Ackumulerad_Amortering = @Current_Ackumulerad_Amortering,
							Ackumulerad_AktieKonto = @current_AktierInsats,
							Ackumulerad_FonderKonto = @current_FonderInsats,
							Ackumulerad_SparKonto = @current_SparandeSparkontoInsats,
							NettoSkuld = ISNULL(@current_Lån, 0) - (@current_AktierInsats + @current_FonderInsats + @current_SparandeSparkontoInsats) 
							-- Räkna med värdet på bostaden efter lånet räknats bort:
							- (@current_BostadsVärde-@current_Lån)
							+ @Current_Försäljningskostnad
							,
							NettoInkomstPerMånad = @current_NettoInkomstPerMånad,
							@ScenarioKod,
							FörsäljningsKostnader = @Current_Försäljningskostnad

						
			END
				
				
					SET @månad_i = (@månad_i + 1)
					SET @årFörändringFlagga = 0
				END
		
			SET @bostad_i = (@bostad_i + 1)
		
		-- 0 på den bostad vi nyss har kört igenom:
		SELECT
			  @current_BostadInköpskostnad						= NULL
			  ,@current_BostadInsats							= NULL
			  ,@current_NettoInkomstPerMånad					= NULL
			  ,@current_InflationIProcentPerÅr					= NULL
			  ,@current_HyraEllerAvgiftPerMånad					= NULL
			  ,@current_ÖverlåtelseAvgift						= NULL
			  ,@current_MäklarArvodeIProcentVidFörsäljning		= NULL
			  ,@current_AvdragIProcentVidFörsäljning			= NULL
			  ,@current_UnderhållPerMånad						= NULL
			  ,@current_AmorteringPerMånad						= NULL
			  ,@current_SparandeSparkontoInsats					= NULL
			  ,@current_SparandeMånadssparProcentPerNettoAllt   = NULL
			  ,@current_SparandeProcentPerÅrUtv					= NULL
			  ,@current_AktierInsats							= NULL
			  ,@current_AktierMånadssparProcentPerNettoAllt		= NULL
			  ,@current_AktierProcentPerÅrUtv					= NULL
			  ,@current_FonderInsats							= NULL
			  ,@current_FonderMånadssparProcentPerNettoAllt		= NULL
			  ,@current_FonderProcentPerÅrUtv					= NULL
			  ,@current_ElperMånad								= NULL
			  ,@current_FörsäkringperMånad						= NULL
			  ,@current_BredbandperMånad						= NULL
			  ,@current_TvperMånad								= NULL
			  ,@current_MatPerMånad								= NULL
			  ,@current_ÖvrigaUtgifterPerMånad					= NULL	
			  ,@current_Lån										= NULL
			  ,@current_InflationIProcentPerÅr					= NULL
			  ,@current_BostadsVärde							= NULL
			  ,@current_BelåningsgradIProcent					= NULL
			  ,@current_RänteProcent							= NULL
			  ,@current_RänteKostnad							= NULL
			  ,@Current_NettoSparande							= 0
			  ,@Current_Ackumulerad_Kostnad						= 0
			  ,@Current_Ackumulerad_RänteKostnad				= 0
			  ,@Current_Ackumulerad_Amortering					= 0	
			  ,@current_Lån										= 0		
			  ,@Current_Försäljningskostnad						= 0  	  			
		
		END
		
	-- resultat
	SELECT
		Alt1.ScenarioKod,
		Alt1.Datum,
		Alt1_Månad_Inkomst = Alt1.Månad_Inkomst,
		Alt2_Månad_Inkomst = Alt2.Månad_Inkomst,
		Alt1_Lägenhetsnamn = Alt1.Lägenhetsnamn,
		Alt1_TypAvBostad = Alt1.TypAvBostad,
		Alt2_Lägenhetsnamn = Alt2.Lägenhetsnamn,
		Alt2_TypAvBostad = Alt2.TypAvBostad,
		Alt1_Månad_Bostadsvärde = Alt1.Månad_Bostadsvärde,
		Alt2_Månad_Bostadsvärde = Alt2.Månad_Bostadsvärde,
		Alt1_Månad_TotalKostnad = Alt1.Månad_TotalKostnad,
		Alt2_Månad_TotalKostnad = Alt2.Månad_TotalKostnad,
		Alt1_Månad_AktuellSkuld = Alt1.Månad_AktuellSkuld,
		Alt2_Månad_AktuellSkuld = Alt2.Månad_AktuellSkuld,
		Alt1_Månad_Amortering = Alt1.Månad_Amortering,
		Alt2_Månad_Amortering = Alt2.Månad_Amortering,
		Alt1_Månad_Räntekostnad = Alt1.Månad_Räntekostnad,
		Alt2_Månad_Räntekostnad = Alt2.Månad_Räntekostnad,		
		Alt1_Månad_ÖvrigaUtgifterUnderMånad = Alt1.Månad_ÖvrigaUtgifterUnderMånad,
		Alt2_Månad_ÖvrigaUtgifterUnderMånad = Alt2.Månad_ÖvrigaUtgifterUnderMånad,
		Alt1_Månad_Belåningsgrad = Alt1.Månad_Belåningsgrad,
		Alt2_Månad_Belåningsgrad = Alt2.Månad_Belåningsgrad,
		Alt1_månad_sparkvotavNettoInkomst =	Alt1.månad_sparkvotavNettoInkomst,
		Alt2_månad_sparkvotavNettoInkomst = Alt2.månad_sparkvotavNettoInkomst,
		Alt1_NettoSkuldsättning = Alt1.NettoSkuldsättning,
		Alt2_NettoSkuldsättning = Alt2.NettoSkuldsättning,
		Alt1_FörsäljningsKostnader = Alt1.FörsäljningsKostnader,
		Alt2_FörsäljningsKostnader = Alt2.FörsäljningsKostnader,
		-- ACKUMULERADE VÄRDEN:
		Alt1_Ackumulerad_Kostnad = Alt1.Ackumulerad_Kostnad,
		Alt2_ackumulerad_kostnad = Alt2.ackumulerad_kostnad,
		Alt1_Ackumulerad_RänteKostnad = Alt1.Ackumulerad_RänteKostnad,
		Alt2_Ackumulerad_RänteKostnad = Alt2.Ackumulerad_RänteKostnad,
		alt1_Ackumulerad_Amortering = alt1.Ackumulerad_Amortering,
		Alt2_Ackumulerad_Amortering = Alt2.Ackumulerad_Amortering,
		Alt1_Ackumulerad_AktieKonto = Alt1.Ackumulerad_AktieKonto,
		Alt2_Ackumulerad_AktieKonto = Alt2.Ackumulerad_AktieKonto,
		Alt1_Ackumulerad_FonderKonto = Alt1.Ackumulerad_FonderKonto,
		Alt2_Ackumulerad_FonderKonto = Alt2.Ackumulerad_FonderKonto,
		Alt1_Ackumulerad_SparKonto = Alt1.Ackumulerad_SparKonto,
		Alt2_Ackumulerad_SparKonto = Alt2.Ackumulerad_SparKonto
	FROM #BoOchSparBudget Alt1
		JOIN #BoOchSparBudget Alt2 ON Alt1.ID + 1 = Alt2.ID AND Alt1.Datum = Alt2.Datum
    
END

GO

 

För att testa koden så kör du exempelvis detta anrop:

EXEC [dbo].[usp_BostadsKostnad]
	@BostadId1 = 1,-- första bostadid,
	@BostadId2 = 2,-- andra bostadid,
	@PeriodAntalÅr = 15, -- antal år
	@PeriodStart = '2014-08-01', -- när startar jämförelsen
	@InkluderaBostadFörsäljningKostnaderOchVinsterFlagga = 1, -- inkludera mäklararvode och reavinstskatt som kostnader (vilket det är!)
	@ScenarioKod = 'Scenario1' -- vilket framtidsscenario ska användas?

 

Vi får då ett resultat där vi kan utläsa bostadsvärde, nettokapital, kostnader, amorteringar och sparande. Det finns såklart många aber med denna kod. Just nu finns exempelvis ingen förmögenhetsskatt eller någon ordentlig fastighetsskatt. Amorteringen är rak, vilket inte alla kör med. Man kan heller inte välja amorteringsfritt över en övergående period.

 

 

 

 

 

YSlow – få hjälp med att snabba upp din sajt!

Sunday, December 6th, 2009

Yslow är ett smidigt integrerat webbutvecklarverktyg som mäter hur lång tid din sajt behöver laddas upp i användarens webbläsare. Verktyget kombineras i samband med den underbara webbutvecklingsverktyget Firebug.

YSlow mäter alltså hur snabbt din sajt laddas, detta är ibland lätt att glömma bort hur viktigt det kan vara, särskilt vid hård serverbelastning. Vissa tips är ganska okonventionella, exempelvis att sätta javascript längst ned på sidan, då webbläsaren har svårt att processa javascript med resten av sidan parallellt. Ett annat tips som YSlow ger är att undvika att dela upp css-filer samt javascript-filer i flera bitar, eftersom det tar längre tid att stänga och sedan öppna filer.

Genom YSlow sänkte jag laddningstiden för supportbetyg.se från 538kb till ca 200, en besparing på nästan 60%, och tiden för laddning från 3,5 sekunder till 1.25, även där en besparing på 60% i tid.

Varför är detta då viktigt? Detta är viktigt eftersom användaren är mycket otålig och lat. Förstår inte användaren vad sajten gör inom 5-10 sekunder, så surfar användaren snabbt bort, då är varje sekund dyrbar till att övertyga!

Solution to “Cannot modify header information – headers already sent”

Sunday, November 15th, 2009

Hi!

This problem seems to occur on a frequently acting basis, so I’ll try to make a summary of the several solutions you can find on the net here:

Solution nr 1: Trim whitespaces near your start-tag in php, so it looks like this:

session_start();
/* After trimming whitespace, write out your header and the rest of your code */

Solution nr 2: header() is coming after require/include

session_start();
/* Try to make requires/includes compile after header */
header("Location: http://www.yoursite.com/mypage.php");

include("helperClass.php");
//code here

3. Or the pandoras box-solution: change the coding of the current file from UTF-8!
Sometimes (I don’t know for what reason) apache can’t read UTF-8 properly and think of the start-tag as other characters.

/*
#1: Open your file in a text editor (i recommend notepad++ or notepad)
#2: Change the coding of the file from UTF-8 to ANSI.
#3: Save and upload it to the server again.
*/

That’s summarises the top 3 solutions for this type of problem. There’s probably more solutions, but in order to find them, you need to dig deep into the search engines.