Ero sivun ”Kohdistamo” versioiden välillä

Opasnet Suomista
Siirry navigaatioon Siirry hakuun
pEi muokkausyhteenvetoa
(→‎Vastaus: koronakide lisätty)
 
(27 välissä olevaa versiota 3 käyttäjän tekeminä ei näytetä)
Rivi 1: Rivi 1:
{{metodi}}
{{metodi}}
[[op_en:Timetracker]]
[[op_en:Timetracker]]
== Kysymys ==
Miten kirjataan työaikaa helpolla tavalla?
== Vastaus ==
Työaikaa kirjataan alla olevalla koodilla "Tallenna kirjaus". Tällöin tallentuu käyttäjän käyttäjätunnus, valittu projekti, aloitusaika (mahdollisesti lopetusaika jos se annetaan) sekä aikaleima. Kirjauksia voi tarkastella koodilla "Hae kirjauksia". Hakua voi rajata käyttäjän, projektin ja aikakriteerin perusteella.
Kirjauksissa on kaksi mahdollista aikatulkintaa. Tällä hetkellä käytetään ensimmäistä, mutta aiemmin oli käytössä jäljempi. Esimerkkinä voidaan ajatella kirjauksia, jotka sama käyttäjä on tehnyt. Ensimmäinen kirjaus on projektia A klo 1-4, toinen on projektia B klo 2-3.
# Käyttäjäkohtaiset kirjaukset tulkitaan tapahtumajärjestyksessä ja loppuaika tarkoittaa kaiken työn lopettamista. Tässä tapauksessa tulkinta on, että klo 1 alkoi projekti A, klo 2 se vaihtui projektiin B, klo 3 työnteko lopetettiin ja klo 4 työnteko lopetettiin (eli kello neljän kirjaus ei vaikuta mihinkään koska tila ei muutu). Tämä tulkinta on suoraviivaisempi ja mahdollistaa työn alku- ja loppuaikojen kirjaamisen toisistaan riippumatta.
# Käyttäjäkohtaiset kirjaukset tulkitaan kirjausjärjestyksessä. Toinen kirjaus siis pyyhkii yli ensimmäisen kirjauksen siltä osin kuin ne ovat päällekkäisiä. Tässä tapauksessa tulkinta on, että klo 1 alkoi projekti A, klo 2 se vaihtui projektiin B, klo 3 palattiin projektiin A ja työnteko lopetettiin klo 4. Tässä tulkinnassa on aina kirjattava alku- ja loppuajat pareina, mikä voi olla hankalaa. Funktiossa makeTimeline käytetään mergeä yhdistämään oikeat aikapisteparit toisiinsa. {{kommentti|#|Tästä voisi tehdä päivitetyn version. Alla oleva Aikakoneen makeTimeline ei liene uusin. Toinen versio löytyy sivulta [[:op_en:OpasnetUtils/Drafts#Miscellaneous functions]].|--[[Käyttäjä:Jouni|Jouni Tuomisto]] ([[Keskustelu käyttäjästä:Jouni|keskustelu]]) 10. heinäkuuta 2018 kello 12.44 (UTC)}}


<rcode name="answer" embed=1 showcode=0 label="Tallenna kirjaus" variables="
<rcode name="answer" embed=1 showcode=0 label="Tallenna kirjaus" variables="
name:työ|description:Minkä työn haluat kirjata?|type:selection|options:
name:työ|description:Minkä työn haluat kirjata?|type:selection|options:
'Yhtäköyttä';Yhtäköyttä;
  'Koronakide';Koronakide;
'Helsingin energiaratkaisu';Helsingin energiaratkaisu;
  'Ilmastovahti';Ilmastovahti;
'Yleiset Opasnet-työt';Yleiset Opasnet-työt;
  'Näkemysverkko';Näkemysverkko;
'Helsingin ilmastokartta 2';Helsingin ilmastokartta 2;
  'Opetus';Opetus;
'Avoimen tieteen tiekartta';Avoimen tieteen tiekartta;
  'Muu kansalaisopisto';Muu kansalaisopisto;
'Hyvinvointi kestävän kasvun perustana';Hyvinvointi kestävä kasvun perustana;
  'Palkallinen vapaa';Palkallinen vapaa;
'STM raportointi ja laskutus';STM raportointi ja laskutus;
  'Palkaton vapaa';Palkaton vapaa;
