Ero sivun ”Projektinhallinta” versioiden välillä

Opasnet Suomista
Siirry navigaatioon Siirry hakuun
(→‎Budjetin laskenta: some bugs fixed)
pEi muokkausyhteenvetoa
 
(31 välissä olevaa versiota 4 käyttäjän tekeminä ei näytetä)
Rivi 1: Rivi 1:
[[Luokka:Projektinhallinta]]
[[Luokka:Sisältää R-koodia]]
{{metodi|moderator=Jouni|stub=Yes}}
{{metodi|moderator=Jouni|stub=Yes}}
'''Projektinhallinta''' sisältää menetelmiä tutkimushankkeiden ja muiden projektien suunnitteluun, seurantaan ja hallintaan. [[Aikakone]] sisältää työajanhallintaan liittyviä osia. Tällä sivulla on menetelmiä talouden hallintaan.  
'''Projektinhallinta''' sisältää menetelmiä tutkimushankkeiden ja muiden projektien suunnitteluun, seurantaan ja hallintaan. [[Aikakone]] sisältää työajanhallintaan liittyviä osia. Tällä sivulla on menetelmiä talouden hallintaan.  
Rivi 4: Rivi 6:
===Budjetin laskenta===
===Budjetin laskenta===


<rcode name="budjetti">
Budjetointijärjestelmän olennaisia piirteitä ovat avoimuus, joustavuus ja laajennettavuus.
library(OpasnetBaseUtils)
* Se toimii Opasnetin perustyökaluilla.
library(xtable)
* Tiedot syötetään suoraan Opasnetin sivulle datatauluksi.
* Budjetti lasketaan yksinkertaisesti sivulla olevaa nappeja painamalla. Tulosteen yksityiskohtaisuuden voi itse valita.
* Siinä on sisäänrakennettuna tiedot laitosten lisäkuluprosenteista eri vuosina: [[Budjettikertoimet]]
* Siinä on sisäänrakennettuna tiedot laitosten palkkaluokkien tasosta: [[Vaativuusluokkien keskipalkat]]
* Palkat budjetoidaan henkilökuukausina ja muut menot euroina, eli kuten budjetintekijä ne ajattelee.
* Se osaa laskea automaattisesti seuraavia asioita yhden rivin mittaisen kuvauksen avulla eli tulot ja menot saadaan pidettyä automaattisesti tasapainossa:
** "Meno X (esim. henkilön palkka) katetaan budjettimomentilta Y (esim. virkapalkoista)" ja se laskee euromäärät automaattisesti eli tulo muuttuu jos menoa muutetaan. Tämä tapahtuu tekemällä tätä tuloa varten rivi, joka sisältää menoa vastaavat määritteet ja sen lisäksi kuvaus-sarakkeen ensimmäisenä sanana täytyy olla "TULOVASTA" (isoilla kirjaimilla). Vuosisarakkeisiin laitetaan se osuus, joka vastatuloa maksetaan; 1 tarkoittaa 100 % eli kyseinen meno katetaan kokonaisuudessaan tästä tulosta.
** "Työpaketin TPX vajeesta Z % katetaan budjettimomentilta Y1 [ja (100 - Z) % budjettimomentilta Y2]." Tämä toteutetaan kirjaamalla Kustannuslajiksi "Tulot" ja kuvaus-sarakkeeseen ensimmäiseksi sanaksi "TULOLOPUT". Tämä tulo on kohdennettu tietylle projektille, työpaketille ja vuodelle. Vuosisarakkeisiin laitetaan se osuus, joka työpaketin tappiosta katetaan kyseiseltä tulomomentilta. Erityisesti tästä tykkään, koska ainakin itse joudun budjetoinnissa ähräämään juuri tämän asian kimpussa pisimpään.
* Jokaisen projektin voi budjetoida toisista riippumatta omalle sivulleen, mutta samalla voidaan helposti hakea vapaavalintaiselta määrältä sivuja budjetit (esim. koskien koko yksikköä tai osastoa) ja laskea ne yhteen yhdeksi budjetiksi [[Lista projekteista|projektilistauksen]] avulla.
* Jos halutaan, systeemiä voidaan helposti laajentaa niin, että palkkatyön osalta työntekijän nimi nostetaan omaksi kentäkseen, jolloin voidaan tehdä yhteenvetoja myös esim. osaston henkilöiden työaikasuunnitelmista eli siitä, kuka tekee mitäkin projektia ja mikä on kunkin budjetoitu kokonaistyöaika.


####Budjettilaskenta: suunnitelluista palkka- ja muista menoista lasketaan kokonaisbudjetti. Toistaiseksi käsitellään vain menoja, tuloja ei ole sisällytetty.