'EU raportointi ja laskutus';EU raportointi ja laskutus;
  'Maahanmuutto';Maahanmuutto;
'TEKES raportointi ja laskutus';TEKES raportointi ja laskutus;
  'Yhtäköyttä';Yhtäköyttä;
'SA raportointi ja laskutus';SA raportointi ja laskutus;
  'Vesiapina';Vesiapina;
'ESR/EAKR raportointi ja laskutus';ESR/EAKR raportointi ja laskutus;
  'Vesiopas';Vesiopas;
'MUUT  raportointi ja laskutus';MUUT  raportointi ja laskutus;
  'Videoblogi';Videoblogi;
'Budjettirahoitus';Budjettirahoitus;
  'Helsingin energiaratkaisu';Helsingin energiaratkaisu;
'Tilintarkastus';Tilintarkastus;
  'Yleiset Opasnet-työt';Yleiset Opasnet-työt;
'Yleinen projektinhallinta ja neuvonta';Yleinen projektinhallinta ja neuvonta;
  'Helsingin ilmastokartta 2';Helsingin ilmastokartta 2;
'Kehittäminen';Kehittäminen;
  'Oletus';Oletus;
'Koulutus';Koulutus;
  'Ulos';Ulos;
'Sisäiset palaverit';Sisäiset palaverit;
  'Muu';Muu
'Vuosibudjetointi';Vuosibudjetointi;
|default:'Koronakide'|
'Tilinpäätös';Tilinpäätös;
category:Työjakson tiedot|
'Oletus';Oletus;
name:jaksoko|description:Mitä haluat kirjata?|type:selection|options:
'Ulos';Ulos;
FALSE;Annan nykyhetken aloitusajaksi;
'Muu';Muu
TRUE;Annan työn alku- ja loppuhetken käsin|
|default:'Helsingin ilmastokartta 2'|
default:FALSE|
category:Henkilötietoa ei tarvitse antaa, jos olet kirjautuneena Opasnettiin|
name:muutyö|description:Muu työ, mikä?|type:text|
name:jaksoko|description:Mitä haluat kirjata?|type:selection|options:
category:Listalta puuttuva työ|category_conditions:työ;'Muu'|
FALSE;Annan nykyhetken aloitusajaksi;
name:alku|description:Milloin aloitit?|type:datetime|
TRUE;Annan työn alku- ja loppuhetken käsin|
category:Jakson ajoitus|category_conditions:jaksoko;TRUE|
default:FALSE|
name:loppu|description:Mihin asti tämä työ jatkui?|type:datetime
name:muutyö|description:Muu työ, mikä?|type:text|
category:Listalta puuttuva työ|category_conditions:työ;'Muu'|
name:aika|description:Milloin aloitit?|type:datetime|
category:Jakson ajoitus|category_conditions:jaksoko;TRUE|
name:loppu|description:Mihin asti tämä työ jatkui?|type:datetime
">
">
library(OpasnetUtils)
library(OpasnetUtils)


alkutyo <- ifelse(työ == 'Muu', muutyö, työ)
if(jaksoko) {
if(jaksoko) {
alku <- as.character(aika)
  alku <- as.numeric(alku)
loppu <- as.character(loppu)
  loppu <- as.numeric(loppu)
  lopputyo <- "Ulos"
} else {
} else {
alku <- as.character(Sys.time())
  alku <- as.numeric(as.POSIXct(date(), format="%c"))
loppu <- NA
  loppu <- NULL
  lopputyo <- NULL
}
}


out <- data.frame(
out <- data.frame(
Työ = ifelse(työ == 'Muu', muutyö, työ),
  Timestamp = as.POSIXct(date(), format="%c"),
Henkilö = wiki_username,
  Work = c(alkutyo, lopputyo),
Aika = alku,
  Person = wiki_username,
Loppu = loppu,
  Result = c(alku, loppu)
Result = 0
)
)
if (jaksoko && alku > loppu){
cat("Kirjaus epäonnistui, aloitusaika on myöhäisempi kuin lopetusaika.\n")
cat("Tarkasta aika ja yritä uudelleen.")
} else{
opbase.upload(input = out, ident = "Op_fi3948", name = "Kohdistamo", subset = "Kirjaukset",
obj_type = "variable", act_type = "append", language = "fin", who = wiki_username)
cat("Kirjaus onnistui. Nämä tiedot tallennettiin.\n")
}


opbase.upload(input = out, ident = "Op_fi3948", name = "Kohdistamo", subset = "Kirjaukset2",
      obj_type = "variable", act_type = "append", language = "fin", who = wiki_username)


oprint(out[colnames(out) != "Result"])
cat("Kirjaus onnistui. Nämä tiedot tallennettiin.\n")
out$Result <- as.character(as.POSIXct(out$Result, origin="1970-01-01 00:00:00"))
oprint(out)
</rcode>
</rcode>
 
 
<rcode graphics=1 name="output" embed=1 showcode=0 label="Hae kirjauksia" variables="
category:Hae kirjauksia|
name:alku|description:Seurantajakson alku|type:date|default:2018-06-01|
name:loppu|description:Seurantajakson loppu|type:date|
name:tekija|description:Työntekijän käyttäjätunnus|type:text|default:Kaikki|
name:projekti|description:Projekti|type:selection|options:
'Kaikki';Kaikki;
'Näkemysverkko';Näkemysverkko;
'STM raportointi ja laskutus';STM raportointi ja laskutus;
'EU raportointi ja laskutus';EU raportointi ja laskutus;
'TEKES raportointi ja laskutus';TEKES raportointi ja laskutus;
'SA raportointi ja laskutus';SA raportointi ja laskutus;
'ESR/EAKR raportointi ja laskutus';ESR/EAKR raportointi ja laskutus;
'MUUT  raportointi ja laskutus';MUUT  raportointi ja laskutus;
'Budjettirahoitus';Budjettirahoitus;
'Tilintarkastus';Tilintarkastus;
'Yleinen projektinhallinta ja neuvonta';Yleinen projektinhallinta ja neuvonta;
'Kehittäminen';Kehittäminen;
'Koulutus';Koulutus;
'Sisäiset palaverit';Sisäiset palaverit;
'Vuosibudjetointi';Vuosibudjetointi;
'Tilinpäätös';Tilinpäätös;
'Pneumokokkirokote';Pneumokokkirokote;
'LVM-tulevaisuuskatsaus';LVM-tulevaisuuskatsaus;
'H2O';H2O;
'Helsingin ilmastokartta';Helsingin ilmastokartta;
'Helsingin ilmastokartta 2';Helsingin ilmastokartta 2;
'Hyvinvointi kestävän kasvun perustana';Hyvinvointi kestävä kasvun perustana;
'IEHIAS';IEHIAS;
'Avoimen tieteen tiekartta';Avoimen tieteen tiekartta;
'Helsingin energiaratkaisu';Helsingin energiaratkaisu;
'Yleiset Opasnet-työt';Yleiset Opasnet-työt;
'Yhtäköyttä';Yhtäköyttä;
'Maahanmuutto';Maahanmuutto;
'Vesiapina';Vesiapina;
'Oletus';Oletus;
'Muu';Muu
|default:'Kaikki'
">
library(OpasnetUtils)
#library(ggplot2)
objects.latest("Op_fi3948", code_name = "alusta") # kirjausajat


kirjausajat <- EvalOutput(kirjausajat)
result(kirjausajat) <- as.character(as.POSIXct(result(kirjausajat), origin="1970-01-01 00:00:00"))
oprint(kirjausajat@output)


objects.latest("Op_en6007",code_name="timelineplot")


<rcode graphics=0 name="output" embed=1 showcode=0 label="Hae kirjauksia" variables="
timelineplot(kirjausajat)+labs(title="Työtunnit aikajanalla")
category:Hae kirjauksia|
</rcode>
name:alku|description:Seurantajakson alku|type:date|default:2014-02-06|
 