budjettilaskenta <- function(page, laitos = "THL", vuosi = "2011") {
Budjetin datataulun rakenne on alla. Sarakkeet Kustannuslaji, vuosi ja kuvaus ovat pakollisia; muut sarakkeet joita ei datataulussa ole annettu luodaan automaattisesti oletusarvoista. Rakenteessa on sellainen erikoisuus, että "kuvaus" on itse asiassa yksi tarkasteltavista vuosista, mikä on jonkin verran hämäävää mutta tuottaa sen edun, että vuodesta toiseen toistuva tapahtuma voidaan kuvata yksinkertaisesti yhdellä rivillä niin että joka vuoden kohdalla on tapahtuman määrä kyseisenä vuonna ja viimeisenä tapahtuman kuvaus.
data <- op_baseGetData("opasnet_base", page)[, -c(1,2)]
 
data <- reshape(data, idvar = "obs.1", timevar = "Havainto", direction = "wide")[, -c(1,4,5,6)]
{| {{prettytable}}
colnames(data) <- c("Kustannuslaji", "määrä", "kuvaus")
|+ Budjetin datataulun sarakkeet
#print(xtable(data), type='html')
| colspan="5"| Selittävät sarakkeet (indeksit)
temp <- data.frame(Kustannuslaji = kustannuslaji, määrä = määrä, kuvaus = kuvaus)
! colspan="3"| Vuosi
data <- rbind(data, temp)
|----
#print(xtable(data), type='html')
! Laitos || Rahoittaja|| Projekti|| Työpaketti|| Kustannuslaji|| 2012|| 2013 || kuvaus
kertoimet <- op_baseGetData("opasnet_base", "Op_fi2704")
|----
kertoimet <- kertoimet[kertoimet$Laitos == "THL" & kertoimet$Vuosi == "2011" & kertoimet$Rahoittaja == "STM", ]
| THL || Suomen Akatemia || Projektin nimi || TP1 || Palkka VT7 || 12|| 6|| Henkilön N.N. palkka vaativuusluokassa VT7, ensimmäisenä vuonna 12 kk, toisena 6 kk
#kertoimet
|----
YK <- kertoimet[kertoimet$Kerroin == "Yleiskustannus", "Result"]
| THL || Suomen Akatemia || Projektin nimi || TP1 || Matkat || 500 || 500 || Matkakustannukset 500 e/vuosi
SK <- kertoimet[kertoimet$Kerroin == "Palkan sivukulu", "Result"]
|}
cat("Yleiskustannuskerroin:", YK, "Sivukulukerroin", SK, "\n")
 
palkka <- op_baseGetData("opasnet_base", "Op_fi2705")[, -c(1,2,7)]
Lisäksi seuraavat sarakkeet luodaan taustatietojen ja laskennan perusteella:
#print(xtable(palkka), type = 'html')
* htkk (henkilötyökuukaudet)
palkka <- palkka[palkka$Laitos == laitos & palkka$Vuosi == vuosi, -c(1,3)]
* Yleiskustannus
colnames(palkka)[1] <- "Kustannuslaji"
* Sivukulu
print(xtable(palkka), type = 'html')
* kkpalkka (kuukausipalkka)
data <- merge(data, palkka, all.x=TRUE)
* summa (meno tai tulo euroina)
#print(xtable(data), type = 'html')
 
test <- "Palkka" == substr(data$Kustannuslaji, 1, 6)
 
data$Result <- ifelse(test, data$Result * data$määrä, data$määrä)
'''Syötettävän datan tyypit vaihtelevat rivistä riippuen:
data$määrä <- ifelse(test, data$määrä, 0)
* Palkkakulut ilmoitetaan kuukausina.
colnames(data)[c(2,4)] <- c("hlö-kk", "summa")
* Muut menot ja tulot ilmoitetaan euroina.
print(xtable(data), type = 'html')
* Automaattisesti laskettavat tulot TULOVASTA ja TULOLOPUT ilmoitetaan osuuksina kyseisen menon tai työpaketin tappion suuruudesta.
data$Kustannuslaji <- ifelse(test, "Palkka", as.character(data$Kustannuslaji))
 
palkat <- sum(data[test, "summa"])
===R-koodi===
out <- data.frame(Kustannuslaji = c("Sivukulut", "Yleiskustannus"), summa = c(palkat*SK, palkat*(1+SK)*YK))
 
out <- rbind(data[, c("Kustannuslaji", "summa")], out)
'''page:Projektinhallinta|name:budjetti
print(xtable(out), type = 'html')
 
out <- as.data.frame(as.table(tapply(out$summa, out$Kustannuslaji, sum)))
<rcode name="budjetti" label="Koodi vain luo funktioita">
colnames(out) <- c("Kustannuslaji", "summa")
library(OpasnetUtils)
print(xtable(out), type = 'html')
 
out$summa <- ifelse(out$Kustannuslaji =="Tulot", out$Kustannuslaji, -out$Kustannuslaji)
####Budjettilaskenta: suunnitelluista palkka- ja muista menoista lasketaan kokonaisbudjetti.
out <- rbind(out, data.frame(Kustannuslaji = "Yhteensä", summa = sum(out$summa)))
 
print(xtable(out), type = 'html')
# Kehityskohteita: Otetaan vapaakenttärivejä, joiden määrä riippuu jostain vastinrivistä.
 
budjettilaskenta <- function(page, laitos = "THL", vuosi = "2012", rahoittaja = "Suomen Akatemia",
projekti = "Projekti", työpaketti = "Työpaketti", työpaketti.add = "Työpaketti", vuosi.add = "2012", laitos.add =
"THL", rahoittaja.add = "Suomen Akatamia", kustannuslaji.add = "Palkka VT7", määrä.add = 0, kuvaus.add = "", series_id = NULL) {
 
# Haetaan budjettidata ja lisätään siihen kaikki ne sarakkeet joita taulussa ei ole.
out <- opbase.data(page, series_id = series_id)[, -c(1,2)]
if(!"Projekti" %in% colnames(out)) {out <- cbind(out, data.frame(Projekti = projekti))}
if(!"Työpaketti" %in% colnames(out)) {out <- cbind(out, data.frame(Työpaketti = työpaketti))}
if(!"Vuosi" %in% colnames(out)) {out <- cbind(out, data.frame(Vuosi = vuosi))}
if(!"Rahoittaja" %in% colnames(out)) {out <- cbind(out, data.frame(Rahoittaja = rahoittaja))}
if(!"Laitos" %in% colnames(out)) {out <- cbind(out, data.frame(Laitos = laitos))}
 
# Datan kuvaus lisätään jokaisen vuoden riville.
kuvaukset <- out[out$Vuosi == "kuvaus", !colnames(out) %in% c("Result", "Vuosi")]
colnames(kuvaukset)[colnames(kuvaukset) == "Result.Text"] <- "kuvaus"
out <- merge(out, kuvaukset)
 
# Turhat (tyhjät) sarakkeet ja rivit poistetaan.
out <- out[out$Vuosi != "kuvaus", !colnames(out) %in% c("Result.Text", "obs.1")]
# Sarakkeiden nimet siistitään ja määrä muutetaan faktorista numeroiksi.
colnames(out)[colnames(out) == "Result"] <- "määrä"
out$määrä <- as.numeric(as.character(out$määrä))
# Lisätään rivi, jossa on käyttöliittymän kautta annetut tilapäisen tapahtuman tiedot.
temp <- data.frame(Projekti = projekti, Työpaketti = työpaketti.add, Vuosi = vuosi.add, Laitos = laitos.add,
Rahoittaja = rahoittaja.add, Kustannuslaji = kustannuslaji.add, määrä = määrä.add, kuvaus = kuvaus.add)
out <- rbind(out, temp)
 
# Haetaan ALV-prosentit ja lasketaan ne relevanteille riveille.
alv <- tidy(opbase.data("Op_fi2913"))
alv <- merge(out, alv) # ALV laitetaan joka riville, joille se on määritelty.
alv$määrä <- alv$määrä * alv$Result
alv$Kustannuslaji <- "ALV"
alv <- alv[colnames(out)]
out <- rbind(out, alv)
 
# Haetaan sivukulu- ja yleiskustannuskertoimet Opasnetistä, siistitään ja yhdistetään budjettiin.
kertoimet <- opbase.data("Op_fi2704")[, 3:8]
kertoimet <- reshape(kertoimet, v.names = "Result", idvar = "obs.1", timevar = "Kerroin", direction = "wide")
kertoimet <- kertoimet[, colnames(kertoimet) != "obs.1"]
colnames(kertoimet)[colnames(kertoimet)=="Result.Yleiskustannus"] <- "Yleiskustannus"
colnames(kertoimet)[colnames(kertoimet)=="Result.sivukulu"] <- "Sivukulu"
out <- merge(out, kertoimet, all.x = TRUE)
 
# Haetaan laitoksen vaativuusluokkien keskipalkat, siistitään ja yhdistetään budjettiin.
palkka <- opbase.data("Op_fi2705")[, 3:6]
colnames(palkka)[colnames(palkka)=="Result"] <- "kkpalkka"
colnames(palkka)[colnames(palkka)=="Vaativuusluokka"] <- "Kustannuslaji"
out <- merge(out, palkka, all.x=TRUE)
 
# Budjetissa on erikseen aktiviteetin määrä (määrä) ja yksikköhinta (kkpalkka).
# Yksikköhinta on kuukausipalkka palkoille ja euromääräisille aktiviteeteille 1.
out$kkpalkka <- ifelse(is.na(out$kkpalkka), 1, out$kkpalkka)
# Muutetaan aktiviteetit euromääräisiksi summiksi. Entinen määrä-sarake muutetaan henkilökuukausiksi.
out$summa <- out$määrä * out$kkpalkka
colnames(out)[colnames(out)=="määrä"] <- "htkk"
 
# Merkitään joka rivi joko tuloksi tai menoksi.
out$tulomeno <- ifelse(out$Kustannuslaji == "Tulot" | substr(paste(out$kuvaus, "    "), 1,4) == "TULO", "Tulot", "Menot")
# Seuraavaksi etsitään sellaiset tulot, jotka automaattisesti skaalataan jonkin määrätyn menon suuruiseksi.
# Vertailukohtana toimiva meno tunnistetaan indeksien arvojen avulla.
# Kehityskohde: kaikkia indeksin arvoja ei tarvitse määritellä, vaan voi käyttää "villiä korttia".
# rahoitus sisältää tiedon siitä, mitä menoja rahoitetaan ja millä prosentilla (osuus 1 tarkoittaa 100%).
rahoitus <- out[substr(paste(out$kuvaus, "    "), 1, 9) == "TULOVASTA", ]
rahoitus$osuus <- rahoitus$htkk
rahoitus <- (rahoitus[, c("Projekti", "Työpaketti", "Vuosi", "Laitos", "Kustannuslaji", "tulomeno", "osuus")])
rahoitus$tulomeno <- "Menot"
 
# temp yhdistää tiedon että rahoitetaan määriteltyihin menoihin. Sen jälkeen tämä summa nimetään tuloksi
# ja lisätään budjettitauluun ja siirrettään summa-sarakkeeseen.
temp <- merge(out, rahoitus)
temp$osuus <- temp$summa * temp$osuus
temp <- temp[, c("Laitos", "Vuosi", "Kustannuslaji", "Työpaketti", "Projekti", "tulomeno", "osuus")]
temp$tulomeno <- "Tulot"
out <- merge(out, temp, all.x = TRUE)
out$summa <- ifelse(is.na(out$osuus), out$summa, out$osuus)
 
# Lasketaan sivukulut ja yleiskustannukset ja merkitään joka rivi joko tuloksi tai menoksi.
test <- substr(paste(out$Kustannuslaji, "     "), 1, 6) == "Palkka" # Onko palkkarivi?
out$htkk <- ifelse(test | substr(paste(out$kuvaus, "      "), 1, 4) == "TULO", out$htkk, 0)
out$Sivukulu <- ifelse(test, out$Sivukulu * out$summa, 0)
out$Yleiskustannus <- ifelse(test, out$Yleiskustannus * (out$Sivukulu + out$summa), 0)
out$tulomeno <- ifelse(out$Kustannuslaji == "Tulot" | substr(paste(out$kuvaus, "    "), 1,4) == "TULO", "Tulot", "Menot")
 
# Lisätään omat rivit sivukuluille ja yleiskustannuksille.
palkat <- out[substr(paste(out$Kustannuslaji, "      "), 1, 6) == "Palkka", ]
palkat$Kustannuslaji <- "Yleiskustannus"
palkat$summa <- palkat$Yleiskustannus
out <- rbind(out, palkat)
palkat$Kustannuslaji <- "Sivukulu"
palkat$summa <- palkat$Sivukulu
out <- rbind(out, palkat)
 
# Menot merkitään negatiivisiksi, jotta voidaan laskea tulot ja menot yhteen.
out$summa <- ifelse(out$tulomeno == "Tulot", out$summa, -out$summa)
# Nyt lisätään TULOLOPUT eli tieto siitä, mikä rahoittaja maksaa tietyn osuuden jäljelle jäävästä summasta.
# Summat lasketaan vuoden, työpaketin ja projektin yhdistelmille.
# Ensin tyhjennetään summasarake TULOLOPUT-riveiltä, koska siinä on osuus vaikka pitää olla 0.
out$summa <- ifelse(substr(paste(out$kuvaus, "          "), 1,9) == "TULOLOPUT", 0, out$summa)
tarve <- as.data.frame(as.table(tapply(-out$summa, out[, c("Vuosi", "Työpaketti", "Projekti")], sum)))
tarve$Freq <- ifelse(tarve$Freq < 0, 0, tarve$Freq)
out <- merge(out, tarve)
# Rahoitusosuus on htkk-sarakkeessa ja tarvittava työpaketin tilanne (=tarve) Freq-sarakkeessa.
out$summa <- ifelse(substr(paste(out$kuvaus, "        "), 1, 9) == "TULOLOPUT", out$htkk * out$Freq, out$summa)
out <- out[, c("Projekti", "Työpaketti", "Vuosi", "Laitos", "Rahoittaja", "Kustannuslaji", "tulomeno", "htkk", "summa", "kuvaus")]
 
return(out)
}
 
################### Budjettiyhteenveto laskee erilaisia summatauluja budjettilaskennan tuottamasta taulusta, jossa on jokainen tapahtuma eritelty.
 
budjettiyhteenveto <- function(budjettitaulu, jaottelu = c(1,2,3), param = "summa") {
out <- budjettitaulu
# Kaikki palkat muutetaan samanlaisiksi.
out$Kustannuslaji <- ifelse(substr(paste(out$Kustannuslaji, "      "), 1, 6) == "Palkka", "Palkka", as.character(out$Kustannuslaji))
 
 
jaottelu <- c("tulomeno", c("Projekti", "Työpaketti", "Vuosi", "Laitos", "Rahoittaja", "Kustannuslaji")[jaottelu])
out <- as.data.frame(as.table(tapply(out[, param], out[, jaottelu], sum)))
 
# Tyhjät rivit poistetaan ja otsikoita parannetaan.
colnames(out)[colnames(out) == "Freq"] <- param
out <- out[!is.na(out[param]), ]
 
return(out)
}
 
############################# htkk
# parametrit: budjettitaulu: budjettilaskenta-funktion tuottama data.frame.
#            jaottelu:      ne selitteet, jotka eritellään (Projekti, Työpaketti, Vuosi, Laitos, Rahoittaja, Kustannuslaji)
htkk <- function(budjettitaulu, jaottelu = c(1,2,3)) {
out <- budjettitaulu
out <- out[substr(paste(out$Kustannuslaji, "      "), 1, 6) == "Palkka" & out$tulomeno == "Menot", ]
out <- budjettiyhteenveto(out, param = "htkk")
return(out)
}
}
</rcode>
</rcode>
Rivi 53: Rivi 203:


<rcode variables="
<rcode variables="
name:kustannuslaji|type:selection|default:'Palkka VT7'|options:'Palkka VT6';Palkka VT6;'Palkka VT7';Palkka VT7;'Palkka VT8';Palkka VT8;'Ostopalvelu';Ostopalvelu;'Matka';Matka;'Tarvike';Tarvike|
name:kustannuslaji.add|type:selection|default:'Palkka VT7'|options:'Palkka VT6';Palkka VT6;'Palkka VT7';Palkka VT7;'Palkka VT8';Palkka VT8;'Ostopalvelu';Ostopalvelu;'Matka';Matka;'Tarvike';Tarvike|
category:Voit testata budjettia tällä tilapäisellä lisätapahtumalla.|
category:Voit testata budjettia tällä tilapäisellä lisätapahtumalla.|
name:määrä|default:0|
name:määrä.add|default:0|
name:kuvaus|type:text
name:kuvaus.add|type:text
" include="page:Projektinhallinta|name:budjetti">
" include="page:Projektinhallinta|name:budjetti">
budjettilaskenta("Tähän tapahtumatiedot sisältävän sivun tunniste")
budjettilaskenta("Tähän tapahtumatiedot sisältävän sivun tunniste")
</rcode>
</rcode>
====generic====
Tämä koodi sisältää funktiot '''dropall''' ja '''PTable''' ja luonnokset koodeista EVPI, EVPPI, stattable.
<rcode name="generic">
##### dropall #################################
dropall <- function(x){
## dropall pudottaa data.framesta pois kaikki faktorien sellaiset levelit, joita ei käytetä.
## parametrit: x = data.frame
    isFac <- NULL
    for (i in 1:dim(x)[2]){isFac[i] = is.factor(x[ , i])}
    for (i in 1:length(isFac)){
        x[, i] <- x[, i][ , drop = TRUE]
        }
    return(x)
    }
##### PTable ####################################
PTable <- function(P, n) {
## PTable muuntaa arvioinnin todennäköisyystaulun sopivaan muotoon arviointia varten.
## Parametrit: P = todennäköisyystaulu Opasnet-kannasta kaivettuna.
##            n = iteraatioiden lukumäärä Monte Carlossa
## Todennäköisyystaulun sarakkeiden on oltava: Muuttuja, Selite, Lokaatio, P
## Tuotteena on Monte Carloa varten tehty taulu, jonka sarakkeina ovat
## n (iteraatio) ja kaikki todennäköisyystaulussa olleet selitteet, joiden riveille on arvottu
## lokaatiot niiden todennäköisyyksien mukaisesti, jotka todennäköisyystaulussa oli annettu.
Pt <- unique(P[,c("Muuttuja", "Selite")])
Pt <- data.frame(Muuttuja = rep(Pt$Muuttuja, n), Selite = rep(Pt$Selite, n), obs = rep(1:n, each = nrow(Pt)), P = runif(n*nrow(Pt), 0, 1))
for(i in 2:nrow(P)){P$Result[i] <- P$Result[i] + ifelse(P$Muuttuja[i] == P$Muuttuja[i-1] & P$Selite[i] == P$Selite[i-1], P$Result[i-1], 0)}
P <- merge(P, Pt)
P <- P[P$P <= P$Result, ]
Pt <- as.data.frame(as.table(tapply(P$Result, as.list(P[, c("Muuttuja", "Selite", "obs")]), min)))
colnames(Pt) <- c("Muuttuja", "Selite", "obs", "Result")
Pt <- Pt[!is.na(P$Result), ]
P <- merge(P, Pt)
P <- P[, !colnames(P) %in% c("Result", "P", "Muuttuja")]
P <- reshape(P, idvar = "obs", timevar = "Selite", v.names = "Lokaatio", direction = "wide")
colnames(P) <- ifelse(substr(colnames(P), 1, 9) == "Lokaatio.", substr(colnames(P), 10,30), colnames(P))
return(P)
}
######################################
##### EVPI = Expected Value of Perfect Information #############
EVPI <- function(outcome, decision){
#### DOES NOT WORK YET
## evpi produces the expected value of perfect information about a decision situation.
# Current code was developed for a previous version and does not yet work.
evpi <- (apply(apply(cost, c(2,3,4), mean, na.rm=TRUE), c(1,3), min, na.rm=TRUE) - apply(apply(cost, c(1,2,4), min,
na.rm=TRUE), c(2,3), mean, na.rm=TRUE))/1e6
plot5 <- as.data.frame(as.table(apply(evpi, 2, sum)))
plot5 <- ggplot(plot5, aes(Var1, weight=Freq)) + geom_bar(position="dodge") +
scale_x_discrete("Year") + scale_y_continuous("Value of perfect information (M€)")
plot5
}
##### EVPPI = Expected Value of Partial Perfect Information ###########
EVPPI <- function(outcome, decision, vars) {
#### DOES NOT WORK YET
## EVPPI calculates the expected value of partial perfect information for a decision.
## Parameters: all parameters must have the same length n = number of iterations.
##            outcome = outcome of interest (a vector with numeric values)
##            decision = decision options (a vector with numeric or character values)
##            vars = uncertain variables of interest (a data.frame with one column for each variable)
# Current code was developed for a previous version and does not yet work.
aer <- DataframeToArray(ae)
aer <- aer[,,c(2,1,4,5),]
dropnonmax <- function(x) {
x[x<max(x, na.rm = TRUE)] <- NA
return(x)
}
aer <- apply(aer, c(1,2,4), dropnonmax)
aer <- as.data.frame(as.table(aer))
aer <- aer[,c(2,3,1,4,5)]
colnames(aer)[3] <- "Policy"
aer <- aer[is.na(aer[,"Freq"])==FALSE,]
aer <- IntArray(aer, cost, "Cost")
aer <- DataframeToArray(aer[,c("obs","Country","Year","Cost")],"Cost")
test2 <- (apply(apply(cost, c(2,3,4), mean, na.rm=TRUE), c(1,3), min, na.rm=TRUE) - apply(aer, c(2,3), mean))/1e6
plot6 <- as.data.frame(as.table(apply(test2, 2, sum)))
plot6 <- ggplot(plot6, aes(Var1, weight=Freq)) + geom_bar(position="dodge") +
scale_x_discrete("Year") + scale_y_continuous("Value of perfect information (M€)")
plot6
test2==evpi #test whether the values are the same
test2-evpi
# It seems that for some reason aer evppi is slightly smaller than evpi,
# although it should be the only variable that varies in the "Policy" dimension
}
##### stattable ##########################################
stattable <- function(data, outcome, indices, obs = "obs", P = 0.95, dec = 2) {
#### DOES NOT WORK YET
## stattable calculates mean, sd, and P % confidence intervals for a data.frame.
## Parameters: data    = data.frame with the values
##            outcome = name of the column in data containing the outcome.
##            indices = a vector of names of columns used as indices.
##            obs    = name of the column in data containing the number of iteration.
##            P      = probability that the true outcome is between the confidence interval.
out <- tapply(data[, colnames(data) == outcome], c(indices, obs), sum, na.rm=TRUE)
ci <- apply(out, 1:length(indices), quantile, probs=c((1-P)/2, 1/2+P/2))
means <- apply(out, 1:length(indices), mean)
sd <- apply(out, 1:length(indices), sd)
out <- paste(round(means), " ± ", sd, " (", round(ci[1,,]), "-", round(ci[2,,]), ")", sep="")
out
}
</rcode>
===Opetuskoodi===
Tämä koodi on muuten sama kuin alkuperäinen, mutta se tulostaa kaikki mahdolliset välivaiheet (tosin yleensä vain ensimmäiset rivi tuloksesta), jotta käyttäjä voi helpommin nähdä, mitä se oikein tekee ja miten. Samoin funktio on muutettu suoraksi koodiksi, koska muuten tulokset näkyvät vasta kerralla kun funktio ajetaan, eikä siinä kohdassa kun asia tapahtuu funktion sisällä.
<rcode name="opetus" variables="
name:jaottelu|descripion:Mitkä jaottelut haluat säilyttää yhteenvedossa?|type:checkbox|options:1;Kustannuslaji;2;Työpaketti;3;Vuosi;4;Laitos;5;Rahoittaja;6;Projekti|default:2;3
">
library(OpasnetUtils)
####Budjettilaskenta: suunnitelluista palkka- ja muista menoista lasketaan kokonaisbudjetti.
# Kehityskohteita: Otetaan vapaakenttärivejä, joiden määrä riippuu jostain vastinrivistä.
#budjettilaskenta <- function(page, laitos = "THL", vuosi = "2012", rahoittaja = "Suomen Akatemia",
# projekti = "Projekti", työpaketti = "Työpaketti", työpaketti.add = "Työpaketti", vuosi.add = "2012", laitos.add =
# "THL", rahoittaja.add = "Suomen Akatamia", kustannuslaji.add = "Palkka VT7", määrä.add = 0, kuvaus.add = "") {
page = "Op_fi2682"; rahoittaja = "STM"; projekti = "Tekaisu"; työpaketti = "TP1"; työpaketti.add = "TP1"; rahoittaja.add = "THL"
vuosi.add = "2012"; laitos.add = "THL"; kustannuslaji.add = "Palkka VT7"; määrä.add = 0; kuvaus.add = "lisäys"
# Haetaan budjettidata ja lisätään siihen kaikki ne sarakkeet joita taulussa ei ole.
out <- opbase.data(page)[, -c(1,2)]
oprint(out[1:6, ])
if(!"Projekti" %in% colnames(out)) {out <- cbind(out, data.frame(Projekti = projekti))}
if(!"Työpaketti" %in% colnames(out)) {out <- cbind(out, data.frame(Työpaketti = työpaketti))}
if(!"Vuosi" %in% colnames(out)) {out <- cbind(out, data.frame(Vuosi = vuosi))}
if(!"Rahoittaja" %in% colnames(out)) {out <- cbind(out, data.frame(Rahoittaja = rahoittaja))}
if(!"Laitos" %in% colnames(out)) {out <- cbind(out, data.frame(Laitos = laitos))}
oprint(out[1:6, ])
# Datan kuvaus lisätään jokaisen vuoden riville.
kuvaukset <- out[out$Vuosi == "kuvaus", !colnames(out) %in% c("Result", "Vuosi")]
colnames(kuvaukset)[colnames(kuvaukset) == "Result.Text"] <- "kuvaus"
oprint(kuvaukset[1:6, ])
out <- merge(out, kuvaukset)
oprint(out[1:6, ])
# Turhat (tyhjät) sarakkeet ja rivit poistetaan.
out <- out[out$Vuosi != "kuvaus", !colnames(out) %in% c("Result.Text", "obs.1")]
oprint(out[1:6, ])
# Sarakkeiden nimet siistitään ja määrä muutetaan faktorista numeroiksi.
colnames(out)[colnames(out) == "Result"] <- "määrä"
out$määrä <- as.numeric(as.character(out$määrä))
oprint(out[1:6, ])
# Lisätään rivi, jossa on käyttöliittymän kautta annetut tilapäisen tapahtuman tiedot.
temp <- data.frame(Projekti = projekti, Työpaketti = työpaketti.add, Vuosi = vuosi.add, Laitos = laitos.add,
Rahoittaja = rahoittaja.add, Kustannuslaji = kustannuslaji.add, määrä = määrä.add, kuvaus = kuvaus.add)
oprint(temp)
out <- rbind(out, temp)
# Haetaan sivukulu- ja yleiskustannuskertoimet Opasnetistä, siistitään ja yhdistetään budjettiin.
kertoimet <- opbase.data("Op_fi2704")[, 3:8]
oprint(kertoimet[1:6, ])
kertoimet <- reshape(kertoimet, v.names = "Result", idvar = "obs.1", timevar = "Kerroin", direction = "wide")
oprint(kertoimet[1:6, ])
kertoimet <- kertoimet[, colnames(kertoimet) != "obs.1"]
oprint(kertoimet[1:6, ])
colnames(kertoimet)[colnames(kertoimet)=="Result.Yleiskustannus"] <- "Yleiskustannus"
colnames(kertoimet)[colnames(kertoimet)=="Result.sivukulu"] <- "Sivukulu"
oprint(kertoimet[1:6, ])
out <- merge(out, kertoimet, all.x = TRUE)
oprint(out[1:6, ])
# Haetaan laitoksen vaativuusluokkien keskipalkat, siistitään ja yhdistetään budjettiin.
palkka <- opbase.data("Op_fi2705")[, 3:6]
oprint(palkka[1:6, ])
colnames(palkka)[colnames(palkka)=="Result"] <- "kkpalkka"
colnames(palkka)[colnames(palkka)=="Vaativuusluokka"] <- "Kustannuslaji"
oprint(palkka[1:6, ])
out <- merge(out, palkka, all.x=TRUE)
oprint(out[1:6, ])
# Budjetissa on erikseen aktiviteetin määrä (määrä) ja yksikköhinta (kkpalkka).
# Yksikköhinta on kuukausipalkka palkoille ja euromääräisille aktiviteeteille 1.
out$kkpalkka <- ifelse(is.na(out$kkpalkka), 1, out$kkpalkka)
oprint(out[1:6, ])
# Muutetaan aktiviteetit euromääräisiksi summiksi. Entinen määrä-sarake muutetaan henkilökuukausiksi.
out$summa <- out$määrä * out$kkpalkka
colnames(out)[colnames(out)=="määrä"] <- "htkk"
oprint(out[1:6, ])
# Merkitään joka rivi joko tuloksi tai menoksi.
out$tulomeno <- ifelse(out$Kustannuslaji == "Tulot" | substr(paste(out$kuvaus, "    "), 1,4) == "TULO", "Tulot", "Menot")
oprint(out[1:6, ])
# Seuraavaksi etsitään sellaiset tulot, jotka automaattisesti skaalataan jonkin määrätyn menon suuruiseksi.
# Vertailukohtana toimiva meno tunnistetaan indeksien arvojen avulla.
# Kehityskohde: kaikkia indeksin arvoja ei tarvitse määritellä, vaan voi käyttää "villiä korttia".
# rahoitus sisältää tiedon siitä, mitä menoja rahoitetaan ja millä prosentilla (osuus 1 tarkoittaa 100%).
rahoitus <- out[substr(paste(out$kuvaus, "    "), 1, 9) == "TULOVASTA", ]
oprint(rahoitus[1:6, ])
rahoitus$osuus <- rahoitus$htkk
rahoitus <- (rahoitus[, c("Projekti", "Työpaketti", "Vuosi", "Laitos", "Kustannuslaji", "tulomeno", "osuus")])
rahoitus$tulomeno <- "Menot"
oprint(rahoitus[1:6, ])
# temp yhdistää tiedon että rahoitetaan määriteltyihin menoihin. Sen jälkeen tämä summa nimetään tuloksi
# ja lisätään budjettitauluun ja siirrettään summa-sarakkeeseen.
temp <- merge(out, rahoitus)
oprint(temp[1:6, ])
temp$osuus <- temp$summa * temp$osuus
oprint(temp[1:6, ])
temp <- temp[, c("Laitos", "Vuosi", "Kustannuslaji", "Työpaketti", "Projekti", "tulomeno", "osuus")]
temp$tulomeno <- "Tulot"
oprint(temp[1:6, ])
out <- merge(out, temp, all.x = TRUE)
oprint(out[1:6, ])
out$summa <- ifelse(is.na(out$osuus), out$summa, out$osuus)
oprint(out[1:6, ])
# Lasketaan sivukulut ja yleiskustannukset.
test <- substr(paste(out$Kustannuslaji, "    "), 1, 6) == "Palkka" # Onko palkkarivi?
test
out$htkk <- ifelse(test | substr(paste(out$kuvaus, "      "), 1, 4) == "TULO", out$htkk, 0)
oprint(out[1:6, ])
out$Sivukulu <- ifelse(test, out$Sivukulu * out$summa, 0)
oprint(out[1:6, ])
out$Yleiskustannus <- ifelse(test, out$Yleiskustannus * (out$Sivukulu + out$summa), 0)
# Lisätään omat rivit sivukuluille ja yleiskustannuksille.
palkat <- out[substr(paste(out$Kustannuslaji, "      "), 1, 6) == "Palkka", ]
oprint(palkat[1:6, ])
palkat$Kustannuslaji <- "Yleiskustannus"
palkat$summa <- palkat$Yleiskustannus
oprint(palkat[1:6, ])
out <- rbind(out, palkat)
palkat$Kustannuslaji <- "Sivukulu"
palkat$summa <- palkat$Sivukulu
oprint(palkat[1:6, ])
out <- rbind(out, palkat)
# Menot merkitään negatiivisiksi, jotta voidaan laskea tulot ja menot yhteen.
out$summa <- ifelse(out$tulomeno == "Tulot", out$summa, -out$summa)
oprint(out[1:6, ])
# Nyt lisätään TULOLOPUT eli tieto siitä, mikä rahoittaja maksaa tietyn osuuden jäljelle jäävästä summasta.
# Summat lasketaan vuoden, työpaketin ja projektin yhdistelmille.
# Ensin tyhjennetään summasarake TULOLOPUT-riveiltä, koska siinä on osuus vaikka pitää olla 0.
out$summa <- ifelse(substr(paste(out$kuvaus, "          "), 1,9) == "TULOLOPUT", 0, out$summa)
oprint(out[1:6, ])
tarve <- as.data.frame(as.table(tapply(-out$summa, out[, c("Vuosi", "Työpaketti", "Projekti")], sum)))
tarve$Freq <- ifelse(tarve$Freq < 0, 0, tarve$Freq)
oprint(tarve[1:6, ])
out <- merge(out, tarve)
oprint(out[1:6, ])
# Rahoitusosuus on htkk-sarakkeessa ja tarvittava työpaketin tilanne (=tarve) Freq-sarakkeessa.
out$summa <- ifelse(substr(paste(out$kuvaus, "        "), 1, 9) == "TULOLOPUT", out$htkk * out$Freq, out$summa)
oprint(out[1:6, ])
out <- out[, c("Projekti", "Työpaketti", "Vuosi", "Laitos", "Rahoittaja", "Kustannuslaji", "tulomeno", "htkk", "summa", "kuvaus")]
oprint(out[1:6, ])
# return(out)
#}
#out <- budjettilaskenta("Op_fi2682", rahoittaja = "STM", projekti = "Tekaisu", työpaketti = "TP1", työpaketti.add = "TP1", rahoittaja.add = "THL")
#print(xtable(out), type = 'html')
################### Budjettiyhteenveto laskee erilaisia summatauluja budjettilaskennan tuottamasta taulusta, jossa on jokainen tapahtuma eritelty.
#budjettiyhteenveto <- function(budjettitaulu, jaottelu = c(1,2,3)) {
# out <- budjettitaulu
# Kaikki palkat muutetaan samanlaisiksi.
out$Kustannuslaji <- ifelse(substr(paste(out$Kustannuslaji, "      "), 1, 6) == "Palkka", "Palkka", as.character(out$Kustannuslaji))
oprint(out[1:6, ])
jaottelu
jaottelu <- c("tulomeno", c("Projekti", "Työpaketti", "Vuosi", "Laitos", "Rahoittaja", "Kustannuslaji")[jaottelu])
jaottelu
out <- as.data.frame(as.table(tapply(out$summa, out[, jaottelu], sum)))
oprint(out[1:6, ])
# Tyhjät rivit poistetaan ja otsikoita parannetaan.
colnames(out)[colnames(out) == "Freq"] <- "Summa"
out <- out[!is.na(out$Summa), ]
oprint(out[1:6, ])
# return(out)
#}
#print(xtable(budjettiyhteenveto(out, jaottelu)), type='html')
#print(xtable(budjettiyhteenveto(out, c(2,6))), type='html')
#out <- budjettiyhteenveto(out, c(3,5))
#out <- out[out$tulomeno == "Tulot", ]
#print(xtable(out), type='html')
</rcode>
==Pohdintaa==
Yhteenvetosivulle: projekti, sivutunniste, sivun nimi. Jotta ei tarvitse datataulussa toistaa sitä asiaa, joka on joka rivillä sama.
findident <- function(name) {
SELECT obj.ident FROM obj WHERE obj.name = name
#HUOM. Tämä ei ota huomioon eri wikejä ja namespaceja, koska tämä tieto ei tallentune obj.nameen
}
Kuinka toimii tehtävienhallinta?
* budjettiin kirjataan projektiin saadut työkuukaudet (työpaketeittain)
* tehtävälistaan kirjataan luvatut tehtävät ja arvioidut kestot
* henkilön työsuunnitelmaan tehdään aikajana siitä, mitä henkilö aikoo tehdä milloinkin. Tähän kirjataan myös lomat, sairauspoissaolot ja matkat.
* sivulistaus listaa kaikki ne tehtävät, joita perustellusti tehdään, kun sivua päivitetään. EI TOIMI!  Missä on sivulistaus? Jospa sekä sivuja että tehtäviä listataan johonkin projektiin kuuluvaksi? Tällöin voi olla yksi sivu per projekti, jossa kaikki nämä tiedot listataan. (Projekti), osaprojekti, tehtävä, henkilö, sivu. Tässä on olennaista, että tehtävät listataan henkilöittäin. Onko? Ei ole, vaan jos henkilöä ei sanota, silloin kuka tahansa projektiin kuuluva henkilö voi tehdä tehtäviä. Tämä taas toteutetaan siten, että jos tehtävän henkilöä ei mainita, kaikki tehtävää tekemään ilmoittautuneet listataan. Projektiin kuuluvat henkilöt taas listataan siten, että mainitaan projekti ja henkilö, mutta ei tehtävää eikä sivua. Tyhjä sarake tarkoittaa "mikä tahansa."
** Usean projektin sivulla voi siis listata, että jokin sivu kuuluu osaksi sitä. Eli
* automaattisesti käydään läpi tietoja siitä, kuka on muokannut mitäkin sivuja ja milloin. Sivuseurannan perusteella sivun päivitys jaetaan aina yhteen tehtävään siten, että automaattisesti otetaan huomioon, paljonko mitäkin tehtävää pitäisi tehdä. Tarvitaanko tätä varten erillinen lista, jossa kerrotaan tehtävätasolla se, mitä projektia katsotaan tehtävän, jos kyseinen sivul liittyy useampaan tehtävään? Pitäisikö tämä tarkastelu tehdä millä tasolla? Vaihtoehdot: projekti, osaprojekti, tehtävä. Tehtävä ei käy, koska hako pitää tehdä nimenomaan hallinnollisista  syiistä ja tehtävät on jaettu toiminnallisin perustein. Hallinollisista syistä seurantatarkkuus on alaprojekti, koska esim EU:lla ei projektitaso riitä. Eli päätelmä: kukin tehtävä kytekeätän ainakin yhteen tai useampaan aliprojektiin (jos projektissa ei ole aliprojekteja, aliprojektiksi katsotaan automaattisesti projekti itse). Eli jotta homma onnistuisi, jokainen sivu pitää pystyä kytkemään yhteen tehtävään, joka puolestaan kytketään useampaan aliprojektiin.
* Miten sitten hallitaan tehtävän tekemisen seurantaa? Jotenkin pitäisi helposti pystyä listaamaan se, missä tilanteessa tehtävä on. Tätä on melko hellppo listata suoraan tehtävälistaan, mitta sitten etenemistä pitää seurata erikseen. Entä jos tieto-oliotemlaattiin laitettaisiin parametriksi tehtävän eteneminen? Ei toimi, koska yhdellä sivulla voi olla useita tehtäviä. Entä jos hyödynnetään todota ja lisätään siihen yksi parametri, joka voidaan lukea suoraan tietokannasta? Tämä voisi toimia, mutta tehtävälistauksen seurannan pitäisi toimia  myös. Jos on molemmissa tietoa, sivun todo ajaa yli tehtävälistasta. Niinpä jos halutaan seurata tilannetta, ei pidä katsoa alkuperäistä listaa vaan pitää ajaa malli, joka tekee tilannekatsauksen.
* työajan seuranta (timetracking) korjaa päivittäin sitä, mitä itse asiassa tuli tehdyksi. Tämä ajaa yli työsuunnitelman ja sivuseurannan, jos on ristiriitoja.
Laskenta:
* Resurssitarkistus: verrataan budjetit ja tehtävälistat toisiinsa. Kaikkiin tehtäviin pitäisi olla löydettävissä riittävästi budjettia työn tekemiseksi.
* Työaikatarkistus: verrataan tehtävälistaa ja henkilöiden työsuunnitelmia toisiinsa. Jokaisen tehtävän pitäisi löytyä jonkun työaikasuunnitelmasta, ja työaikasuunnitelmat eivät saisi olla kohtuuttomasti ylityöllistettyjä.
* Työtehtävien seuranta: katsotaan tehtävään suunniteltu työaika tehtävälistasta. Lisäksi katsotaan, paljonko tehtävään on oikeasti käytetty aikaa työsuunnitelman, sivuseurannan ja päivittäisen työajanseurannan perusteella.
* Työaikaraportointi: Käydään läpi tehtyjä työtehtäviä. näistä kertyvät työtunnit allokoidaan aliprojekteille siten, että tärkeyslistalla ensimmäiset aliprojektit tulevat ensimmäisenä raportoitua. Kun jokin projekti on raportoitu, työaikaraportti on lukittava jotta laskenta ei muutu jälkikäteen. Miten? Tietty tehtävä tai aliprojekti ei kuitenkaan ole tullut valmiiksi raportointijakson päättyessä.
Pitääkö tehdä niin, että aina kun raportoidaan, kyseinen työaikalistaus kopioidaan jollekin sivulle, ja se sitten automaattisesti miinustetaan tehdyistä työajoista ensimmäisenä, ja vasta jäljelle jääneeseen työaikaan sovelletaan allokointia. Mutta sitten siitäkin tarvitaan listaus, mitä projektiraportointeja lasketaan mukaan mihinkin työaikaraportointiin. Vai tehdäänkö niin, että on yksi lista siitä, minkä projektin raportointi on missäkin, ja sitten kaikkien relevanttien projektien raportoinnit kaivetaan esiin? Tämä on hyvä.
* Projektin tuntiraportti: projekti, aliprojekti, henkilö, alku, loppu, tehdyt tunnit. Tämä summataan sopivaan tarkkuuteen projektista riippuen, esim. EU-projekteissa henkilö, alku, loppu summataan raportointijaksolla pois, kun taas EAKR-projekteissa mitään niistä ei summata vaan raportti tehdään yksityiskohtiaan myöten. Ilmeisesti joka tapauksessa yksityiskohtainen raportti pitää tallentaa, muuten käy niin, ettei summatiedolla pystytä yksiselitteisesti laskemaan jo raportoituja tunteja pois.
==Katso myös==
* [[Aikakone]]
* [[Lista projekteista]]
* [[:Malline:Budjettirajapinta‎]]
* [[Arvonlisävero]]
* [[Projektisopimukset]]
==Viitteet==
==Aiheeseen liittyviä tiedostoja==
{{mfiles}}