name:loppu|description:Seurantajakson loppu|type:date|
<rcode name="answer" embed=1 showcode=0 label="Poista kirjaus" variables="
name:tekijä|description:Työntekijän käyttäjätunnus|type:text|default:Kaikki|
name:nro|description:Poistettavan kirjauksen rivinumero (Obs)|type:text|
name:projekti|description:Projekti|type:selection|options:
category:Kirjauksen poisto|
'Kaikki';Kaikki;
name:syy|description:Poiston syy|type:text
'STM raportointi ja laskutus';STM raportointi ja laskutus;
'EU raportointi ja laskutus';EU raportointi ja laskutus;
'TEKES raportointi ja laskutus';TEKES raportointi ja laskutus;
'SA raportointi ja laskutus';SA raportointi ja laskutus;
'ESR/EAKR raportointi ja laskutus';ESR/EAKR raportointi ja laskutus;
'MUUT  raportointi ja laskutus';MUUT  raportointi ja laskutus;
'Budjettirahoitus';Budjettirahoitus;
'Tilintarkastus';Tilintarkastus;
'Yleinen projektinhallinta ja neuvonta';Yleinen projektinhallinta ja neuvonta;
'Kehittäminen';Kehittäminen;
'Koulutus';Koulutus;
'Sisäiset palaverit';Sisäiset palaverit;
'Vuosibudjetointi';Vuosibudjetointi;
'Tilinpäätös';Tilinpäätös;
'Pneumokokkirokote';Pneumokokkirokote;
'LVM-tulevaisuuskatsaus';LVM-tulevaisuuskatsaus;
'H2O';H2O;
'Helsingin ilmastokartta';Helsingin ilmastokartta;
'Helsingin ilmastokartta 2';Helsingin ilmastokartta 2;
'Hyvinvointi kestävän kasvun perustana';Hyvinvointi kestävä kasvun perustana;
'IEHIAS';IEHIAS;
'Avoimen tieteen tiekartta';Avoimen tieteen tiekartta;
'Helsingin energiaratkaisu';Helsingin energiaratkaisu;
'Yleiset Opasnet-työt';Yleiset Opasnet-työt;
'Yhtäköyttä';Yhtäköyttä
'Oletus';Oletus;
'Muu';Muu
|default:'Kaikki'
">
">
 
library(OpasnetUtils)
library(OpasnetUtils)
library(ggplot2)
objects.latest("Op_en6007", code_name = "answer") # We need timing