Nykyinen versio 22. elokuuta 2013 kello 10.57




Projektinhallinta sisältää menetelmiä tutkimushankkeiden ja muiden projektien suunnitteluun, seurantaan ja hallintaan. Aikakone sisältää työajanhallintaan liittyviä osia. Tällä sivulla on menetelmiä talouden hallintaan.

Budjetin laskenta

Budjetointijärjestelmän olennaisia piirteitä ovat avoimuus, joustavuus ja laajennettavuus.

  • Se toimii Opasnetin perustyökaluilla.
  • Tiedot syötetään suoraan Opasnetin sivulle datatauluksi.
  • Budjetti lasketaan yksinkertaisesti sivulla olevaa nappeja painamalla. Tulosteen yksityiskohtaisuuden voi itse valita.
  • Siinä on sisäänrakennettuna tiedot laitosten lisäkuluprosenteista eri vuosina: Budjettikertoimet
  • Siinä on sisäänrakennettuna tiedot laitosten palkkaluokkien tasosta: Vaativuusluokkien keskipalkat
  • Palkat budjetoidaan henkilökuukausina ja muut menot euroina, eli kuten budjetintekijä ne ajattelee.
  • Se osaa laskea automaattisesti seuraavia asioita yhden rivin mittaisen kuvauksen avulla eli tulot ja menot saadaan pidettyä automaattisesti tasapainossa:
    • "Meno X (esim. henkilön palkka) katetaan budjettimomentilta Y (esim. virkapalkoista)" ja se laskee euromäärät automaattisesti eli tulo muuttuu jos menoa muutetaan. Tämä tapahtuu tekemällä tätä tuloa varten rivi, joka sisältää menoa vastaavat määritteet ja sen lisäksi kuvaus-sarakkeen ensimmäisenä sanana täytyy olla "TULOVASTA" (isoilla kirjaimilla). Vuosisarakkeisiin laitetaan se osuus, joka vastatuloa maksetaan; 1 tarkoittaa 100 % eli kyseinen meno katetaan kokonaisuudessaan tästä tulosta.
    • "Työpaketin TPX vajeesta Z % katetaan budjettimomentilta Y1 [ja (100 - Z) % budjettimomentilta Y2]." Tämä toteutetaan kirjaamalla Kustannuslajiksi "Tulot" ja kuvaus-sarakkeeseen ensimmäiseksi sanaksi "TULOLOPUT". Tämä tulo on kohdennettu tietylle projektille, työpaketille ja vuodelle. Vuosisarakkeisiin laitetaan se osuus, joka työpaketin tappiosta katetaan kyseiseltä tulomomentilta. Erityisesti tästä tykkään, koska ainakin itse joudun budjetoinnissa ähräämään juuri tämän asian kimpussa pisimpään.
  • Jokaisen projektin voi budjetoida toisista riippumatta omalle sivulleen, mutta samalla voidaan helposti hakea vapaavalintaiselta määrältä sivuja budjetit (esim. koskien koko yksikköä tai osastoa) ja laskea ne yhteen yhdeksi budjetiksi projektilistauksen avulla.
  • Jos halutaan, systeemiä voidaan helposti laajentaa niin, että palkkatyön osalta työntekijän nimi nostetaan omaksi kentäkseen, jolloin voidaan tehdä yhteenvetoja myös esim. osaston henkilöiden työaikasuunnitelmista eli siitä, kuka tekee mitäkin projektia ja mikä on kunkin budjetoitu kokonaistyöaika.