kirjausajat <- function(alku, loppu, tekijä, projekti){
nro <- gsub("\\s", "", unlist(strsplit(nro, ","))) # Pilkotaan pilkusta ja poistetaan alku- ja loppuvälilyönnit
dat <- opbase.data("Op_fi3948", subset = 'Kirjaukset')
 
poistot <- opbase.data("Op_fi3948", subset = 'Kirjauspoistot')
dat <- data.frame(
  Timestamp = as.POSIXct(date(), format="%c"),
# pois <- as.numeric(as.character(poistot$Kirjausnro))  # Varoitus nousee tästä, kun yritetään muuttaa numericiksi ei-numeerinen.
  User = wiki_username,
# Varoitus tulee arvosta k1 mutta tällä ei ole käytännön merkitystä. Varoitus ei ole virhe eikä toiminta keskeydy.
  Syy = syy,
#
  Result = nro
# pois <- subset(pois, pois > 0)
)
# dat <- dat[-pois , colnames(dat) != "Result"] # Tässä kohti voisi käyttää %in%iä, mutta dat[dat %in% poistot$Kirjausnro , ]
# # ei ainakaan toiminut. En siis tiedä, miten kutsua dat:in rivinumerosaraketta.
#
# dat on data.frame ja siksi et voi käyttää sitä vertailussa vektoriin. Sen sijaan 1:nrow(dat) tuottaa juoksevan rivinumeroinnin dat:lle.
# Kirjausnro puolestaan pitää muuttaa numeroiksi, jotta sitä voi verrata rivinumeroihin. Suositeltavampi tyyli on tämä:


pois <- as.numeric(levels(poistot$Kirjausnro)[poistot$Kirjausnro])
opbase.upload(input = dat, ident = "Op_fi3948", name = "Kohdistamo", subset = "Kirjauspoistot2",
dat <- dat[!1:nrow(dat) %in% pois , colnames(dat) != "Result"]
              act_type = "append", language = "fin", who = wiki_username
)


cat("Nämä kirjaukset poistettu onnistuneesti.\n")


#tuntikirjaus <- opbase.data("Op_fi3950.tuntikirjaus")
oprint(dat)
#työtehtävät <- opbase.data("Op_fi3950.tyotehtavat")
#työsuunnitelma <- opbase.data("Op_fi3950.tyosuunnitelma")
#tuntikirjaus <- tuntikirjaus[colnames(tuntikirjaus) != "Obs"]
#työtehtävät <- työtehtävät[colnames(työtehtävät) != "Obs"]
#työsuunnitelma <- työsuunnitelma[colnames(työsuunnitelma) != "Obs"]
#colnames(työsuunnitelma)[colnames(työsuunnitelma) == "Result"] <- "Loppu"
#työsuunnitelma <- data.frame(työsuunnitelma, Henkilö = "Jouni")
dat <- dat[dat$Henkilö %in% tekijä , ]
molemmat <- dat[dat$Loppu != "NA" , ]
työ <- dat[dat$Loppu == "NA" , ]
ulos <- työ[työ$Työ == "Ulos" , ]
työ <- työ[työ$Työ != "Ulos" , ]


if (length(työ$Työ) > length(ulos$Työ)) {työ <- työ[-((nrow(ulos)+1):nrow(työ)), ]
</rcode>
työ$Loppu <- ulos$Aika
} else työ$Loppu <- ulos$Aika
työ <- rbind(työ, molemmat)


if (projekti != "Kaikki") työ <- työ[työ$Työ == projekti , ]
* Katso ohjeita sivulta [[Kohdistamo/Ohje]]
* {{tuloslinkki}}


työ$Aika <- as.POSIXct(työ$Aika, tz = 'Europe/Helsinki')
<rcode label="Saldoseuranta" graphics=1 embed=1>
työ$Loppu <- as.POSIXct(työ$Loppu, tz = 'Europe/Helsinki')
library(OpasnetUtils)
library(ggplot2)
objects.latest("Op_fi3948", code_name = "alusta") # kirjausajat


työ <- työ[
tekija <- "Varpu Vidgren"
työ$Aika >= as.POSIXct(alku, tz = 'Europe/Helsinki') &
projekti <- "Kaikki"
työ$Aika <= as.POSIXct(loppu, tz = 'Europe/Helsinki') +3600*24 ,
alku <- "2018-08-01"
]
loppu <- "2099-01-01"


työaika <- (sum(as.numeric(työ$Loppu))-sum(as.numeric(työ$Aika)))
kirjausajat <- EvalOutput(kirjausajat)
kirjausajat <- kirjausajat[kirjausajat$Work!="Ulos",]
työaika <- (round(työaika/3600, digits = 2))
cat("Valitulla välillä tehty työaika on yhteensä ", työaika, " tuntia. \n")


työ$Aika <- as.character(työ$Aika)
cat("Tarkastellaan aikaväliä", alku, " - ", loppu, "\n")
työ$Loppu <- as.character(työ$Loppu)
 
oprint(työ)
durat <- kirjausajat
#oprint(työsuunnitelma)
colnames(durat@output)[match(c("kirjausajatResult","Duration"),colnames(durat@output))] <- c("Time","kirjausajatResult")
#oprint(työtehtävät)
durat <- unkeep(durat, "Timestamp", sources=TRUE)
durat$Time <- as.Date(as.POSIXct(durat$Time,origin="1970-01-01"))
#out <- poistot
 
#oprint(out)
dat <- seq.Date(min(durat$Time),to=max(durat$Time),by=1)
dat <- dat[!weekdays(dat, abbreviate = TRUE) %in% c("la","su","Sat","Sun")]
 
#tuntikirjaus <- timing(tuntikirjaus, timecol = c("Aika", "Loppu"), weeks = 6)
odote <- EvalOutput(Ovariable(
#timeline <- makeTimeline(tuntikirjaus)
  "odote",
#timeline <- timeline[order(timeline$Time) , ]
  data=data.frame(
#timeline$Time[nrow(timeline)] <- max(timeline$Time, na.rm = TRUE)
    Work = "odote",
    Person = NA,
#for(i in 1:(nrow(timeline)-1)) {timeline$end[i] <- timeline$Time[i+1]}
    Time= dat,
#timeline[nrow(timeline), "end"] <- NA
    Result = -7.35, # This applies only if every person has equal working time
#timeline$end <- as.POSIXct(timeline$end, origin = "1970-01-01")
    stringsAsFactors = FALSE
  )
#ggplot(timeline, aes(
))
# xmin = Time, # as.Date(as.character(Start))
 
# xmax = end, # as.Date(as.character(End)) + 2
tst <- combine(durat,odote, name="tst")
# ymin = as.numeric(Henkilö),
tst@output <- fillna(tst@output, "Person")
# ymax = as.numeric(Henkilö) + 1,
# fill = Työ)) + geom_rect()
#
}