Budjetin datataulun rakenne on alla. Sarakkeet Kustannuslaji, vuosi ja kuvaus ovat pakollisia; muut sarakkeet joita ei datataulussa ole annettu luodaan automaattisesti oletusarvoista. Rakenteessa on sellainen erikoisuus, että "kuvaus" on itse asiassa yksi tarkasteltavista vuosista, mikä on jonkin verran hämäävää mutta tuottaa sen edun, että vuodesta toiseen toistuva tapahtuma voidaan kuvata yksinkertaisesti yhdellä rivillä niin että joka vuoden kohdalla on tapahtuman määrä kyseisenä vuonna ja viimeisenä tapahtuman kuvaus.

Budjetin datataulun sarakkeet
Selittävät sarakkeet (indeksit) Vuosi
Laitos Rahoittaja Projekti Työpaketti Kustannuslaji 2012 2013 kuvaus
THL Suomen Akatemia Projektin nimi TP1 Palkka VT7 12 6 Henkilön N.N. palkka vaativuusluokassa VT7, ensimmäisenä vuonna 12 kk, toisena 6 kk
THL Suomen Akatemia Projektin nimi TP1 Matkat 500 500 Matkakustannukset 500 e/vuosi

Lisäksi seuraavat sarakkeet luodaan taustatietojen ja laskennan perusteella:

  • htkk (henkilötyökuukaudet)
  • Yleiskustannus
  • Sivukulu
  • kkpalkka (kuukausipalkka)
  • summa (meno tai tulo euroina)