if (tekijä != "Kaikki") tekijä <- gsub("\\s", "", unlist(strsplit(tekijä, ","))) else tekijä <- c("Sharp", "Heta", "Pauli", "Jaakko", "Mori", "Julia")
tmp <- oapply(tst, cols="Work",FUN=sum)
kirjausajat(alku, loppu, tekijä, projekti)
cat("Henkilöiden työaikasaldo", as.character(max(tmp$Time)),":\n")
oprint(oapply(tmp, "Person", FUN=sum)@output)


ggplot(tmp@output, aes(x=Time, y=cumsum(tstResult),colour=Person))+geom_line()+
  theme_gray(base_size=24)+
  labs(
    title="Työajan kumulatiivinen saldo",
    y="Työtuntisaldo (h)",
    x="Kalenteriaika"
  )


#objects.store(output, kirjausajat)
result(kirjausajat) <- as.character(as.POSIXct(result(kirjausajat), origin="1970-01-01 00:00:00"))
# Periaatteena on kaksi koodia: initiate luo funktiot, ovariablet ja muut yleiskäyttöiset oliot ja tallentaa ne serverille.
oprint(kirjausajat@output)
# Käyttökoodi answer kutsuu noita olioita ja suorittaa niillä tapauskohtaisia toimenpiteitä. Koska tämä on tapauskohtainen
# koodi, ei kannata tallentaa olioita (ethän kutsu niitä missään). Kunhan koodi on vakiintunut, kannattaa se jakaa
# yleiseen ja projektikohtaiseen. Esimerkiksi tekijöiden tunnukset kannattaa ottaa funktioon parametriksi, jotta funktio
# olisi yleispätevä, ja parametrin arvo kerrotaan projektikohtaisessa koodissa.
</rcode>
</rcode>


== Perustelut ==


=== Laskenta ===


 
<rcode name="alusta" label="Alusta ovariablet kirjaukset, kirjauspoistot, kirjausajat" embed=1>
<rcode name="answer" embed=1 showcode=0 label="Poista kirjaus" variables="
# Tämä on koodi Op_fi3948/alusta sivulla [[Kohdistamo]]
name:nro|description:Poistettavan kirjauksen Obs|type:text|
category:Kirjauksen poisto|
name:syy|description:Poiston syy|type:text
">


library(OpasnetUtils)
library(OpasnetUtils)


nro <- gsub("\\s", "", unlist(strsplit(nro, ","))) # Pilkotaan pilkusta ja poistetaan alku- ja loppuvälilyönnit
kirjaukset <- Ovariable(
  "kirjaukset",
  ddata = "Op_fi3948", subset="Kirjaukset2",getddata=FALSE
)


dat <- data.frame(Kirjausnro = nro, Syy = syy, Result = 1)
kirjauspoistot <- Ovariable(
  "kirjauspoistot",
  ddata="Op_fi3948", subset="Kirjauspoistot2", getddata=FALSE
)