Syötettävän datan tyypit vaihtelevat rivistä riippuen:

  • Palkkakulut ilmoitetaan kuukausina.
  • Muut menot ja tulot ilmoitetaan euroina.
  • Automaattisesti laskettavat tulot TULOVASTA ja TULOLOPUT ilmoitetaan osuuksina kyseisen menon tai työpaketin tappion suuruudesta.

R-koodi

page:Projektinhallinta|name:budjetti

+ Näytä koodi

Tällä käyttöliittymällä ohjataan budjettilaskentaa:

Voit testata budjettia tällä tilapäisellä lisätapahtumalla.

kustannuslaji.add:

määrä.add:

kuvaus.add:

+ Näytä koodi

generic

Tämä koodi sisältää funktiot dropall ja PTable ja luonnokset koodeista EVPI, EVPPI, stattable.

+ Näytä koodi

Opetuskoodi

Tämä koodi on muuten sama kuin alkuperäinen, mutta se tulostaa kaikki mahdolliset välivaiheet (tosin yleensä vain ensimmäiset rivi tuloksesta), jotta käyttäjä voi helpommin nähdä, mitä se oikein tekee ja miten. Samoin funktio on muutettu suoraksi koodiksi, koska muuten tulokset näkyvät vasta kerralla kun funktio ajetaan, eikä siinä kohdassa kun asia tapahtuu funktion sisällä.

jaottelu:
Kustannuslaji
Työpaketti
Vuosi
Laitos
Rahoittaja
Projekti

+ Näytä koodi

Pohdintaa

Yhteenvetosivulle: projekti, sivutunniste, sivun nimi. Jotta ei tarvitse datataulussa toistaa sitä asiaa, joka on joka rivillä sama.

findident <- function(name) { SELECT obj.ident FROM obj WHERE obj.name = name

  1. HUOM. Tämä ei ota huomioon eri wikejä ja namespaceja, koska tämä tieto ei tallentune obj.nameen

}

Kuinka toimii tehtävienhallinta?

  • budjettiin kirjataan projektiin saadut työkuukaudet (työpaketeittain)
  • tehtävälistaan kirjataan luvatut tehtävät ja arvioidut kestot
  • henkilön työsuunnitelmaan tehdään aikajana siitä, mitä henkilö aikoo tehdä milloinkin. Tähän kirjataan myös lomat, sairauspoissaolot ja matkat.
  • sivulistaus listaa kaikki ne tehtävät, joita perustellusti tehdään, kun sivua päivitetään. EI TOIMI! Missä on sivulistaus? Jospa sekä sivuja että tehtäviä listataan johonkin projektiin kuuluvaksi? Tällöin voi olla yksi sivu per projekti, jossa kaikki nämä tiedot listataan. (Projekti), osaprojekti, tehtävä, henkilö, sivu. Tässä on olennaista, että tehtävät listataan henkilöittäin. Onko? Ei ole, vaan jos henkilöä ei sanota, silloin kuka tahansa projektiin kuuluva henkilö voi tehdä tehtäviä. Tämä taas toteutetaan siten, että jos tehtävän henkilöä ei mainita, kaikki tehtävää tekemään ilmoittautuneet listataan. Projektiin kuuluvat henkilöt taas listataan siten, että mainitaan projekti ja henkilö, mutta ei tehtävää eikä sivua. Tyhjä sarake tarkoittaa "mikä tahansa."
    • Usean projektin sivulla voi siis listata, että jokin sivu kuuluu osaksi sitä. Eli
  • automaattisesti käydään läpi tietoja siitä, kuka on muokannut mitäkin sivuja ja milloin. Sivuseurannan perusteella sivun päivitys jaetaan aina yhteen tehtävään siten, että automaattisesti otetaan huomioon, paljonko mitäkin tehtävää pitäisi tehdä. Tarvitaanko tätä varten erillinen lista, jossa kerrotaan tehtävätasolla se, mitä projektia katsotaan tehtävän, jos kyseinen sivul liittyy useampaan tehtävään? Pitäisikö tämä tarkastelu tehdä millä tasolla? Vaihtoehdot: projekti, osaprojekti, tehtävä. Tehtävä ei käy, koska hako pitää tehdä nimenomaan hallinnollisista syiistä ja tehtävät on jaettu toiminnallisin perustein. Hallinollisista syistä seurantatarkkuus on alaprojekti, koska esim EU:lla ei projektitaso riitä. Eli päätelmä: kukin tehtävä kytekeätän ainakin yhteen tai useampaan aliprojektiin (jos projektissa ei ole aliprojekteja, aliprojektiksi katsotaan automaattisesti projekti itse). Eli jotta homma onnistuisi, jokainen sivu pitää pystyä kytkemään yhteen tehtävään, joka puolestaan kytketään useampaan aliprojektiin.
  • Miten sitten hallitaan tehtävän tekemisen seurantaa? Jotenkin pitäisi helposti pystyä listaamaan se, missä tilanteessa tehtävä on. Tätä on melko hellppo listata suoraan tehtävälistaan, mitta sitten etenemistä pitää seurata erikseen. Entä jos tieto-oliotemlaattiin laitettaisiin parametriksi tehtävän eteneminen? Ei toimi, koska yhdellä sivulla voi olla useita tehtäviä. Entä jos hyödynnetään todota ja lisätään siihen yksi parametri, joka voidaan lukea suoraan tietokannasta? Tämä voisi toimia, mutta tehtävälistauksen seurannan pitäisi toimia myös. Jos on molemmissa tietoa, sivun todo ajaa yli tehtävälistasta. Niinpä jos halutaan seurata tilannetta, ei pidä katsoa alkuperäistä listaa vaan pitää ajaa malli, joka tekee tilannekatsauksen.
  • työajan seuranta (timetracking) korjaa päivittäin sitä, mitä itse asiassa tuli tehdyksi. Tämä ajaa yli työsuunnitelman ja sivuseurannan, jos on ristiriitoja.

Laskenta:

  • Resurssitarkistus: verrataan budjetit ja tehtävälistat toisiinsa. Kaikkiin tehtäviin pitäisi olla löydettävissä riittävästi budjettia työn tekemiseksi.
  • Työaikatarkistus: verrataan tehtävälistaa ja henkilöiden työsuunnitelmia toisiinsa. Jokaisen tehtävän pitäisi löytyä jonkun työaikasuunnitelmasta, ja työaikasuunnitelmat eivät saisi olla kohtuuttomasti ylityöllistettyjä.
  • Työtehtävien seuranta: katsotaan tehtävään suunniteltu työaika tehtävälistasta. Lisäksi katsotaan, paljonko tehtävään on oikeasti käytetty aikaa työsuunnitelman, sivuseurannan ja päivittäisen työajanseurannan perusteella.
  • Työaikaraportointi: Käydään läpi tehtyjä työtehtäviä. näistä kertyvät työtunnit allokoidaan aliprojekteille siten, että tärkeyslistalla ensimmäiset aliprojektit tulevat ensimmäisenä raportoitua. Kun jokin projekti on raportoitu, työaikaraportti on lukittava jotta laskenta ei muutu jälkikäteen. Miten? Tietty tehtävä tai aliprojekti ei kuitenkaan ole tullut valmiiksi raportointijakson päättyessä.

Pitääkö tehdä niin, että aina kun raportoidaan, kyseinen työaikalistaus kopioidaan jollekin sivulle, ja se sitten automaattisesti miinustetaan tehdyistä työajoista ensimmäisenä, ja vasta jäljelle jääneeseen työaikaan sovelletaan allokointia. Mutta sitten siitäkin tarvitaan listaus, mitä projektiraportointeja lasketaan mukaan mihinkin työaikaraportointiin. Vai tehdäänkö niin, että on yksi lista siitä, minkä projektin raportointi on missäkin, ja sitten kaikkien relevanttien projektien raportoinnit kaivetaan esiin? Tämä on hyvä.

  • Projektin tuntiraportti: projekti, aliprojekti, henkilö, alku, loppu, tehdyt tunnit. Tämä summataan sopivaan tarkkuuteen projektista riippuen, esim. EU-projekteissa henkilö, alku, loppu summataan raportointijaksolla pois, kun taas EAKR-projekteissa mitään niistä ei summata vaan raportti tehdään yksityiskohtiaan myöten. Ilmeisesti joka tapauksessa yksityiskohtainen raportti pitää tallentaa, muuten käy niin, ettei summatiedolla pystytä yksiselitteisesti laskemaan jo raportoituja tunteja pois.

Katso myös

Viitteet

Aiheeseen liittyviä tiedostoja

<mfanonymousfilelist></mfanonymousfilelist>