opbase.upload(input = dat, ident = "Op_fi3948", name = "Kohdistamo", subset = "Kirjauspoistot",  
kirjausajat <- Ovariable(
act_type = "append", language = "fin", who = wiki_username
  "kirjausajat",
  dependencies = data.frame(
    Name=c(
      "kirjaukset",
      "kirjauspoistot",
      "alku",
      "loppu",
      "tekija",
      "projekti"
    ),
    Ident=c(
      "Op_fi3948/alusta", # [[Kohdistamo]]
      "Op_fi3948/alusta", # [[Kohdistamo]]
      "Op_fi3948/oletukset", # [[Kohdistamo]]
      "Op_fi3948/oletukset", # [[Kohdistamo]]
      "Op_fi3948/oletukset", # [[Kohdistamo]]
      "Op_fi3948/oletukset" # [[Kohdistamo]]
    )
  ),
  formula = function(...) {
   
    dat <- kirjaukset[-na.omit(result(kirjauspoistot)) , ]
    alk <- as.numeric(as.POSIXct(alku))
    lop <- as.numeric(as.POSIXct(loppu))
   
    #tuntikirjaus <- opbase.data("Op_fi3950.tuntikirjaus")
    #työtehtävät <- opbase.data("Op_fi3950.tyotehtavat")
    #työsuunnitelma <- opbase.data("Op_fi3950.tyosuunnitelma")
    #tuntikirjaus <- tuntikirjaus[colnames(tuntikirjaus) != "Obs"]
    #työtehtävät <- työtehtävät[colnames(työtehtävät) != "Obs"]
    #työsuunnitelma <- työsuunnitelma[colnames(työsuunnitelma) != "Obs"]
    #colnames(työsuunnitelma)[colnames(työsuunnitelma) == "Result"] <- "Loppu"
    #työsuunnitelma <- data.frame(työsuunnitelma, Henkilö = "Jouni")
   
    if(tekija!='Kaikki') {
      tekija <- trimws(unlist(strsplit(tekija, ",")))
      dat <- dat[dat$Person %in% tekija , ]
    }
    dat <- dat[order(dat$Person, result(dat)),]
    res <- result(dat)
    dat$Duration <- c(res[2:length(res)] - res[1:(length(res)-1)], 0) / 3600
    # This removes the last entry from each person's duration because that is calculated wrongly.
    dat$Duration[c(match(unique(dat$Person),dat$Person)-1,length(dat$Person))] <- 0
   
    if(projekti!="Kaikki") dat <- dat[dat$Work == projekti , ]
    res <- result(dat)
    dat <- dat[res >= alk & res <= lop +3600*24 , ]
    if(nrow(dat@output)==0) {
      warning("No rows to display\n")
      return(dat)
    }
    tyoaika <- aggregate(dat@output["Duration"], dat@output[c("Person","Work")], sum)
    tyoaika <- tyoaika[tyoaika$Work!="Ulos",]
   
    cat("Valitulla välillä tehty työaika yhteensä ", sum(tyoaika$Duration), " tuntia.\n")
    oprint(tyoaika)
   
    return(dat)
  }
)
)


cat("Nämä kirjaukset poistettu onnistuneesti.\n")
objects.store(kirjaukset, kirjauspoistot, kirjausajat)
cat("Ovariablet kirjaukset, kirjauspoistot ja kirjausajat tallennettu.\n")
</rcode>


oprint(dat)
<rcode name="oletukset" label="Alusta oletusarvot alku, loppu, tekija, projekti" embed=1>
# Tämä on koodi Op_fi3948/oletukset sivulla [[Kohdistamo]]


</rcode>
library(OpasnetUtils)


alku <- "2018-06-01"
loppu <- "2099-01-01"
tekija <- "Kaikki"
projekti <- "Kaikki"


* Katso ohjeita sivulta [[Kohdistamo/Ohje]]
objects.store(alku, loppu, tekija, projekti)
* {{tuloslinkki}}
cat("Vektorit alku, loppu, tekija ja projekti tallennettu.\n")
</rcode>


== Aikakoneen laskenta ==
=== Aikakoneen laskenta ===


Tässä on siistitty ja dokumentoitu versio [[Aikakone]]en makeTimeline-funktiosta, joka ottaa sisäänsä työajan alku- ja loppuaikoja ja tuottaa aikajanan. Funktion olennainen lisäarvo on siinä, että sille voi antaa päällekkäisiä ajanjaksoja, ja se korvaa vanhemmat kirjaukset (eli ylempänä taulukossa olevat) uudemmilla, jos niiissä on päällekkäisyyksiä. Toinen lisäarvo on se, että se automaattisesti käsittelee jokaisen henkilön ajankäyttöä erikseen, mutta muiden indeksien suhteen se vain periyttää tiedot aikajanalle. Muita indeksejä voi siis käyttää tarpeen mukaan.
Tässä on siistitty ja dokumentoitu versio [[Aikakone]]en makeTimeline-funktiosta, joka ottaa sisäänsä työajan alku- ja loppuaikoja ja tuottaa aikajanan. Funktion olennainen lisäarvo on siinä, että sille voi antaa päällekkäisiä ajanjaksoja, ja se korvaa vanhemmat kirjaukset (eli ylempänä taulukossa olevat) uudemmilla, jos niiissä on päällekkäisyyksiä. Toinen lisäarvo on se, että se automaattisesti käsittelee jokaisen henkilön ajankäyttöä erikseen, mutta muiden indeksien suhteen se vain periyttää tiedot aikajanalle. Muita indeksejä voi siis käyttää tarpeen mukaan.
{{comment|# |Kehityskohteita: tarvitaanko koskaan tilannetta, jossa henkilösarakkeita onkin useita? Ei liene tärkeä, vaan tarvittaessa tämä toteutetaan luomalla tämmöinen sarake etukäteen.|--[[Käyttäjä:Jouni|Jouni Tuomisto]] ([[Keskustelu käyttäjästä:Jouni|keskustelu]]) 15. heinäkuuta 2014 kello 08.28 (UTC)}}


<rcode embed=1>
<rcode embed=1>

Nykyinen versio 16. maaliskuuta 2022 kello 08.28


Kysymys

Miten kirjataan työaikaa helpolla tavalla?

Vastaus

Työaikaa kirjataan alla olevalla koodilla "Tallenna kirjaus". Tällöin tallentuu käyttäjän käyttäjätunnus, valittu projekti, aloitusaika (mahdollisesti lopetusaika jos se annetaan) sekä aikaleima. Kirjauksia voi tarkastella koodilla "Hae kirjauksia". Hakua voi rajata käyttäjän, projektin ja aikakriteerin perusteella.

Kirjauksissa on kaksi mahdollista aikatulkintaa. Tällä hetkellä käytetään ensimmäistä, mutta aiemmin oli käytössä jäljempi. Esimerkkinä voidaan ajatella kirjauksia, jotka sama käyttäjä on tehnyt. Ensimmäinen kirjaus on projektia A klo 1-4, toinen on projektia B klo 2-3.

  1. Käyttäjäkohtaiset kirjaukset tulkitaan tapahtumajärjestyksessä ja loppuaika tarkoittaa kaiken työn lopettamista. Tässä tapauksessa tulkinta on, että klo 1 alkoi projekti A, klo 2 se vaihtui projektiin B, klo 3 työnteko lopetettiin ja klo 4 työnteko lopetettiin (eli kello neljän kirjaus ei vaikuta mihinkään koska tila ei muutu). Tämä tulkinta on suoraviivaisempi ja mahdollistaa työn alku- ja loppuaikojen kirjaamisen toisistaan riippumatta.
  2. Käyttäjäkohtaiset kirjaukset tulkitaan kirjausjärjestyksessä. Toinen kirjaus siis pyyhkii yli ensimmäisen kirjauksen siltä osin kuin ne ovat päällekkäisiä. Tässä tapauksessa tulkinta on, että klo 1 alkoi projekti A, klo 2 se vaihtui projektiin B, klo 3 palattiin projektiin A ja työnteko lopetettiin klo 4. Tässä tulkinnassa on aina kirjattava alku- ja loppuajat pareina, mikä voi olla hankalaa. Funktiossa makeTimeline käytetään mergeä yhdistämään oikeat aikapisteparit toisiinsa. --# Tästä voisi tehdä päivitetyn version. Alla oleva Aikakoneen makeTimeline ei liene uusin. Toinen versio löytyy sivulta op_en:OpasnetUtils/Drafts#Miscellaneous functions. --Jouni Tuomisto (keskustelu) 10. heinäkuuta 2018 kello 12.44 (UTC)

Työjakson tiedot

Minkä työn haluat kirjata?:

Mitä haluat kirjata?:

Listalta puuttuva työ

Muu työ, mikä?:

Jakson ajoitus

Milloin aloitit?:
..-::

Mihin asti tämä työ jatkui?:
..-::

+ Näytä koodi


Hae kirjauksia

Seurantajakson alku:
..

Seurantajakson loppu:
..

Työntekijän käyttäjätunnus:

Projekti:

+ Näytä koodi

Kirjauksen poisto

Poistettavan kirjauksen rivinumero (Obs):

Poiston syy:

+ Näytä koodi


+ Näytä koodi

Perustelut

Laskenta

+ Näytä koodi

+ Näytä koodi

Aikakoneen laskenta

Tässä on siistitty ja dokumentoitu versio Aikakoneen makeTimeline-funktiosta, joka ottaa sisäänsä työajan alku- ja loppuaikoja ja tuottaa aikajanan. Funktion olennainen lisäarvo on siinä, että sille voi antaa päällekkäisiä ajanjaksoja, ja se korvaa vanhemmat kirjaukset (eli ylempänä taulukossa olevat) uudemmilla, jos niiissä on päällekkäisyyksiä. Toinen lisäarvo on se, että se automaattisesti käsittelee jokaisen henkilön ajankäyttöä erikseen, mutta muiden indeksien suhteen se vain periyttää tiedot aikajanalle. Muita indeksejä voi siis käyttää tarpeen mukaan.

+ Näytä koodi